nucleo的RTC续(二)
如前所述,对于我等菜鸟,STM32L053R8的RTC想用起来是有极大的障碍啦。除非不断电也不重启。
还好,我手头有一个用于Arduino的ds3231模块,在Arduino上用着挺好的,就想想能不能用于这个上呢。
说做就做,先连上再说
5V, GND, SDA, SCL貌似这几根线需要连
按Arduino的连法(A4 SDA, A5 SCL)
I2C i2c(A4, A5);
然后上电RESET后给出提示:
(pinmap not found for peripheral)
研究半天,大概就是A4, A5没I2C功能 ,说好的兼容Arduino UNO R3呢, 做人咋不信守承诺呢?
好吧,找一下针脚图
SDA, SCL对应的是D14, D15, 可以在程序中直接用:I2C_SDA, I2C_SCL代替
I2C i2c(I2C_SDA, I2C_SCL);
貌似不出错了
然后呢,试验一下能不能用吧
合计按Arduino的库改写一下,应该没啥难度吧
比如这个:
byte DS3231::getDate() { Wire.beginTransmission(CLOCK_ADDRESS); Wire.write(uint8_t(0x04)); Wire.endTransmission(); Wire.requestFrom(CLOCK_ADDRESS, 1); return bcdToDec(Wire.read()); }
看起来So Easy嘛
然后,仿照mbed I2C的例子改造一下
#include "mbed.h" // Read temperature from LM75BD I2C i2c(p28, p27); const int addr = 0x90; int main() { char cmd[2]; while (1) { cmd[0] = 0x01; cmd[1] = 0x00; i2c.write(addr, cmd, 2); wait(0.5); cmd[0] = 0x00; i2c.write(addr, cmd, 1); i2c.read(addr, cmd, 2); float tmp = (float((cmd[0]<<8)|cmd[1]) / 256.0); printf("Temp = %.2f\n", tmp); } }
#include "mbed.h" #define DS3231_ADDR (0x68) Serial pc(USBTX,USBRX); I2C i2c(I2C_SDA, I2C_SCL); DigitalOut myled(LED1); int main() { char data_write[10]; char data_read[10]; data_write[0] = 0x00; //data_write[1] = 0x02; int status ; status = i2c.write(DS3231_ADDR, data_write, 1, 0); pc.printf("Return Value:%d\r\n", status); if (status != 0) { //NO ACK pc.printf("I2C Write status Error\r\n"); } status = i2c.read(DS3231_ADDR, data_read, 7); pc.printf("\r\nReturn Value:%d\r\n", status); if (status != 0) { //NO ACK pc.printf("I2C Read status Error\r\n"); } for(int i=0; i<7; i++) pc.printf("%x\t", data_read[i]); pc.printf("\r\nI2C Test End!\r\n"); }
然后呢,貌似根本不工作
Return Value:1 I2C Read status Error ff ff ff ff ff ff ff I2C Test End! Return Value:1 I2C Write status Error
差哪里呢?
且看下文分解