Maxim Integrated新型实时钟(RTC)DS3231,内部集成TCXO、RTC和32.768kHz晶体采用低成本、标准型和16引脚SOIC封装DS3231成本低,精度高I2C实时时钟(RTC),具有集成的温补晶振(TCXO)和晶体。该装置包含电池输入端,断开主电源时仍能保持精确的计时。集成晶体振动提高了设备的长期精度,减少了生产线上的部件数量。DS3231提供商用和工业温度范围,16引脚300mil的SO封装。
RTC保存秒、分、时、周、日、月、年的信息。月末日期将自动调整,包括闰年的修正。时钟的工作格式可以是24小时或/AM/PM指示12小时格式。提供两个可设置的日历闹钟和一个可设置的方波输出。地址和数据通过I2C串行传输双向总线。
用于监测温度补偿的精确电压基准和比较器电路VCC状态,检测电源故障,提供复位输出,必要时自动切换到备份电源。此外,/RST监控引脚可作为产生μP手动输入复位。
关键特性
0°C至 40°C精度在范围内±2ppm -40°C至 85°C精度在范围内±3.5ppm 连续计时提供电池备份输入 工作温度范围 商用级:0°C至 70°C 工业级:-40°C至 85°C 低功耗 实时时钟产生秒、分、时、周、日、月、年计时,并提供有效期至2100年的闰年补偿 两个日历闹钟 可编程方波输出 高速(400kHz) I2C接口 工作在3.3V 数字温度传感器输出:精度为±3°C 老化修正寄存器 /RST输出/按钮复位 做块板,用ds3231sn时钟芯片,板的其他部分都做好了,昨天在网上找到了一个stm32驱动ds3231程序,我用的430单片机按程序修改,但是没有正确的时间读。通信似乎不对,但时间延迟完全按照在线程序进行。为什么?附原理图。 补充:模拟时,时间读取函数,模拟看到年月日时分秒为0。****************************************************/ 贴出代码:
/// /* DS3231.C文件 */ #include"ds3231sn.h" #define SETIIC_SCL P1OUT |= BIT7 #define CLRIIC_SCL P1OUT &=~BIT7
#define SETIIC_SDA P1OUT |= BIT6 #define CLRIIC_SDA P1OUT &=~BIT6
#define IIC_SDA (P1IN&BIT6) _calendar_obj calendar; #define DS3231_WriteAddress 0xD0 #define DS3231_ReadAddress0xD1 //------------------------------------------------------------------- unsigned char BCD2HEX(unsigned char val) { unsigned char i; i= val&0x0f; val >>= 4; val &= 0x0f; val *= 10; i = val; return i; }
unsigned short B_BCD(unsigned char val) { unsigned char i,j,k; i=val/10; j=val; k=j (i<<4); return k; } //------------------------------------------------------------------- void IIC_Init(void) {//IIC总线初始化函数 P1DIR |= BIT7;P1DIR |= BIT6; SETIIC_SDA;//释放IIC总线数据线。 SETIIC_SCL;//释放IIC总线时钟线。 } //------------------------------------------------------------------- void IIC_start(void) {//IIC总线产生起始信号函数 P1DIR |= BIT6; SETIIC_SDA;///提高数据线 delay_us(1); SETIIC_SCL;//提高时钟线 delay_us(5); CLRIIC_SDA;//当时钟线为高电时,拉低数据线,产生起始信号。 delay_us(5); CLRIIC_SCL;//拉低时钟线 delay_us(2); } //------------------------------------------------------------------- void IIC_stop(void) {//IIC总线产生停止信号函数 P1DIR |= BIT6; CLRIIC_SCL;//拉低时钟线 CLRIIC_SDA;///拉低数据线 delay_us(4); SETIIC_SCL;//提高时钟线。 delay_us(5); SETIIC_SDA;//时钟时线为高电平时,拉高数据线,产生停止信号。 delay_us(4); } //------------------------------------------------------------------- unsigned char IIC_Tack(void) {//接收应答信号函数 unsigned char timnu=0;//定义一个位变量,以暂存响应状态。 P1DIR &=~ BIT6; SETIIC_SDA;//释放数据总线,准备接收应答信号。 delay_us(1); SETIIC_SCL;//提高时钟线。 delay_us(1); while(IIC_SDA==1)///读取响应信号状态。 { timnu ; if(timnu>250) { IIC_stop(); return 1;//返回响应信号状态,0表示响应,1表示非响应。 } } CLRIIC_SCL;//拉低时钟线。 return 0;//返回响应信号状态,0表示响应,1表示非响应。 } //产生ACK应答 void IIC_Ack(void) { P1DIR |= BIT6; CLRIIC_SCL; CLRIIC_SDA; delay_us(2); SETIIC_SCL; &nbs; delay_us(2); CLRIIC_SCL; } //不产生ACK应答 void IIC_NAck(void) { P1DIR |= BIT6; CLRIIC_SCL; SETIIC_SDA; delay_us(2); SETIIC_SCL; delay_us(2); CLRIIC_SCL; } //------------------------------------------------------------------- void IIC_write_byte(unsigned char Data) {//向IIC总线写入一个字节的数据函数 unsigned char i; P1DIR |= BIT6; CLRIIC_SCL;//拉低时钟线,允许改变数据线的状态 for(i=0;i<8;i++) { if((Data&0x80)>>7) SETIIC_SDA; else CLRIIC_SDA; Data<<=1; delay_us(2); //对TEA5767这三个延时都是必须的 SETIIC_SCL;//拉高时钟线。 delay_us(2); CLRIIC_SCL;//拉低时钟线,允许改变数据线的状态 delay_us(2); } } //------------------------------------------------------------------- unsigned char IIC_read_byte(unsigned char ack) {//从IIC总线读取一个字节的数据函数 unsigned char i; unsigned char Data=0; //定义一个缓冲寄存器。 P1DIR &=~ BIT6; for(i=0;i<8;i++)//有8位数据 { CLRIIC_SCL;//拉低时钟线,为读取下一位数据做准备。 delay_us(2); SETIIC_SCL;//拉高时钟线,为读取下一位数据做准备。 Data=Data<<1;//将缓冲字节的数据左移一位,准备读取数据。
if(IIC_SDA==1)//如果数据线为高平电平。 Data++;delay_us(1); } if (!ack) IIC_NAck();//发送nACK else IIC_Ack(); //发送ACK return Data;//返回读取的一个字节数据。 } //------------------------------------------------------------------- void IIC_single_byte_write(unsigned char Waddr,unsigned char Data) {//向任意地址写入一个字节数据函数 IIC_start();//产生起始信号 delay_us(5); IIC_write_byte(DS3231_WriteAddress);//写入设备地址(写) IIC_Tack();//等待设备的应答. delay_us(5); IIC_write_byte(Waddr);//写入要操作的单元地址。 IIC_Tack();//等待设备的应答。 delay_us(5); IIC_write_byte(Data);//写入数据。 IIC_Tack();//等待设备的应答。 delay_us(5); IIC_stop();//产生停止符号。 } //------------------------------------------------------------------- unsigned char IIC_single_byte_read(unsigned char Waddr) {//从任意地址读取一个字节数据函数 unsigned char Data;//定义一个缓冲寄存器。 IIC_start();//产生起始信号 IIC_write_byte(DS3231_WriteAddress);//写入设备地址(写) IIC_Tack();//等待设备的应答 delay_us(5); IIC_write_byte(Waddr);//写入要操作的单元地址。 IIC_Tack();//等待设备的应答。 delay_us(5); IIC_start();//产生起始信号 IIC_write_byte(DS3231_ReadAddress);//写入设备地址(写) IIC_Tack();//等待设备的应答 delay_us(5); Data=IIC_read_byte(1);//写入数据。 IIC_stop();//产生停止符号。 //-------------------返回读取的数据-------------------- return Data;//返回读取的一个字节数据。 } void Read_RTC(void) { calendar.w_year=IIC_single_byte_read(0x06); calendar.w_month=IIC_single_byte_read(0x05); calendar.w_date=IIC_single_byte_read(0x04); calendar.hour=IIC_single_byte_read(0x02); calendar.min=IIC_single_byte_read(0x01); calendar.sec=IIC_single_byte_read(0x00); } void Set_RTC(unsigned char yea,unsigned char mon,unsigned char da,unsigned char hou,unsigned char min,unsigned char sec) { unsigned char temp=0;
temp=B_BCD(yea); IIC_single_byte_write(0x06,temp);
temp=B_BCD(mon); IIC_single_byte_write(0x05,temp);
temp=B_BCD(da); IIC_single_byte_write(0x04,temp);
temp=B_BCD(hou); IIC_single_byte_write(0x02,temp);
temp=B_BCD(min); IIC_single_byte_write(0x01,temp);
temp=B_BCD(sec); IIC_single_byte_write(0x00,temp); } void get_show_time(void) { calendar.w_year=IIC_single_byte_read(0x06); calendar.w_year=BCD2HEX(calendar.w_year);
calendar.w_month=IIC_single_byte_read(0x05); calendar.w_month=BCD2HEX(calendar.w_month);
calendar.w_date=IIC_single_byte_read(0x04); calendar.w_date=BCD2HEX(calendar.w_date);
calendar.hour=IIC_single_byte_read(0x02); calendar.hour&=0x3f; calendar.hour=BCD2HEX(calendar.hour);
calendar.min=IIC_single_byte_read(0x01); calendar.min=BCD2HEX(calendar.min);
calendar.sec=IIC_single_byte_read(0x00); calendar.sec=BCD2HEX(calendar.sec); } void DS3231_Initial() { IIC_Init(); IIC_single_byte_write(0x0e,0); delay_ms(2); IIC_single_byte_write(0x0f,0); delay_ms(2); } ———————————————— 版权声明:本文为CSDN博主「m0_37895072」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/m0_37895072/article/details/102979136