久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

51單片機DS1302簡要記錄

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:825513 發(fā)表于 2021-5-16 20:40 | 只看該作者 |只看大圖 回帖獎勵 |倒序瀏覽 |閱讀模式
寫了一個DS1302的程序,在開發(fā)板上成功運行,通過LCD1602顯示時間,現(xiàn)在分享出來,給像我這樣的單片機萌新一個參考吧。

從2021年5月11日0時0分0秒開始計時并在LCD1602上顯示,源碼如下:

  1. #include<reg52.h>
  2. #include<intrins.h>

  3. sbit RST=P2^4;
  4. sbit CLK=P2^1;
  5. sbit IO=P2^0;
  6. sbit RS=P1^0;
  7. sbit RW=P1^1;
  8. sbit E=P2^5;
  9. sbit DU=P2^6;

  10. unsigned char num[]={"0123456789"};                //LCD1602顯示的數(shù)字字符

  11. void X()                //關(guān)閉數(shù)碼管
  12. {
  13.         DU=1;
  14.         P0=0x00;
  15.         DU=0;
  16. }

  17. void Delay()
  18. {
  19.         _nop_();
  20. }

  21. void Write_Bit_DS1302(unsigned char DAT)                //向DS1302寫入一字節(jié)的數(shù)據(jù)
  22. {
  23.         unsigned char i;
  24.         CLK=0;
  25.         Delay();
  26.         for(i=0;i<8;i++)
  27.         {
  28.                 IO=DAT&0x01;                //低位在前,高位在后
  29.                 Delay();
  30.                 CLK=1;                //時鐘信號上升沿,寫入數(shù)據(jù)
  31.                 Delay();
  32.                 CLK=0;                //重新拉低CLK,形成脈沖
  33.                 DAT>>=1;                //將DAT的各數(shù)據(jù)位右移1位,準備寫入下一數(shù)據(jù)位
  34.         }
  35. }

  36. void Write_DS1302(unsigned char CMD,unsigned char DAT)                //向DS1302寫入命令和數(shù)據(jù)
  37. {
  38.         RST=0;                //禁止數(shù)據(jù)傳輸
  39.         CLK=0;                //在寫入數(shù)據(jù)前確保CLK置低電平
  40.         RST=1;                //開始數(shù)據(jù)傳輸
  41.         Delay();
  42.         Write_Bit_DS1302(CMD);                //寫入命令
  43.         Write_Bit_DS1302(DAT);                //寫入數(shù)據(jù)
  44.         CLK=1;
  45.         RST=0;
  46. }

  47. unsigned char Read_Bit_DS1302()                //從DS1302讀出一字節(jié)的數(shù)據(jù)
  48. {
  49.         unsigned char i,DAT;
  50.         Delay();
  51.         for(i=0;i<8;i++)
  52.         {
  53.                 DAT>>=1;
  54.                 if(IO==1)
  55.                 {
  56.                         DAT|=0x80;
  57.                 }
  58.                 CLK=1;
  59.                 Delay();
  60.                 CLK=0;                //時鐘信號下降沿,讀出數(shù)據(jù)
  61.                 Delay();
  62.         }
  63.         return DAT;
  64. }

  65. unsigned char Read_DS1302(unsigned char CMD)                //向DS1302寫入命令后再從DS1302讀出數(shù)據(jù)
  66. {
  67.         unsigned char DAT;
  68.         RST=0;
  69.         CLK=0;
  70.         RST=1;
  71.         Write_Bit_DS1302(CMD);                //寫入命令
  72.         DAT=Read_Bit_DS1302();                //讀出數(shù)據(jù)
  73.         CLK=1;
  74.         RST=0;
  75.         return DAT;
  76. }

  77. void Init_DS1302()                //DS1302初始化
  78. {
  79.         unsigned char X;
  80.         X=Read_DS1302(0x81);
  81.         if(X&0x80)                //判斷DS1302是否處于運行狀態(tài)
  82.         {
  83.                 Write_DS1302(0x8e,0x00);                //允許將數(shù)據(jù)寫入DS1302的寄存器
  84.                 Write_DS1302(0x80,((00/10)<<4|(00%10)));                //寫入“秒”的初始值,需要將LCD1602顯示的數(shù)字的ASCII值轉(zhuǎn)換成BCD碼
  85.                 Write_DS1302(0x82,((00/10)<<4|(00%10)));                //寫入“分”的初始值
  86.                 Write_DS1302(0x84,((00/10)<<4|(00%10)));                //寫入“時”的初始值
  87.                 Write_DS1302(0x86,((11/10)<<4|(11%10)));                //寫入“日”的初始值
  88.                 Write_DS1302(0x88,((5/10)<<4|(5%10)));                //寫入“月”的初始值
  89.                 Write_DS1302(0x8c,((21/10)<<4|(21%10)));                //寫入“年”的初始值
  90.                 Write_DS1302(0x8e,0x80);                //禁止將數(shù)據(jù)寫入DS1302的寄存器
  91.         }
  92. }

  93. void Delay5ms()
  94. {
  95.         unsigned char i,j;
  96.         _nop_();
  97.         i=9;
  98.         j=244;
  99.         do
  100.         {
  101.                 while(--j);
  102.         }
  103.         while(--i);
  104. }

  105. int ReadBusy()                //LCD1602“讀忙”操作
  106. {
  107.         int temp;
  108.         RS=0;
  109.         RW=1;
  110.         _nop_();
  111.         P0=0xff;
  112.         _nop_();
  113.         E=1;
  114.         _nop_();
  115.         temp=P0;
  116.         _nop_();
  117.         E=0;
  118.         return(temp&0x80);
  119. }

  120. void Write_Com(char com)                //LCD1602“寫命令”操作
  121. {
  122.         while(ReadBusy());
  123.         RS=0;
  124.         RW=0;
  125.         E=0;
  126.         _nop_();
  127.         P0=com;
  128.         _nop_();
  129.         E=1;
  130.         Delay5ms();
  131.         E=0;
  132.         Delay5ms();
  133. }

  134. void Write_Dat(char dat)                //LCD1602“寫數(shù)據(jù)”操作
  135. {
  136.         while(ReadBusy());
  137.         RS=1;
  138.         RW=0;
  139.         E=0;
  140.         _nop_();
  141.         P0=dat;
  142.         _nop_();
  143.         E=1;
  144.         Delay5ms();
  145.         E=0;
  146.         Delay5ms();
  147. }

  148. void LCD1602_Init()                //LCD1602初始化
  149. {
  150.         Delay5ms();                //延時15ms,首次寫入LCD1602時應(yīng)給LCD1602一段較長的響應(yīng)時間
  151.         Delay5ms();
  152.         Delay5ms();
  153.         Write_Com(0x38);                //顯示模式設(shè)置:16*2顯示、5*7點陣,連續(xù)寫入3次,確保LCD1602初始化成功
  154.         Delay5ms();
  155.         Write_Com(0x38);
  156.         Delay5ms();
  157.         Write_Com(0x38);
  158.         Delay5ms();
  159.         Write_Com(0x0c);                //顯示模式設(shè)置:開顯示、光標不顯示、光標不閃爍
  160.         Delay5ms();
  161.         Write_Com(0x06);                //顯示模式設(shè)置:光標右移,字符不右移
  162.         Delay5ms();
  163.         Write_Com(0x01);                //清除屏幕
  164.         Delay5ms();
  165. }

  166. void Display_Second(unsigned char x)                //LCD1602顯示“秒”的數(shù)值
  167. {
  168.         unsigned char i,j;
  169.         i=x/10;                //取數(shù)值的十位
  170.         j=x%10;                //取數(shù)值的個位
  171.         Write_Com(0x80+0x49);                //寫入在LCD1602上顯示的位置
  172.         Write_Dat(num[i]);
  173.         Write_Dat(num[j]);
  174.         Delay5ms();
  175. }

  176. void Display_Minute(unsigned char x)                //LCD1602顯示“分”的數(shù)值
  177. {
  178.         unsigned char i,j;
  179.         i=x/10;
  180.         j=x%10;
  181.         Write_Com(0x80+0x46);
  182.         Write_Dat(num[i]);
  183.         Write_Dat(num[j]);
  184.         Delay5ms();
  185. }

  186. void Display_Hour(unsigned char x)                //LCD1602顯示“時”的數(shù)值
  187. {
  188.         unsigned char i,j;
  189.         i=x/10;
  190.         j=x%10;
  191.         Write_Com(0x80+0x43);
  192.         Write_Dat(num[i]);
  193.         Write_Dat(num[j]);
  194.         Delay5ms();
  195. }

  196. void Display_Day(unsigned char x)                //LCD1602顯示“日”的數(shù)值
  197. {
  198.         unsigned char i,j;
  199.         i=x/10;
  200.         j=x%10;
  201.         Write_Com(0x80+0x0c);
  202.         Write_Dat(num[i]);
  203.         Write_Dat(num[j]);
  204.         Delay5ms();
  205. }

  206. void Display_Month(unsigned char x)                //LCD1602顯示“月”的數(shù)值
  207. {
  208.         unsigned char i,j;
  209.         i=x/10;
  210.         j=x%10;
  211.         Write_Com(0x80+0x09);
  212.         Write_Dat(num[i]);
  213.         Write_Dat(num[j]);
  214.         Delay5ms();
  215. }

  216. void Display_Year(unsigned char x)                //LCD1602顯示“年”的數(shù)值
  217. {
  218.         unsigned char i,j;
  219.         i=x/10;
  220.         j=x%10;
  221.         Write_Com(0x80+0x06);
  222.         Write_Dat(num[i]);
  223.         Write_Dat(num[j]);
  224.         Delay5ms();
  225. }

  226. void main()
  227. {
  228.         unsigned char second,minute,hour,day,month,year;
  229.         unsigned char temp;                //暫存從DS1302讀出的數(shù)據(jù)
  230.         X();
  231.         LCD1602_Init();
  232.         Write_Com(0x80+0x01);
  233.         Write_Dat('D');
  234.         Write_Dat('A');
  235.         Write_Dat('T');
  236.         Write_Dat('E');
  237.         Write_Dat(':');
  238.         Delay5ms();
  239.         Write_Com(0x80+0x08);
  240.         Write_Dat('-');
  241.         Delay5ms();
  242.         Write_Com(0x80+0x0b);
  243.         Write_Dat('-');
  244.         Delay5ms();
  245.         Write_Com(0x80+0x45);
  246.         Write_Dat(':');
  247.         Delay5ms();
  248.         Write_Com(0x80+0x48);
  249.         Write_Dat(':');
  250.         Delay5ms();
  251.         Init_DS1302();
  252.         
  253.         while(1)
  254.         {
  255.                 temp=Read_DS1302(0x81);
  256.                 second=((temp&0x70)>>4)*10+(temp&0x0f);                //將“秒”的BCD碼轉(zhuǎn)換成對應(yīng)的ASCII值
  257.                 Display_Second(second);
  258.                 temp=Read_DS1302(0x83);
  259.                 minute=((temp&0x70)>>4)*10+(temp&0x0f);                //將“分”的BCD碼轉(zhuǎn)換成對應(yīng)的ASCII值
  260.                 Display_Minute(minute);
  261.                 temp=Read_DS1302(0x85);
  262.                 hour=((temp&0x70)>>4)*10+(temp&0x0f);                //將“時”的BCD碼轉(zhuǎn)換成對應(yīng)的ASCII值
  263.                 Display_Hour(hour);
  264.                 temp=Read_DS1302(0x87);
  265.                 day=((temp&0x70)>>4)*10+(temp&0x0f);                //將“日”的BCD碼轉(zhuǎn)換成對應(yīng)的ASCII值
  266.                 Display_Day(day);
  267.                 temp=Read_DS1302(0x89);
  268.                 month=((temp&0x70)>>4)*10+(temp&0x0f);                //將“月”的BCD碼轉(zhuǎn)換成對應(yīng)的ASCII值
  269.                 Display_Month(month);
  270.                 temp=Read_DS1302(0x8d);
  271.                 year=((temp&0x70)>>4)*10+(temp&0x0f);                //將“年”的BCD碼轉(zhuǎn)換成對應(yīng)的ASCII值
  272.                 Display_Year(year);
  273.         }
  274. }
復(fù)制代碼

以下為原理圖

LCD1602模塊.png (30.13 KB, 下載次數(shù): 150)

LCD1602模塊.png

DS1302時鐘模塊.png (19.63 KB, 下載次數(shù): 161)

DS1302時鐘模塊.png

評分

參與人數(shù) 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

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

使用道具 舉報

沙發(fā)
ID:924117 發(fā)表于 2021-5-20 22:05 | 只看該作者
感謝分享,有個疑問,I/O接口的輸出方式是什么?
回復(fù)

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

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

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

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 中文字幕一区二区三区乱码图片 | 国产精品欧美一区二区三区 | 国产成人黄色 | 在线免费国产 | av影音在线 | www九色| 亚洲国产成人精品久久久国产成人一区 | 在线播放91| 男人天堂网址 | 在线色网 | 伊人久久成人 | 精品国产欧美一区二区三区成人 | 国产精品久久久久久久久免费丝袜 | 欧洲妇女成人淫片aaa视频 | 日韩小视频| 午夜精品久久久久久 | 国产欧美一区二区三区在线看 | 成人免费小视频 | 久久国产婷婷国产香蕉 | 免费看一区二区三区 | 亚洲综合精品 | 成人精品一区二区三区中文字幕 | 亚洲高清av在线 | 久久成人免费 | 最新av在线网址 | 精品美女视频在免费观看 | 中文字幕一区二区三区精彩视频 | 亚洲成人在线视频播放 | 欧美色综合天天久久综合精品 | 羞羞视频免费在线观看 | 精品国产91 | 国产成人综合在线 | 美女露尿口视频 | 欧美精品福利视频 | 亚洲精品一区二区三区丝袜 | 久久99精品久久久久久 | 亚洲美女视频 | 国产一区 | 亚洲国产欧美91 | 婷婷99| 欧美日韩在线观看一区二区三区 |