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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

基于51單片機的可調數字時鐘程序

[復制鏈接]
跳轉到指定樓層
樓主
ID:790161 發表于 2020-10-13 19:12 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
使用51單片機內部定時器中斷方式一計算時間,在LCD1602液晶顯示小時、分鐘、秒,并且可以使用按鍵調整小時和分鐘,每次到整點時整點報時。
附件含Proteus電路仿真圖,

代碼如下:

  1. //=============================================================
  2. //功能描述:液晶顯示時鐘,可調時間,準備整點時報時
  3. //MCU:STC89C51,晶振頻率:11.0592MHz
  4. //=============================================================
  5. #include<reg51.h>  
  6. #include<stdlib.h>  
  7. #include<intrins.h>  

  8. sbit RS=P2^0;    //寄存器選擇位,將RS位定義為P2.0引腳
  9. sbit RW=P2^1;    //讀寫選擇位,將RW位定義為P2.1引腳
  10. sbit E=P2^2;     //使能信號位,將E位定義為P2.2引腳
  11. sbit BF=P0^7;    //忙碌標志位,,將BF位定義為P0.7引腳
  12. sbit k1=P1^0;    //按鍵調小時加
  13. sbit k2=P1^1;    //按鍵調小時減
  14. sbit k3=P1^2;    //按鍵調分鐘加
  15. sbit k4=P1^3;    //按鍵調分鐘減
  16. sbit beep=P1^4;  //蜂鳴器

  17. unsigned char code digit[ ]={"0123456789"}; //定義字符數組顯示數字
  18. unsigned char code string[ ]={"Weather:Sunny"}; //定義字符數組顯示提示信息
  19. unsigned char count;   //定義變量統計中斷累計次數
  20. unsigned char s,m,h;   //定義變量儲存秒、分鐘和小時
  21. /*==================================================
  22. 函數功能:延時
  23. (3j+2)*i=(3×33+2)×10=1010(微秒),可以認為是1毫秒
  24. ==================================================*/
  25. void delay1ms()        //@11.0592MHz
  26. {
  27.    unsigned char i,j;        
  28.          for(i=0;i<10;i++)
  29.           for(j=0;j<33;j++);                 
  30. }

  31. void delay100ms()                //@11.0592MHz
  32. {
  33.         unsigned char i, j;
  34.         i = 180;
  35.         j = 73;
  36.         do
  37.         {
  38.                 while (--j);
  39.         } while (--i);
  40. }

  41. /*==================================================
  42. 函數功能:延時若干毫秒
  43. ==================================================*/
  44. void delay(unsigned char n)
  45. {
  46.    unsigned char i;
  47.          for(i=0;i<n;i++)
  48.          delay1ms();
  49. }

  50. /*==================================================
  51. 函數功能:蜂鳴器發出聲音
  52. ==================================================*/
  53. void sound(){
  54.          beep=0;
  55.          delay100ms();
  56.          beep=1;
  57.          delay100ms();
  58. }

  59. /*==================================================
  60. 函數功能:判斷液晶模塊的忙碌狀態
  61. ==================================================*/
  62. unsigned char BusyTest(void)
  63.   {
  64.     bit result;
  65.                 RS=0;       //根據規定,RS為低電平,RW為高電平時,可以讀狀態
  66.     RW=1;
  67.     E=1;        //E=1,才允許讀寫
  68.     _nop_();   //空操作
  69.     _nop_();
  70.     _nop_();
  71.     _nop_();   //空操作四個機器周期,給硬件反應時間        
  72.     result=BF;  //將忙碌標志電平賦給result
  73.     E=0;         //將E恢復低電平
  74.     return result;
  75.   }
  76. /*==================================================
  77. 函數功能:將模式設置指令或顯示地址寫入液晶模塊
  78. ==================================================*/
  79. void WriteInstruction (unsigned char dictate)
  80. {   
  81.    while(BusyTest()==1); //如果忙就等待
  82.          RS=0;                  //根據規定,RS和R/W同時為低電平時,可以寫入指令
  83.          RW=0;   
  84.          E=0;                   //E置低電平(根據表8-6,寫指令時,E為高脈沖,
  85.                           // 就是讓E從0到1發生正跳變,所以應先置"0"
  86.          _nop_();
  87.          _nop_();             //空操作兩個機器周期,給硬件反應時間
  88.          P0=dictate;            //將數據送入P0口,即寫入指令或地址
  89.          _nop_();
  90.          _nop_();
  91.          _nop_();
  92.          _nop_();               //空操作四個機器周期,給硬件反應時間
  93.          E=1;                   //E置高電平
  94.          _nop_();
  95.          _nop_();
  96.          _nop_();
  97.          _nop_();               //空操作四個機器周期,給硬件反應時間
  98.           E=0;                  //當E由高電平跳變成低電平時,液晶模塊開始執行命令
  99. }
  100. /*==================================================
  101. 函數功能:指定字符顯示的實際地址
  102. ==================================================*/
  103. void WriteAddress(unsigned char x)
  104. {
  105.      WriteInstruction(x|0x80); //顯示位置的確定方法規定為"80H+地址碼x"
  106. }
  107. /*==================================================
  108. 函數功能:將數據(字符的標準ASCII碼)寫入液晶模塊
  109. ==================================================*/
  110. void WriteData(unsigned char y)
  111. {
  112.     while(BusyTest()==1);  
  113.           RS=1;           //RS為高電平,RW為低電平時,可以寫入數據
  114.           RW=0;
  115.           E=0;            //E置低電平(根據表8-6,寫指令時,E為高脈沖,
  116.                        // 就是讓E從0到1發生正跳變,所以應先置"0"
  117.           P0=y;           //將數據送入P0口,即將數據寫入液晶模塊
  118.           _nop_();
  119.           _nop_();
  120.            _nop_();
  121.      _nop_();       //空操作四個機器周期,給硬件反應時間
  122.           E=1;          //E置高電平
  123.           _nop_();
  124.           _nop_();
  125.           _nop_();
  126.           _nop_();        //空操作四個機器周期,給硬件反應時間
  127.           E=0;            //當E由高電平跳變成低電平時,液晶模塊開始執行命令
  128. }
  129. /*==================================================
  130. 函數功能:對LCD的顯示模式進行初始化設置
  131. ==================================================*/
  132. void LcdInitiate(void)
  133. {
  134.   delay(15);             //延時15ms,首次寫指令時應給LCD一段較長的反應時間
  135.   WriteInstruction(0x38);  //顯示模式設置:16×2顯示,5×7點陣,8位數據接口
  136.         delay(5);               //延時5ms ,給硬件一點反應時間
  137.   WriteInstruction(0x38);
  138.         delay(5);
  139.         WriteInstruction(0x38); //連續三次,確保初始化成功
  140.         delay(5);
  141.         WriteInstruction(0x0c);  //顯示模式設置:顯示開,無光標,光標不閃爍
  142.         delay(5);
  143.         WriteInstruction(0x06);  //顯示模式設置:光標右移,字符不移
  144.         delay(5);
  145.         WriteInstruction(0x01);  //清屏幕指令,將以前的顯示內容清除
  146.         delay(5);

  147. }
  148. /*==================================================
  149. 函數功能:顯示小時、調整小時時間                          
  150. ==================================================*/
  151. void DisplayHour()
  152. {
  153.   unsigned char i,j;
  154.         if(k1==0)           //按鈕k1按下時
  155.                 delay(10);        //延時消抖
  156.         if(k1==0)            //判斷k1按下
  157.         {
  158.                 while(!k1);         //k1狀態取反
  159.                 h++;               //小時數增加
  160.         }
  161.         if(k2==0)            //按鈕k2按下時
  162.                 delay(10);         //延時消抖
  163.         if(k2==0)            //判斷k1按下
  164.         {
  165.                 while(!k2);        //k2狀態取反
  166.                 if(h/10==0&&h%10==0)  //判斷時間是否在24小時上
  167.                 {
  168.                 h=24;                 //當小時在24小時
  169.                 h--;                  //小時數減少為23
  170.                 }
  171.                 else
  172.                         h--;                //小時數減少
  173.         }
  174.         i=h/10;                //取整運算,求得十位數字
  175.         j=h%10;                //取余運算,求得各位數字
  176.   WriteAddress(0x44);   //寫顯示地址,將十位數字顯示在第2行第5列
  177.         WriteData(digit[i]);  //將十位數字的字符常量寫入LCD
  178.         WriteData(digit[j]);  //將個位數字的字符常量寫入LCD

  179. }
  180. /*==================================================
  181. 函數功能:顯示分鐘、調整分鐘時間                           
  182. ==================================================*/
  183. void DisplayMinute()
  184. {
  185.   unsigned char i,j;
  186.   i=m/10;                //取整運算,求得十位數字
  187.         j=m%10;                //取余運算,求得各位數字
  188.                 if(k3==0)             //按鈕k3按下時
  189.                 delay(10);            //延時消抖
  190.         if(k3==0)              //判斷k3按下
  191.         {
  192.                 while(!k3);          //k3狀態取反
  193.                 m++;                  //分鐘數增加
  194.         }
  195.         if(k4==0)                //按鈕k4按下時
  196.                 delay(10);             //延時消抖
  197.         if(k4==0)                  //判斷k4按下
  198.         {
  199.                 while(!k4);             //k4狀態取反
  200.                 if(m/10==0&&m%10==0)    //判斷時間是否在60分鐘上
  201.                 {
  202.                 m=60;                   //當小時在60分鐘
  203.                 m--;                    //分鐘數減少為59
  204.                 if(h==0)                //判斷小時是否在0點                        
  205.                         h=24;
  206.                   h--;
  207.                 }
  208.                 else
  209.                         m--;                    //分鐘數減少
  210.         }
  211.   if(m/10==5&&m%10==9&&s/10==5)  //判斷分鐘數是否在59分50秒
  212.         {
  213.                 sound();                //蜂鳴器響10秒
  214.         }
  215.   WriteAddress(0x47);   //寫顯示地址,將十位數字顯示在第2行第8列
  216.         WriteData(digit[i]);  //將十位數字的字符常量寫入LCD
  217.         WriteData(digit[j]);  //將個位數字的字符常量寫入LCD

  218. }
  219. /*==================================================
  220. 函數功能:顯示秒                        
  221. ==================================================*/
  222. void DisplaySecond()
  223. {
  224.    unsigned char i,j;
  225.           i=s/10;                //取整運算,求得十位數字
  226.           j=s%10;                //取余運算,求得各位數字
  227.   WriteAddress(0x4a);   //寫顯示地址,將十位數字顯示在第2行第11列
  228.         WriteData(digit[i]);  //將十位數字的字符常量寫入LCD
  229.         WriteData(digit[j]);  //將個位數字的字符常量寫入LCD
  230. }

  231. /*==================================================
  232.                  主函數
  233. ==================================================*/
  234. void main(void)
  235. {
  236.   unsigned char i;
  237.   beep=1;          //蜂鳴器初始為0
  238.   LcdInitiate();  //調用LCD初始化函數

  239.   TMOD=0x01;                //使用定時器T0的模式1
  240.         TH0=(65536-46083)/256;    //定時器T0的高8位設置初值
  241.         TL0=(65536-46083)%256;    //定時器T0的低8位設置初值
  242.         EA=1;                     //開總中斷
  243.         ET0=1;                    //定時器T0中斷允許
  244.         TR0=1;                    //啟動定時器T0

  245.         count=0;              //中斷次數初始化為0
  246.         s=0;                  //秒初始化為0
  247.         m=0;                  //分鐘初始化為0
  248.         h=0;                  //小時初始化為0

  249.    WriteAddress(0x02);          //寫地址,從第1行第4列開始顯示
  250.          i=0;              //從字符數組的第1個元素開始顯示
  251.          while(string[i]!='\0')   //只要沒有顯示到字符串的結束標志'\0',就繼續
  252.          {
  253.                  WriteData(string[i]); //將第i個字符數組元素寫入LCD
  254.                  i++;                 //指向下一個數組元素
  255.          }
  256.          WriteAddress(0x46);     //寫地址,將第二個分號顯示在第2行第7列
  257.         WriteData(':');         //將分號的字符常量寫入LCD
  258.         WriteAddress(0x49);     //寫地址,將第二個分號顯示在第2行第10列
  259.         WriteData(':');         //將分號的字符常量寫入LCD  
  260.     while(1)            //無限循環
  261.    {
  262.       DisplayHour();            //顯示小時
  263.                         delay(5);           //給硬件一點反應時間
  264.                         DisplayMinute();    //顯示分鐘
  265.                         delay(5);           //給硬件一點反應時間
  266.                         DisplaySecond();    //顯示秒        
  267.       delay(5);                  //給硬件一點反應時間
  268.    }
  269. }
  270. /*==================================================
  271. 函數功能:定時器T0的中斷服務函數
  272. ==================================================*/
  273. void Time0(void ) interrupt 1 //使用定時器T0中斷方式一,中斷地址為0013H
  274.          {
  275.      count++;  //每產生1次中斷,中斷累計次數加1
  276.                  if(count==20)  //如果中斷次數計滿20次
  277.                     {
  278.           count=0;  //中斷累計次數清0
  279.                       s++;      //秒加1                                 
  280.                          }
  281.                   if(s==60)   //如果計滿60秒
  282.                          {
  283.                           s=0;     //秒清0
  284.                           m++;     //分鐘加1
  285.                     }
  286.                   if(m==60)    //如果計滿60分
  287.                    {
  288.                            m=0;   //分鐘清0
  289.                            h++;    //小時加1
  290.                     }
  291.              if(h==24)  //如果計滿24小時
  292.                    {
  293.                            h=0;   //小時清0
  294.                    }
  295.           TH0=(65536-46083)/256;   //定時器T0高8位重新賦初值
  296.                 TL0=(65536-46083)%256;   //定時器T0低8位重新賦初值               
  297.   }
復制代碼

基于51單片機的可調數字時鐘.zip

91.83 KB, 下載次數: 54, 下載積分: 黑幣 -5

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

使用道具 舉報

來自 2#
ID:328014 發表于 2020-12-10 16:07 | 只看該作者
JOYG 發表于 2020-12-10 15:06
為啥在我這邊運行不出來



可能是你的Proteus版本不對,你看我用8.8版的 成功了
回復

使用道具 舉報

板凳
ID:775946 發表于 2020-10-14 19:27 | 只看該作者
厲害了,成功運行
回復

使用道具 舉報

地板
ID:569113 發表于 2020-10-14 19:31 | 只看該作者
顯示時間那里有個bug,時間到23:59的時候會卡住,希望樓主改進一下
回復

使用道具 舉報

5#
ID:790161 發表于 2020-12-8 14:24 | 只看該作者
DSFGSF 發表于 2020-10-14 19:31
顯示時間那里有個bug,時間到23:59的時候會卡住,希望樓主改進一下

我這里沒有這個情況
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 亚洲一区二区免费 | 国产精品久久久久久久三级 | 91亚洲精品久久久电影 | 日韩中文字幕在线播放 | 在线观看免费av网 | 97视频在线观看网站 | 天天曰天天干 | 国产精品欧美一区二区三区不卡 | 亚洲成人精品影院 | 日本精品视频 | 中文字幕一区二区三区四区五区 | 国产午夜影院 | av黄色免费在线观看 | 久久极品 | 国产伦精品一区二区三区精品视频 | 国产精品久久久久久久久久 | 成人高清视频在线观看 | 一级毛片免费看 | 亚洲一区二区三区久久久 | 成年人网站在线观看视频 | 最新国产精品精品视频 | 免费在线黄色av | 午夜精品久久久久久久星辰影院 | 日日爱夜夜操 | 国产色片| 亚洲成人精品一区 | 国产精品一区在线观看 | 国产精品乱码一区二区三区 | .国产精品成人自产拍在线观看6 | 精品免费视频 | 亚洲精品一区二区 | 99精品免费 | 亚洲精品国产精品国自产在线 | 一级片网站视频 | 亚洲精品一区二区在线 | 国产不卡视频 | 久久久免费 | 91九色在线观看 | 日韩欧美一区二区在线播放 | 日本不卡在线视频 | 久久精品中文 |