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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 5225|回復: 6
打印 上一主題 下一主題
收起左側

單片機+DS1302可調時鐘代碼(LCD1602顯示)Proteus仿真圖

  [復制鏈接]
跳轉到指定樓層
樓主
用了兩天時間做了這個仿真,時鐘計時(年月日時分秒)使用DS1302實現,計時范圍2000年1月1日0時0分0秒~2099年12月31日23時59分59秒,上電初始顯示時間2000年1月1日0時0分0秒,通過三個按鍵實現時間修改。按下K1按鍵來依次選中需要修改的時間項(年月日時分秒),此時被選中的時間項將閃爍顯示,然后可以通過K2和K3按鍵分別進行數值加1和減1,再按下K1切換到下一時間項,一直到切換到時間項“秒”后按下K1即推出時間修改,LCD1602顯示繼續走時。

當某個時間項的數值加到最大時,再按K2鍵加,則到最小值,(例如“年”加到99,再加則到00);
當某個時間項的數值減到最小時,再按K3鍵減,則到最大值,(例如“時”減到00,再減則到23)。
(閏年平年2月份的天數“日”的調整正常,例如2040年(閏年),則該年的2月份的日數最大加到29,再加,則到1;2041年(平年)的2月份的日數最大加到28,再加,則到1)

仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)


單片機源程序如下:
  1. #include<reg52.h>
  2. #include<intrins.h>

  3. sbit RST=P1^3;
  4. sbit CLK=P1^4;
  5. sbit IO=P1^5;
  6. sbit RS=P2^5;
  7. sbit RW=P2^6;
  8. sbit E=P2^7;
  9. sbit K1=P3^4;                //時間(修改)選擇
  10. sbit K2=P3^5;                //時間“加”
  11. sbit K3=P3^6;                //時間“減”

  12. unsigned char second,minute,hour,day,month,year;                //在LCD1602上顯示的數值
  13. unsigned char temp_s,temp_min,temp_h,temp_d,temp_mon,temp_y;                //暫存從DS1302讀出的數據
  14. unsigned char x=0;                //選擇修改時間中的某一個數值

  15. void Delay()
  16. {
  17.         _nop_();
  18. }

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

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

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

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

  75. void Init_DS1302()                //DS1302初始化
  76. {
  77.         Write_DS1302(0x8E,0x00);                //允許將數據寫入DS1302的寄存器
  78.         Write_DS1302(0x80,((0/10)<<4)+(0%10));                //寫入“秒”的初始值,需要將LCD1602顯示的數值轉換成BCD碼
  79.         Write_DS1302(0x82,((0/10)<<4)+(0%10));                //寫入“分”的初始值
  80.         Write_DS1302(0x84,((0/10)<<4)+(0%10));                //寫入“時”的初始值
  81.         Write_DS1302(0x86,((1/10)<<4)+(1%10));                //寫入“日”的初始值
  82.         Write_DS1302(0x88,((1/10)<<4)+(1%10));                //寫入“月”的初始值
  83.         Write_DS1302(0x8C,((0/10)<<4)+(0%10));                //寫入“年”的初始值
  84. }

  85. void Delay5ms()
  86. {
  87.         unsigned char i,j;
  88.         _nop_();
  89.         i=10;
  90.         j=183;
  91.         do
  92.         {
  93.                 while(--j);
  94.         }
  95.         while(--i);
  96. }

  97. int LCD1602_ReadBusy()                //LCD1602“讀忙”操作
  98. {
  99.         int temp;
  100.         RS=0;
  101.         RW=1;
  102.         _nop_();
  103.         P0=0xff;
  104.         _nop_();
  105.         E=1;
  106.         _nop_();
  107.         temp=P0;
  108.         _nop_();
  109.         E=0;
  110.         return(temp&0x80);
  111. }

  112. void LCD1602_Write_Com(char com)                //LCD1602“寫命令”操作
  113. {
  114.         while(LCD1602_ReadBusy());
  115.         RS=0;
  116.         RW=0;
  117.         E=0;
  118.         _nop_();
  119.         P0=com;
  120.         _nop_();
  121.         E=1;
  122.         Delay5ms();
  123.         E=0;
  124.         Delay5ms();
  125. }

  126. void LCD1602_Write_Dat(char dat)                //LCD1602“寫數據”操作
  127. {
  128.         while(LCD1602_ReadBusy());
  129.         RS=1;
  130.         RW=0;
  131.         E=0;
  132.         _nop_();
  133.         P0=dat;
  134.         _nop_();
  135.         E=1;
  136.         Delay5ms();
  137.         E=0;
  138.         Delay5ms();
  139. }

  140. void LCD1602_Init()                //LCD1602初始化
  141. {
  142.         Delay5ms();
  143.         Delay5ms();
  144.         Delay5ms();
  145.         LCD1602_Write_Com(0x38);
  146.         Delay5ms();
  147.         LCD1602_Write_Com(0x0C);
  148.         Delay5ms();
  149.         LCD1602_Write_Com(0x06);
  150.         Delay5ms();
  151.         LCD1602_Write_Com(0x01);
  152.         Delay5ms();
  153. }

  154. void LCD1602_Display_Init()                //在LCD1602的恒定位置上顯示恒定的字符
  155. {
  156.         LCD1602_Write_Com(0x80+0x03);
  157.         LCD1602_Write_Dat(0x30+2);
  158.         LCD1602_Write_Dat(0x30+0);
  159.         Delay5ms();
  160.         LCD1602_Write_Com(0x80+0x07);
  161.         LCD1602_Write_Dat('/');
  162.         Delay5ms();
  163.         LCD1602_Write_Com(0x80+0x0A);
  164.         LCD1602_Write_Dat('/');
  165.         Delay5ms();
  166.         LCD1602_Write_Com(0x80+0x46);
  167.         LCD1602_Write_Dat(':');
  168.         Delay5ms();
  169.         LCD1602_Write_Com(0x80+0x49);
  170.         LCD1602_Write_Dat(':');
  171.         Delay5ms();
  172. }

  173. void Display_Second(unsigned char x)                //LCD1602顯示“秒”的數值
  174. {
  175.         unsigned char i,j;
  176.         i=x/10;
  177.         j=x%10;
  178.         LCD1602_Write_Com(0x80+0x4A);
  179.         LCD1602_Write_Dat(0x30+i);
  180.         LCD1602_Write_Dat(0x30+j);
  181.         Delay5ms();
  182. }

  183. void Display_Minute(unsigned char x)                //LCD1602顯示“分”的數值
  184. {
  185.         unsigned char i,j;
  186.         i=x/10;
  187.         j=x%10;
  188.         LCD1602_Write_Com(0x80+0x47);
  189.         LCD1602_Write_Dat(0x30+i);
  190.         LCD1602_Write_Dat(0x30+j);
  191.         Delay5ms();
  192. }

  193. void Display_Hour(unsigned char x)                //LCD1602顯示“時”的數值
  194. {
  195.         unsigned char i,j;
  196.         i=x/10;
  197.         j=x%10;
  198.         LCD1602_Write_Com(0x80+0x44);
  199.         LCD1602_Write_Dat(0x30+i);
  200.         LCD1602_Write_Dat(0x30+j);
  201.         Delay5ms();
  202. }

  203. void Display_Day(unsigned char x)                //LCD1602顯示“日”的數值
  204. {
  205.         unsigned char i,j;
  206.         i=x/10;
  207.         j=x%10;
  208.         LCD1602_Write_Com(0x80+0x0B);
  209.         LCD1602_Write_Dat(0x30+i);
  210.         LCD1602_Write_Dat(0x30+j);
  211.         Delay5ms();
  212. }

  213. void Display_Month(unsigned char x)                //LCD1602顯示“月”的數值
  214. {
  215.         unsigned char i,j;
  216.         i=x/10;
  217.         j=x%10;
  218.         LCD1602_Write_Com(0x80+0x08);
  219.         LCD1602_Write_Dat(0x30+i);
  220.         LCD1602_Write_Dat(0x30+j);
  221.         Delay5ms();
  222. }

  223. void Display_Year(unsigned char x)                //LCD1602顯示“年”的數值
  224. {
  225.         unsigned char i,j;
  226.         i=x/10;
  227.         j=x%10;
  228.         LCD1602_Write_Com(0x80+0x05);
  229.         LCD1602_Write_Dat(0x30+i);
  230.         LCD1602_Write_Dat(0x30+j);
  231.         Delay5ms();
  232. }

  233. void Convert()
  234. {
  235.         temp_s=Read_DS1302(0x81);
  236.         second=(temp_s>>4)*10+(temp_s&0x0F);                //將“秒”的BCD碼轉換成對應的ASCII值
  237.         
  238.         temp_min=Read_DS1302(0x83);
  239.         minute=(temp_min>>4)*10+(temp_min&0x0F);                //將“分”的BCD碼轉換成對應的ASCII值
  240.         
  241.         temp_h=Read_DS1302(0x85);
  242.         hour=(temp_h>>4)*10+(temp_h&0x0F);                //將“時”的BCD碼轉換成對應的ASCII值
  243.         
  244.         temp_d=Read_DS1302(0x87);
  245.         day=(temp_d>>4)*10+(temp_d&0x0F);                //將“日”的BCD碼轉換成對應的ASCII值
  246.         
  247.         temp_mon=Read_DS1302(0x89);
  248.         month=(temp_mon>>4)*10+(temp_mon&0x0F);                //將“月”的BCD碼轉換成對應的ASCII值
  249.         
  250.         temp_y=Read_DS1302(0x8D);
  251.         year=(temp_y>>4)*10+(temp_y&0x0F);                //將“年”的BCD碼轉換成對應的ASCII值
  252. }

  253. void Delay10ms()
  254. {
  255.         unsigned char i,j;
  256.         i=20;
  257.         j=113;
  258.         do
  259.         {
  260.                 while(--j);
  261.         }
  262.         while(--i);
  263. }

  264. unsigned char Get_Key()                //獲取按鍵值
  265. {
  266.         static bit flag=0;
  267.         unsigned char k=0;
  268.         
  269.         if((flag==0)&&((K1==0)||(K2==0)||(K3==0)))
  270.         {
  271.                 Delay10ms();
  272.                 flag=1;
  273.                 if(K1==0)
  274.                 {
  275.                         k=1;
  276.                 }
  277.                 else if(K2==0)
  278.                 {
  279.                         k=2;
  280.                 }
  281.                 else if(K3==0)
  282.                 {
  283.                         k=3;
  284.                 }
  285.         }
  286.         else if((K1==1)&&(K2==1)&&(K3==1))
  287.         {
  288.                 flag=0;
  289.         }
  290.         return k;
  291. }

  292. void Set_Time(unsigned char num)                //設置DS1302的起始計時
  293. {
  294.         unsigned char temp_second,temp_minute,temp_hour,temp_day,temp_month,temp_year;                //暫存經過轉換后得到的BCD碼
  295.         
  296.         switch(num)
  297.         {
  298.                 case 1:
  299.                         if(++x>6)                //時間(修改)選擇
  300.                         {
  301.                                 x=0;
  302.                         }
  303.                 break;
  304.                         
  305.                 case 2:                //時間“加”
  306.                         if(x==1)                //年
  307.                         {
  308.                                 year++;
  309.                                 if(year>99)
  310.                                 {
  311.                                         year=0;
  312.                                 }
  313.                                 temp_year=((year/10)<<4)+(year%10);
  314.                                 Write_DS1302(0x8C,temp_year);
  315.                         }
  316.                         
  317.                         if(x==2)                //月
  318.                         {
  319.                                 month++;
  320.                                 if(month>12)
  321.                                 {
  322.                                         month=1;
  323.                                 }
  324.                                 temp_month=((month/10)<<4)+(month%10);
  325.                                 Write_DS1302(0x88,temp_month);
  326.                         }
  327.                         
  328.                         if(x==3)                //日
  329.                         {
  330.                                 day++;
  331.                                 if(month==1||month==3||month==5||month==7||month==8||month==10||month==12)                //大月有31天
  332.                                 {
  333.                                         if(day>31)
  334.                                         {
  335.                                                 day=1;
  336.                                         }
  337.                                 }
  338.                                 else if(month==4||month==6||month==9||month==11)                //小月有30天
  339.                                 {
  340.                                         if(day>30)
  341.                                         {
  342.                                                 day=1;
  343.                                         }
  344.                                 }
  345.                                 else if(month==2&&(year%4==0))                //閏年的二月有29天
  346. ……………………

  347. …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼

所有資料51hei附件下載:
DS1302時間顯示(LCD1602).zip (22.12 KB, 下載次數: 190)


評分

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

查看全部評分

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

使用道具 舉報

沙發
ID:920142 發表于 2022-4-8 13:34 | 只看該作者
特別好,參考了一下寫出了調節時間的代碼,值得學習
回復

使用道具 舉報

板凳
ID:1057381 發表于 2022-12-21 19:59 | 只看該作者
感謝大佬,如果需要多加一個移位確認的開關,需要怎么改呢
回復

使用道具 舉報

地板
ID:1132062 發表于 2024-9-16 23:27 | 只看該作者
好,感謝
回復

使用道具 舉報

5#
ID:278457 發表于 2024-10-4 02:58 | 只看該作者
強,學習
回復

使用道具 舉報

6#
ID:204072 發表于 2024-12-21 23:47 | 只看該作者
只是到了2099年12月31日后又變成了2000年,LZ能不能再修改一下,謝謝!
回復

使用道具 舉報

7#
ID:204072 發表于 2024-12-21 23:54 | 只看該作者
只是到了2099年12月31日后又回到了2000年1月1日,LZ能否修改一下,謝謝!
回復

使用道具 舉報

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

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 亚洲+变态+欧美+另类+精品 | 国产免费国产 | 欧美成人hd | 久久99久久99 | 久久不卡日韩美女 | 亚洲综合大片69999 | 在线免费观看成人 | 亚洲成人精品一区 | 国产精品污www一区二区三区 | 色综合久 | 日本精品一区二区在线观看 | 精品一区二区在线观看 | 91热在线 | 在线免费观看黄色网址 | 高清成人av | 欧美伦理一区 | 51ⅴ精品国产91久久久久久 | 黄a在线播放 | 中文字幕一区二区不卡 | 国产精品视频一区二区三区不卡 | 91视频大全| 狠狠干av| 97免费在线观看视频 | 午夜三级网站 | 欧美一级二级视频 | 成人欧美一区二区三区在线播放 | 成人a在线 | 午夜影院在线免费观看视频 | 日韩精品成人一区二区三区视频 | 射久久 | 亚洲区中文字幕 | 亚洲精品一区二区在线观看 | 久久久婷婷| 亚洲91精品 | 国产精品一区二区无线 | 91网站在线播放 | 成人欧美一区二区三区视频xxx | 欧美国产日韩一区 | 在线成人av | 国产成人在线视频免费观看 | 久久国内|