找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2451|回复: 8
打印 上一主题 下一主题
收起左侧

单片机+DS1302时钟芯片程序读数据一直是29

[复制链接]
跳转到指定楼层
楼主
    DS1302时钟芯片,按照手册写的呀!为什么在单片机开发板上一直2081-29-29  29:29:29 ,我是用的LCD1602作为显示器,程序烧写进去以后一直是这样。其中的LCD1602显示程序没有问题,可以不用看,应该是DS1302的程序哪里出了问题,附件里我加了keil5的工程文件,大佬们有空帮我看一下,不胜感激。我网上查过资料,也有很多人遇到DS1302的这种问题,但没有合适的解决我的问题。extern unsigned char Real_Time[]; 已经设置为全局变量。

单片机源程序如下:
  1. #include <REGX51.H>
  2. #include "LCD1602.H"
  3. #include "DS1302.H"

  4. unsigned int Second,Minutes,Hour,Day,Month,Year,Week;
  5. unsigned char Weeks[7][3]={"Mon","Tue","Thu","Wed","Fri","Sat","Sun"};


  6. void main()
  7. {
  8.         LCD_Init();
  9.         LCD_ShowNum(1,1,20,2);//LCD1602显示数字,分别是,第一行,第一列,数字位数。
  10.         LCD_ShowString(1,5,"-  -");//显示字符串
  11.         LCD_ShowString(2,3,":  :");
  12.         DS1302_Init();//初始化1302
  13.   Set_Time();//设置给定的时间
  14.         
  15.         while(1)
  16.         {
  17.                 Read_Time();//读取时间
  18. LCD_ShowNum(1,3,Real_Time[0],2);
  19.                 LCD_ShowNum(1,6,Real_Time[1],2);
  20.                 LCD_ShowNum(1,9,Real_Time[2],2);
  21.                 LCD_ShowNum(2,1,Real_Time[3],2);
  22.                 LCD_ShowNum(2,4,Real_Time[4],2);
  23.                 LCD_ShowNum(2,7,Real_Time[5],2);        
  24.                 LCD_ShowString(1,13,"Sat");               
  25.         }
  26. }

  27. //一-------------------
  28. #include <REGX51.H>

  29. //写指令
  30. #define DS1302_Second 0x80
  31. #define DS1302_Minute 0x82
  32. #define DS1302_Hour   0x84
  33. #define DS1302_Day    0x86
  34. #define DS1302_Month  0x88
  35. #define DS1302_Year   0x8A
  36. #define DS1302_Week   0x8C
  37. #define DS1302_WP                        0x8E
  38. //读指令
  39. #define DS1302R_Second 0x81
  40. #define DS1302R_Minute 0x83
  41. #define DS1302R_Hour   0x85
  42. #define DS1302R_Day    0x87
  43. #define DS1302R_Month  0x89
  44. #define DS1302R_Year   0x8B
  45. #define DS1302R_Week   0x8D

  46. sbit DS1302_SCLK=P3^6;
  47. sbit DS1302_CE=P3^5;
  48. sbit DS1302_IO=P3^4;

  49. unsigned char Time[7]={21,11,28,20,50,30,7};//设定的时间,依次为 年/月/日/时/分/秒/周
  50. unsigned char Real_Time[7];


  51. void DS1302_Init()  //初始化
  52.         {
  53.                 DS1302_CE=0;
  54.                 DS1302_SCLK=0;
  55.         }

  56. DS1302_WriteByte(unsigned char cmd,datax)//DS1302写命令
  57. {
  58.         unsigned int i;
  59.         DS1302_CE=1;
  60.         for(i=0;i<8;i++)
  61.         {
  62.                 DS1302_IO=cmd&(0x01<<i);
  63.                 DS1302_SCLK=1;
  64.                 DS1302_SCLK=0;
  65.         }
  66.                 for(i=0;i<8;i++)
  67.         {
  68.                 DS1302_IO=datax & (0x01<<i);
  69.                 DS1302_SCLK=1;
  70.                 DS1302_SCLK=0;
  71.         }
  72.         DS1302_CE=0;
  73. }

  74. unsigned char DS1302_ReadByte(unsigned char cmd)//DS1302读命令
  75. {
  76.         unsigned char data1=0x00;
  77.         unsigned int i;
  78.         DS1302_CE=1;
  79.         for(i=0;i<8;i++)
  80.         {
  81.                 DS1302_IO=cmd&(0x01<<i);
  82.                 DS1302_SCLK=0;
  83.                 DS1302_SCLK=1;
  84.         }
  85.                 for(i=0;i<8;i++)
  86.         {
  87.                 if(DS1302_IO==1){data1=DS1302_IO|(0x01<<i);}
  88.                 DS1302_SCLK=1;
  89.                 DS1302_SCLK=0;
  90.         }
  91.                 DS1302_CE=0;
  92.                 DS1302_IO=0;
  93.                 return data1;
  94. }


  95. void Set_Time()
  96. {
  97.         DS1302_WriteByte(DS1302_WP,0x00);//关闭写保护
  98.         DS1302_WriteByte(DS1302_Year,21);//设置年
  99.         DS1302_WriteByte(DS1302_Month,Time[1]);//设置年
  100.         DS1302_WriteByte(DS1302_Day,Time[2]);//设置年
  101.         DS1302_WriteByte(DS1302_Hour,Time[3]);//设置年
  102.         DS1302_WriteByte(DS1302_Minute,Time[4]);//设置年
  103.         DS1302_WriteByte(DS1302_Second,Time[5]);//设置年
  104.         DS1302_WriteByte(DS1302_Week,Time[6]);//设置年
  105. }

  106. void Read_Time()
  107. {
  108.         unsigned int i;
  109.   Real_Time[0]=DS1302_ReadByte(DS1302R_Year);
  110.         Real_Time[1]=DS1302_ReadByte(DS1302R_Month);
  111.         Real_Time[2]=DS1302_ReadByte(DS1302R_Day);
  112.         Real_Time[3]=DS1302_ReadByte(DS1302R_Hour);
  113.         Real_Time[4]=DS1302_ReadByte(DS1302R_Minute);
  114.         Real_Time[5]=DS1302_ReadByte(DS1302R_Second);
  115.         Real_Time[6]=DS1302_ReadByte(DS1302R_Week);
  116.         for(i=0;i<7;i++)
  117.         {
  118.                 Time[i]=Time[i]/16*10+Time[i]%16;
  119.         }
  120. }
复制代码

51hei图片_20211205210428.jpg (424.15 KB, 下载次数: 179)

51hei图片_20211205210428.jpg

06DS1302时钟芯片.zip

42.37 KB, 下载次数: 8

keil5工程文件

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:624769 发表于 2021-12-5 22:04 | 只看该作者
你太依赖显示屏了,

你先用串口,把从DS1302中读取出来的值原封不动的发出来, 串口助手 直接原封不动的 HEX接收, HEX显示,看看到底是什么值,然后分析是什么问题, 你这29都是转码以后的值了,要从源头分析。
几个参考值,秒为默认上电后是 0x80, 写保护位默认上电后是 0x00, 充电设置位,默认上电后是 0x5C, 别急着写数据,先读数据,看看对不对了,再验证其他的。
回复

使用道具 举报

板凳
ID:988270 发表于 2021-12-5 22:31 | 只看该作者
188610329 发表于 2021-12-5 22:04
你太依赖显示屏了,

你先用串口,把从DS1302中读取出来的值原封不动的发出来, 串口助手 直接原封不动的 ...

刚用串口测试了一下,读出来数据是81,在秒的位置读出来的一直是81,因为DS1302输出的是BCD码,所以转换一下,其实是129,刚好对应上LCD显示的29
回复

使用道具 举报

地板
ID:624769 发表于 2021-12-5 22:58 | 只看该作者
天赋异禀 发表于 2021-12-5 22:31
刚用串口测试了一下,读出来数据是81,在秒的位置读出来的一直是81,因为DS1302输出的是BCD码,所以转换 ...

你读秒的时候, 往 DS1302 发出去的就是 0x81 吧? 所以你最后读出来 0x81, 说明,你压根没完成读取,读的,就是你发的,
回复

使用道具 举报

5#
ID:988270 发表于 2021-12-5 23:02 | 只看该作者
天赋异禀 发表于 2021-12-5 22:31
刚用串口测试了一下,读出来数据是81,在秒的位置读出来的一直是81,因为DS1302输出的是BCD码,所以转换 ...

我刚又用串口工具测试了一下,下面的程序当我给出P3_5=1,串口接收到的数据是01 01 01 00 00 00这样一直循环,但如果是P3_0接口就没有问题,这是硬件出问题了吗?还是设置的问题?
[code]#include <REGX52.H>
回复

使用道具 举报

6#
ID:988270 发表于 2021-12-5 23:04 | 只看该作者
188610329 发表于 2021-12-5 22:58
你读秒的时候, 往 DS1302 发出去的就是 0x81 吧? 所以你最后读出来 0x81, 说明,你压根没完成读取,读 ...

那就是读的程序有问题了,但是0x81是存储秒的地址呀,就算读取 错误也不应该返回一个原地址呀
回复

使用道具 举报

7#
ID:624769 发表于 2021-12-6 15:37 | 只看该作者
天赋异禀 发表于 2021-12-5 23:04
那就是读的程序有问题了,但是0x81是存储秒的地址呀,就算读取 错误也不应该返回一个原地址呀

你DS1302 的读写代码写得非常“妖异”,很抱歉,我看不明白。

建议是,你直接用串口,依次 发送 0x81  0x83   0x91 这些,让单片机 传送到 DS1302 后回传给串口,有助于你分析。  然后, 利用串口  发送比如  0x80 0x00, 让单片机转发给DS1302让DS1302跑起来后, 再用 0x81 读一下看看效果,是否会数据变化,通过这些综合判断一下,是啥问题,或者下载一个中规中矩的DS1302的代码,尝试一下读写看看。
回复

使用道具 举报

8#
ID:401564 发表于 2021-12-6 23:36 | 只看该作者
如果是普中的板子,有可能是P3.4或者P3.5或者P3.6没有上拉电阻
你看一下原理图,认真看一下
回复

使用道具 举报

9#
ID:584814 发表于 2021-12-8 15:34 | 只看该作者
定型的板子,板载的时钟芯片肯定不会有什么没上拉之类的问题。
从现象上看,是读取时钟数据不正常。
可以用试验板所配的原代码跑一下,正常后再根据自己需要修改。
还有个恶心的问题,就是当备用电池没电、芯片是仿的没仿好的情况下,必须先写时钟数据然后读取才能正常,换句话说如果你不先写个逻辑正确的数据就不会出正常的结果(一般会走时但乱走,也有不走的)。
另:记得有些这种板上时钟有个跳线(比如图中黄色的那个切换板载模块用的),如果不按要求做就相当于没接上时钟模块
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表