DS1302做时钟出现的问题,很是纠结

2020-02-02 09:28发布

秒显示的规律:
00 01 02 03 04
08 09 10 11 12
10 11 12 13 14
18 19 20 21 22
20 21 22 23 24
28 29 30 31 32
然后再循环一次,刚好60次。但是感觉时间显示的是2秒才变一次,ds1302是买的时钟模块,应该没什么问题吧。我把液晶显示器更新时间设置为0.5秒,还是这样。检查了几天了,真不知道这怎么回事。。。。

友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
11条回答
sakmb
1楼-- · 2020-02-02 14:51
 精彩回答 2  元偷偷看……
paradisespace
2楼-- · 2020-02-02 16:24
程序是用模块写的
paradisespace
3楼-- · 2020-02-02 16:56
sakmb 发表于 2012-5-27 00:44
估计是程序问题,你上程序大家看看那

上传了,显示上有规律,开始以为是进制的转换问题 但是检查又看不出问题来,头都看懵了。
jxcylxh
4楼-- · 2020-02-02 19:59
呵呵,这个我刚遇到过,你的程序的读部分有问题,你把读回来的数据分析一下,你肯定多移了一位。还有就是在用的时候加上上拉电阻。
paradisespace
5楼-- · 2020-02-02 22:14
  1. #include <intrins.h>
  2. #include "DS1302.h"

  3. /*************************通用宏定义*******************************/
  4. #define DEC2BCD(X)        ((X/10)<<4 | (X%10))                  //用于将十进制转成BCD码的宏
  5. #define BCD2DEC(X)        (((X&0x70)>>4)*10 + (X&0x0F))        //用于将BCD码转成十进制的宏
  6. /***********************变量定义******************************/
  7. unsigned char year,month,day,week,hour,minute,second;                        //年月日周时分秒变量

  8. /***********************函数定义******************************/
  9. void DS1302_Write_Byte(unsigned  char Wdata_temp);                                //写字节函数
  10. unsigned char DS1302_Read_Byte(void);                                                        //读字节函数
  11. void DS1302_Write(unsigned char address,unsigned char dat);                //向指定地址写一字节数据函数
  12. unsigned char DS1302_Read ( unsigned char address );                                //从指定地址读一字节数据函数
  13. void DS1302_Read_RTC(void);                                                                                //读取DS1302的时间函数
  14. void DS1302_Set_RTC(void);                                                                                //设定DS1302的时间函数
  15. void DS1302_Init();

  16. //SCL的上升沿写入数据,下降沿读取数据,数据均是先低位,后高位
  17. /************************************************************
  18. *名称:DS1302_Write_Byte()
  19. *说明:
  20. *功能:向DS1302写一个字节数据
  21. *调用:无
  22. *输入:Wdata_temp
  23. *输出:无
  24. ***********************************************************/
  25. void DS1302_Init()
  26. {
  27.         DS1302_Write(W_CONTROL,0x00);
  28.         year=0x00;
  29.         month=0x00;
  30.         day=0x00;
  31.         hour=0x00;
  32.         minute=0x00;
  33.         second=0x00;
  34.                
  35. }


  36. /************************************************************
  37. *名称:DS1302_Write_Byte()
  38. *说明:
  39. *功能:向DS1302写一个字节数据
  40. *调用:无
  41. *输入:Wdata_temp
  42. *输出:无
  43. ***********************************************************/
  44. void DS1302_Write_Byte(unsigned  char Wdata_temp)
  45. {
  46.         unsigned char i;
  47.         SCLK=0;                         //初始时钟线置0
  48.         _nop_();_nop_();
  49.         for (i=0;i<8;i++)                        //开始传输8bit数据,循环8次 写入数据
  50.         {
  51.                 SDA=Wdata_temp&0x01;   //取出数据的最低位,写入数据线
  52.                 _nop_();_nop_();
  53.                
  54.                 SCLK=1;                                        //时钟线拉高,构成时钟的上升沿
  55.                 _nop_();_nop_();
  56.                
  57.                 SCLK=0;                                 //时钟线拉低,为下一个上升沿做准备
  58.                 Wdata_temp>>=1;                //数据右移一位,准备传输下一位数据       
  59.         }
  60. }   

  61. /************************************************************
  62. *名称: DS1302_Read_Byte()
  63. *说明:
  64. *功能:向DS1302读一个字节数据
  65. *调用:无
  66. *输入:无
  67. *输出: Rdata_temp
  68. ***********************************************************/
  69. unsigned  char DS1302_Read_Byte(void)
  70. {
  71.         unsigned  char i;
  72.         unsigned  char Rdata_temp=0;
  73.         for (i=0;i<8;i++)          //循环8次 读取数据
  74.         {            
  75.                 if(SDA)
  76.                 Rdata_temp|=0x80;               //每次传输低字节
  77.                 SCLK=1;
  78.                 _nop_();
  79.                 SCLK=0;
  80.                 _nop_();
  81.                 Rdata_temp>>=1;                 //右移一位
  82.         }
  83.         return (Rdata_temp);
  84. }
  85. /************************************************************
  86. *名称:DS1302_Write()
  87. *说明:先写地址,后写数据
  88. *功能:向address相应的地址中写一个字节的数据
  89. *调用:DS1302_Write_Byte()
  90. *输入:address:要写入的地址。dat:要写入的控制字
  91. *输出:无
  92. ***********************************************************/
  93. void DS1302_Write(unsigned char address,unsigned char dat)
  94. {
  95.         DS1302_RST=0;               
  96.         _nop_();
  97.         SCLK=0;
  98.         _nop_();
  99.         DS1302_RST=1;       
  100.            _nop_();   //启动
  101.         DS1302_Write_Byte(address);        //发送地址
  102.         DS1302_Write_Byte(dat);                //发送数据
  103.         DS1302_RST=0;                  //恢复
  104. }
  105. /************************************************************
  106. *名称:DS1302_Read()
  107. *说明:先写地址,后读数据
  108. *功能:向address相应的地址中读一个字节的数据
  109. *调用:DS1302_Write_Byte();DS1302_Read_Byte()
  110. *输入:address:要写入的地址。
  111. *输出:dat:读取的数据
  112. ***********************************************************/
  113. unsigned char DS1302_Read ( unsigned char address )
  114. {
  115.         unsigned char dat=0x00;
  116.         DS1302_RST=0;
  117.         SCLK=0;
  118.         DS1302_RST=1;
  119.         _nop_();
  120.         DS1302_Write_Byte(address);
  121.         dat=DS1302_Read_Byte();
  122.         DS1302_RST=0;
  123.         _nop_();                //以下为DS1302复位的稳定时间
  124.         DS1302_RST=0;
  125.         SCLK=0;
  126.         _nop_();
  127.         SCLK=1;
  128.         _nop_();
  129.         SDA=0;
  130.         _nop_();
  131.         SDA=1;
  132.         _nop_();
  133.         return (dat);                        //返回
  134. }
  135. /************************************************************
  136. *名称:DS1302_Read_RTC()
  137. *说明:
  138. *功能:读取当前时间        ,同时将读到的BCD码数据转换为十进制
  139. *调用:DS1302_Read();
  140. *输入:
  141. *输出:
  142. ***********************************************************/
  143. void DS1302_Read_RTC(void)
  144. {
  145.         unsigned char shi,ge;
  146.         //读取当前时间值,并将BCD码转换为十进制
  147.         //读取秒值
  148.         second=DS1302_Read(R_SECOND) & 0x7f;   //并将秒的BCD码值转换为十进制值
  149. //        second=BCD2DEC(second);
  150.         shi=(second>>4);
  151.         ge=(second & 0x0f);
  152.         second=shi*10+ge;
  153.        
  154.         //相同的操作一次读取分时日月星期年,并将读出的值进行转换
  155.         minute=DS1302_Read(R_MINUTE);
  156.         minute=BCD2DEC(minute);
  157.                
  158.         hour=DS1302_Read(R_HOUR) & 0x1f;
  159.         hour=BCD2DEC(hour);
  160.                
  161.         day=DS1302_Read(R_DAY);
  162.         day=BCD2DEC(day);
  163.                
  164.         month=DS1302_Read(R_MONTH);
  165.         month=BCD2DEC(month);
  166.                
  167.         week=DS1302_Read(R_WEEK);
  168.                
  169.         year=DS1302_Read(R_YEAR);
  170.         year=BCD2DEC(year);
  171. }

  172. //设定DS1302的时间函数
  173. void DS1302_Set_RTC(void)
  174. {
  175.          unsigned char ge,shi;
  176.         //转换时间设定值为DS1602要求的BCD码值
  177.         //调整秒
  178. //        second=    DEC2BCD(second);
  179.         ge=second%10;
  180.         shi=second/10;
  181.         second=ge+shi*16;

  182.         //调整分
  183.         minute=    DEC2BCD(minute);
  184.         //调整时
  185.         hour=      DEC2BCD(hour);
  186.         //调整日
  187.         day=       DEC2BCD(day);       
  188.         //调整月
  189.         month=     DEC2BCD(month);
  190.         //调整年
  191.         year=      DEC2BCD(year);
  192.        
  193.         //设置时间
  194.         DS1302_Write(W_CONTROL,0x00);                        //设置DS1302寄存器允许写入数据
  195.         DS1302_Write(W_SECOND,second);                        //写秒
  196.         DS1302_Write(W_MINUTE,minute);                        //写分
  197.         DS1302_Write(W_HOUR,hour);                                //写小时
  198.         DS1302_Write(W_DAY,day);                                //写日
  199.         DS1302_Write(W_MONTH,month);                        //写月
  200.         DS1302_Write(W_WEEK,week);                                //写星期
  201.         DS1302_Write(W_YEAR,year);                                //写年
  202.         DS1302_Write(W_CONTROL,0x80);                        //设置DS1302寄存器禁止写入数据
  203. }
复制代码
millwood0
6楼-- · 2020-02-03 04:08
 精彩回答 2  元偷偷看……

一周热门 更多>