历史上的今天
今天是:2025年01月19日(星期日)
2020年01月19日 | DS3231温度读取实验 附单片机源程序
2020-01-19 来源:51hei
DS3231作为一个走时精准的RTC芯片,内部带有温度补偿电路,此例将读取其中11H和12H寄存器,提取测得的温度值并传送到串口输出。
类似程序网上非常之多,不再赘述,在此重新提说几处需要注意的地方。
1.根据DS3231的芯片手册,其温度传感器的精度为±3℃,毕竟不是专用的温度传感器,在使用中可以作为一个参考,且仅此而已。
2.根据DS3231的芯片手册,其温度分辨率为±0.25℃,所以其小数部分读出的值只能是.00、.25、.50、.75这四种,如果读出的值不是这四种,则数据处理有误。
3.本实验使用一个float型数据直接接收了转换的温度值,没有对补码的符号位进行判断等。
注明:本程序没有使用CONV位进行强制转换,但是实际上温度值的刷新速度还是很令人满意(用手按住芯片,温度值更改速度很快,下面的测试图片是恒温下检测的,故无变化)。
测试程序:
#include #include"stdio.h" #include //位定义 sbit DS3231_SDA=P3^3; sbit DS3231_SCL=P3^2; //运行数组 unsigned char DS3231_Time_Buffer[7]={0x00,0x48,0x11,0x02,0x12,0x02,0x19}; unsigned char temp[2]={0,0}; char buf[20]={0}; //运行标志位 bit busy=0; //运行变量 float v; /*############################################################################## 编写/测试:凌净清河 日期:2019年2月12日 测试平台:IAP15W4K58S4 鸣谢:DS3231部分驱动函数借用了51黑论坛上某位的程序,但是时间太久忘记是谁的了。 并未修改原作者的写法,如果原作者认出,鄙人在此表示感谢,或可联系我提名。 ##############################################################################*/ /*###################以下为给DS3231定义的IIC通信函数################*/ void DS3231_Delay()//使用空操作进行短暂的延时 { _nop_(); _nop_(); _nop_(); _nop_(); } void DS3231_IIC_Start()//IIC总线的开始信号 { DS3231_SCL=1; DS3231_SDA=1; DS3231_Delay(); DS3231_SDA=0; DS3231_Delay(); DS3231_SCL=0; } void DS3231_IIC_Stop()//IIC总线的停止信号 { DS3231_SCL=0; DS3231_SDA=0; DS3231_Delay(); DS3231_SCL=1; DS3231_Delay(); DS3231_SDA=1; DS3231_Delay(); } bit DS3231_IIC_Send_Byte(unsigned char dat)//写操作 { unsigned char mask;//定义一个掩码用于进行按位发送数据的操作 bit ack; for(mask=0x80;mask!=0;mask>>=1) { if((mask&dat)==0) DS3231_SDA=0; else DS3231_SDA=1; DS3231_Delay(); DS3231_SCL=1; DS3231_Delay(); DS3231_SCL=0; } DS3231_SDA=1; DS3231_Delay(); DS3231_SCL=1; ack=DS3231_SDA; DS3231_Delay(); DS3231_SCL=0; return (~ack); } unsigned char DS3231_IIC_Read_Byte_NAK()//读操作+非应答 { unsigned char mask;//定义一个用于累加的位存储临时变量 unsigned char dat; DS3231_SDA=1; for(mask=0x80;mask!=0;mask>>=1) { DS3231_Delay(); DS3231_SCL=1; if(DS3231_SDA==0) dat&=~mask; else dat|=mask; DS3231_Delay(); DS3231_SCL=0; } DS3231_SDA=1; DS3231_Delay(); DS3231_SCL=1; DS3231_Delay(); DS3231_SCL=0; return dat; } unsigned char DS3231_IIC_Read_Byte_ACK()//读操作+应答 { unsigned char mask;//定义一个用于累加的位存储临时变量 unsigned char dat; DS3231_SDA=1; for(mask=0x80;mask!=0;mask>>=1) { DS3231_Delay(); DS3231_SCL=1; if(DS3231_SDA==0) dat&=~mask; else dat|=mask; DS3231_Delay(); DS3231_SCL=0; } DS3231_SDA=0; DS3231_Delay(); DS3231_SCL=1; DS3231_Delay(); DS3231_SCL=0; return dat; } /*#################以下为给DS3231封装的寄存器通信函数###############*/ void DS3231_Read_Registers(unsigned char *buf,unsigned char addr,unsigned char len)//读EEPROM中多个字节 { do{ DS3231_IIC_Start(); if(DS3231_IIC_Send_Byte(0xD0)) { break; } DS3231_IIC_Stop(); }while(1); DS3231_IIC_Send_Byte(addr); DS3231_IIC_Start(); DS3231_IIC_Send_Byte((0xD0)|0x01);//寻址,读操作 while(len>1) { *buf++=DS3231_IIC_Read_Byte_ACK(); len--; } *buf=DS3231_IIC_Read_Byte_NAK();//读一个字节 DS3231_IIC_Stop(); } void DS3231_Write_Registers(unsigned char *buf,unsigned char addr,unsigned char len)//写寄存器,传入待写入数组 { while(len>0) { do{ DS3231_IIC_Start(); if(DS3231_IIC_Send_Byte(0xD0)) { break; } DS3231_IIC_Stop(); }while(1); DS3231_IIC_Send_Byte(addr); while(len>0) { DS3231_IIC_Send_Byte(*buf++); len--; addr++; if((addr&0x07)==0) { break; } } DS3231_IIC_Stop(); } } void SendData(unsigned char dat)//串口1发送一个字节数据 { while(busy); busy=1; SBUF=dat; } void SendString(char *p)//串口发送一个字符串 { while(*p!='




