完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
做了块板子,用ds3231sn时钟芯片,板子其它部分都做好了,昨天网上找了一个STM32驱动ds3231的程序,我用的430单片机,按照程序修改了一下,却死活读取不到正确时间。貌似通讯不对,可是时序延时是完全按照网上的程序的。为什么会这样?附原理图。
补充:在仿真时,时间读取函数里面,仿真看到年月日时分秒都是0。 编辑
|
|
相关推荐
5个回答
|
|
有人不
|
|
|
|
贴出来代码:
》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》 》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》 /////////////////////////////////////////////////////////////////////////////////// /* 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_ReadAddress 0xD1 //------------------------------------------------------------------- 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%10; 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; 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); } |
|
|
|
///////////////////////////////////////////////////////////////////////////////////
/* 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_ReadAddress 0xD1 //------------------------------------------------------------------- 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%10; 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; 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); } |
|
|
|
我也是接收到的全是0,我用的是STM8。
|
|
|
|
我读取也全是000,用89C58做的,已经几天了,还没找的问题
|
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
开启全新AI时代 智能嵌入式系统快速发展——“第六届国产嵌入式操作系统技术与产业发展论坛”圆满结束
1664 浏览 0 评论
2024 RT-Thread全球巡回线下培训火热来袭!报名提问有奖!
8011 浏览 10 评论
1849 浏览 0 评论
IaaS+on+DPU(IoD)+下一代高性能算力底座技术白皮书
3255 浏览 0 评论
飞凌嵌入式-ELFBOARD 常用的USB接口及其不同版本介绍第1期
1196 浏览 0 评论
68023 浏览 21 评论
嵌入式热门DIY项目:智能机器人开源资料合集(原理图、代码、论文)
68605 浏览 22 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-9-12 21:25 , Processed in 0.725284 second(s), Total 83, Slave 63 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191