这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » STM32 » NUCLEO L053R8 边学边玩

共34条 3/4 1 2 3 4 跳转至
专家
2015-11-05 20:43:59     打赏
21楼

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


差哪里呢?

且看下文分解


专家
2015-11-05 20:50:06     打赏
22楼

EEPW的论坛编辑器插入代码部分靠色

对我这种色弱的人来讲,简直是灾难啊

所以如果插乱,别奇怪


专家
2015-11-05 20:53:26     打赏
23楼

话说,贴的Arduino部分和改的部分不一样

贴的Arduino部分是里边获取日期的部分


改写的部分是获取年月日时分秒等数据的。

仅供参考,勿怪。



专家
2015-11-05 21:04:35     打赏
24楼

nucleo的RTC续(三)


为啥例子里读那个LM75BD就会返回正确数据,而我这个就不能呢?


然后追踪了一下Arduino的代码。


在:

uint8_t twi_readFrom(uint8_t address, uint8_t* data, uint8_t length, uint8_t sendStop)中

  // build sla+w, slave device address + w bit
  twi_slarw = TW_READ;
  twi_slarw |= address << 1;

 在:

uint8_t twi_writeTo(uint8_t address, uint8_t* data, uint8_t length, uint8_t wait, uint8_t sendStop)

  // build sla+w, slave device address + w bit
  twi_slarw = TW_WRITE;
  twi_slarw |= address << 1;

 

在AVR C库手册中:

R/W bit in SLA+R/W address field.
• #define TW_READ 1
• #define TW_WRITE 0

也就是说,地址其实是加上读写位后转换而来的地址。


另外,找了一下DS3231的文档:


果然如此、



专家
2015-11-05 21:17:32     打赏
25楼

nucleo的RTC续(四)


改写后的代码如下:

#include "mbed.h"

#define DS3231_ADDR   (0x68)
#define TW_READ 1
#define TW_WRITE 0

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( (TW_WRITE | DS3231_ADDR <<1) , 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( (TW_READ | DS3231_ADDR <<1), 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:0

Return Value:0
26	7	21	4	5	11	15	
I2C Test End!


总算出数啦,累死我啦。

数据依次是:秒,分,小时,星期,日, 月,年

和当前时间完全一致啊,爽得不要不要的。

(数据是BCD编码存储的,我用16进制打印出来就是正确的,年,月和STM32L053R8的定义有些差异,需要注意)


专家
2015-11-05 21:29:28     打赏
26楼

DS3231寄存器说明 & Arduino库


DS3231_TEST.zip



高工
2015-11-05 21:29:35     打赏
27楼
大众创新就靠这个板子啦

专家
2015-11-05 21:31:05     打赏
28楼

上传附件累死个人啊。

填一大堆内容。


用户体验呢?


院士
2015-11-05 21:35:12     打赏
29楼
真棒,真棒~~

专家
2015-11-05 21:37:51     打赏
30楼

还有个问题

为何我的地址要<<来转换呢


为何那个LM75BD,就没转换呢。

找了半天资料,其实程序中的那个地址就是转换后的。(好吧,我跪了)


然后下一个问题

为何它转换后的读写地址都一样呢

按说应该一个1结尾,一个0结尾啊?


好吧,据说其实直接读就可以。

可能是我没研究透彻,不研究啦。总之我一贯的原则就是不求甚解。

有知道的兄弟回复一下。

感激不尽啊。



共34条 3/4 1 2 3 4 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]