找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 2534|回復(fù): 8
打印 上一主題 下一主題
收起左側(cè)

單片機(jī)+DS1302時(shí)鐘芯片程序讀數(shù)據(jù)一直是29

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
    DS1302時(shí)鐘芯片,按照手冊(cè)寫(xiě)的呀!為什么在單片機(jī)開(kāi)發(fā)板上一直2081-29-29  29:29:29 ,我是用的LCD1602作為顯示器,程序燒寫(xiě)進(jìn)去以后一直是這樣。其中的LCD1602顯示程序沒(méi)有問(wèn)題,可以不用看,應(yīng)該是DS1302的程序哪里出了問(wèn)題,附件里我加了keil5的工程文件,大佬們有空幫我看一下,不勝感激。我網(wǎng)上查過(guò)資料,也有很多人遇到DS1302的這種問(wèn)題,但沒(méi)有合適的解決我的問(wèn)題。extern unsigned char Real_Time[]; 已經(jīng)設(shè)置為全局變量。

單片機(jī)源程序如下:
  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顯示數(shù)字,分別是,第一行,第一列,數(shù)字位數(shù)。
  10.         LCD_ShowString(1,5,"-  -");//顯示字符串
  11.         LCD_ShowString(2,3,":  :");
  12.         DS1302_Init();//初始化1302
  13.   Set_Time();//設(shè)置給定的時(shí)間
  14.         
  15.         while(1)
  16.         {
  17.                 Read_Time();//讀取時(shí)間
  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. //寫(xiě)指令
  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};//設(shè)定的時(shí)間,依次為 年/月/日/時(shí)/分/秒/周
  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寫(xiě)命令
  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);//關(guān)閉寫(xiě)保護(hù)
  98.         DS1302_WriteByte(DS1302_Year,21);//設(shè)置年
  99.         DS1302_WriteByte(DS1302_Month,Time[1]);//設(shè)置年
  100.         DS1302_WriteByte(DS1302_Day,Time[2]);//設(shè)置年
  101.         DS1302_WriteByte(DS1302_Hour,Time[3]);//設(shè)置年
  102.         DS1302_WriteByte(DS1302_Minute,Time[4]);//設(shè)置年
  103.         DS1302_WriteByte(DS1302_Second,Time[5]);//設(shè)置年
  104.         DS1302_WriteByte(DS1302_Week,Time[6]);//設(shè)置年
  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. }
復(fù)制代碼

51hei圖片_20211205210428.jpg (424.15 KB, 下載次數(shù): 179)

51hei圖片_20211205210428.jpg

06DS1302時(shí)鐘芯片.zip

42.37 KB, 下載次數(shù): 8

keil5工程文件

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:624769 發(fā)表于 2021-12-5 22:04 | 只看該作者
你太依賴顯示屏了,

你先用串口,把從DS1302中讀取出來(lái)的值原封不動(dòng)的發(fā)出來(lái), 串口助手 直接原封不動(dòng)的 HEX接收, HEX顯示,看看到底是什么值,然后分析是什么問(wèn)題, 你這29都是轉(zhuǎn)碼以后的值了,要從源頭分析。
幾個(gè)參考值,秒為默認(rèn)上電后是 0x80, 寫(xiě)保護(hù)位默認(rèn)上電后是 0x00, 充電設(shè)置位,默認(rèn)上電后是 0x5C, 別急著寫(xiě)數(shù)據(jù),先讀數(shù)據(jù),看看對(duì)不對(duì)了,再驗(yàn)證其他的。
回復(fù)

使用道具 舉報(bào)

板凳
ID:988270 發(fā)表于 2021-12-5 22:31 | 只看該作者
188610329 發(fā)表于 2021-12-5 22:04
你太依賴顯示屏了,

你先用串口,把從DS1302中讀取出來(lái)的值原封不動(dòng)的發(fā)出來(lái), 串口助手 直接原封不動(dòng)的 ...

剛用串口測(cè)試了一下,讀出來(lái)數(shù)據(jù)是81,在秒的位置讀出來(lái)的一直是81,因?yàn)镈S1302輸出的是BCD碼,所以轉(zhuǎn)換一下,其實(shí)是129,剛好對(duì)應(yīng)上LCD顯示的29
回復(fù)

使用道具 舉報(bào)

地板
ID:624769 發(fā)表于 2021-12-5 22:58 | 只看該作者
天賦異稟 發(fā)表于 2021-12-5 22:31
剛用串口測(cè)試了一下,讀出來(lái)數(shù)據(jù)是81,在秒的位置讀出來(lái)的一直是81,因?yàn)镈S1302輸出的是BCD碼,所以轉(zhuǎn)換 ...

你讀秒的時(shí)候, 往 DS1302 發(fā)出去的就是 0x81 吧? 所以你最后讀出來(lái) 0x81, 說(shuō)明,你壓根沒(méi)完成讀取,讀的,就是你發(fā)的,
回復(fù)

使用道具 舉報(bào)

5#
ID:988270 發(fā)表于 2021-12-5 23:02 | 只看該作者
天賦異稟 發(fā)表于 2021-12-5 22:31
剛用串口測(cè)試了一下,讀出來(lái)數(shù)據(jù)是81,在秒的位置讀出來(lái)的一直是81,因?yàn)镈S1302輸出的是BCD碼,所以轉(zhuǎn)換 ...

我剛又用串口工具測(cè)試了一下,下面的程序當(dāng)我給出P3_5=1,串口接收到的數(shù)據(jù)是01 01 01 00 00 00這樣一直循環(huán),但如果是P3_0接口就沒(méi)有問(wèn)題,這是硬件出問(wèn)題了嗎?還是設(shè)置的問(wèn)題?
[code]#include <REGX52.H>
回復(fù)

使用道具 舉報(bào)

6#
ID:988270 發(fā)表于 2021-12-5 23:04 | 只看該作者
188610329 發(fā)表于 2021-12-5 22:58
你讀秒的時(shí)候, 往 DS1302 發(fā)出去的就是 0x81 吧? 所以你最后讀出來(lái) 0x81, 說(shuō)明,你壓根沒(méi)完成讀取,讀 ...

那就是讀的程序有問(wèn)題了,但是0x81是存儲(chǔ)秒的地址呀,就算讀取 錯(cuò)誤也不應(yīng)該返回一個(gè)原地址呀
回復(fù)

使用道具 舉報(bào)

7#
ID:624769 發(fā)表于 2021-12-6 15:37 | 只看該作者
天賦異稟 發(fā)表于 2021-12-5 23:04
那就是讀的程序有問(wèn)題了,但是0x81是存儲(chǔ)秒的地址呀,就算讀取 錯(cuò)誤也不應(yīng)該返回一個(gè)原地址呀

你DS1302 的讀寫(xiě)代碼寫(xiě)得非!把悺保鼙,我看不明白。

建議是,你直接用串口,依次 發(fā)送 0x81  0x83   0x91 這些,讓單片機(jī) 傳送到 DS1302 后回傳給串口,有助于你分析。  然后, 利用串口  發(fā)送比如  0x80 0x00, 讓單片機(jī)轉(zhuǎn)發(fā)給DS1302讓DS1302跑起來(lái)后, 再用 0x81 讀一下看看效果,是否會(huì)數(shù)據(jù)變化,通過(guò)這些綜合判斷一下,是啥問(wèn)題,或者下載一個(gè)中規(guī)中矩的DS1302的代碼,嘗試一下讀寫(xiě)看看。
回復(fù)

使用道具 舉報(bào)

8#
ID:401564 發(fā)表于 2021-12-6 23:36 | 只看該作者
如果是普中的板子,有可能是P3.4或者P3.5或者P3.6沒(méi)有上拉電阻
你看一下原理圖,認(rèn)真看一下
回復(fù)

使用道具 舉報(bào)

9#
ID:584814 發(fā)表于 2021-12-8 15:34 | 只看該作者
定型的板子,板載的時(shí)鐘芯片肯定不會(huì)有什么沒(méi)上拉之類(lèi)的問(wèn)題。
從現(xiàn)象上看,是讀取時(shí)鐘數(shù)據(jù)不正常。
可以用試驗(yàn)板所配的原代碼跑一下,正常后再根據(jù)自己需要修改。
還有個(gè)惡心的問(wèn)題,就是當(dāng)備用電池沒(méi)電、芯片是仿的沒(méi)仿好的情況下,必須先寫(xiě)時(shí)鐘數(shù)據(jù)然后讀取才能正常,換句話說(shuō)如果你不先寫(xiě)個(gè)邏輯正確的數(shù)據(jù)就不會(huì)出正常的結(jié)果(一般會(huì)走時(shí)但亂走,也有不走的)。
另:記得有些這種板上時(shí)鐘有個(gè)跳線(比如圖中黃色的那個(gè)切換板載模塊用的),如果不按要求做就相當(dāng)于沒(méi)接上時(shí)鐘模塊
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表