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

QQ登錄

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

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

51單片機(jī)lcd簡(jiǎn)易鬧鐘程序,可設(shè)定實(shí)時(shí)時(shí)間和鬧鐘時(shí)間

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)


單片機(jī)源程序如下:
  1. #include<reg52.h>    //包含單片機(jī)寄存器的頭文件
  2. #include<intrins.h>  //包含_nop_()函數(shù)定義的頭文件

  3. #define uchar  unsigned char
  4. #define uint  unsigned int

  5. sbit RS=P2^0;   //寄存器選擇位,將RS位定義為P2.0引腳
  6. sbit RW=P2^1;   //讀寫(xiě)選擇位,將RW位定義為P2.1引腳
  7. sbit E=P2^2;    //使能信號(hào)位,將E位定義為P2.2引腳
  8. sbit BF=P0^7;   //忙碌標(biāo)志位,將BF位定義為P0.7引腳

  9. sbit k1=P3^2;   //功能鍵
  10. sbit k2=P3^4;   //加鍵
  11. sbit k3=P3^5;   //減鍵
  12. sbit k4=P3^7;   //保存并退出、開(kāi)啟或關(guān)閉鬧鐘
  13. sbit buzz=P1^0;   //蜂鳴器

  14. uchar code table[] =  "    19-59-55 0N ";      //初始化液晶顯示
  15. uchar code table1[] = "    19-59-50    ";

  16. uchar count,k1num;
  17. char sec = 50,min = 59,hour = 19;//時(shí)鐘秒、分、時(shí)
  18. char s = 55,m = 59,h = 19;       //鬧秒、分、時(shí)
  19. char alarm_flag = 0;             //鬧鐘開(kāi)啟關(guān)閉標(biāo)志位 0開(kāi)啟;1關(guān)閉
  20. char num = 0;                    //用于蜂鳴器報(bào)警時(shí)間計(jì)數(shù)


  21. /****延時(shí)若干毫秒****/
  22. void delay(uchar n)
  23. {
  24.         uchar i,a,b;
  25.         for(i=0;i<n;i++)
  26.             for(b=199;b>0;b--)
  27.                 for(a=1;a>0;a--);
  28. }

  29. /***********************************************
  30. 函數(shù)功能:判斷液晶模塊的忙碌狀態(tài)
  31. 返回值:result。result=1,忙碌;result=0,不忙
  32. ************************************************/
  33. uchar BusyTest(void)
  34. {
  35.         bit result;
  36.         RS=0;  //根據(jù)規(guī)定,RS為低電平,RW為高電平時(shí),可以讀狀態(tài)
  37.         RW=1;
  38.         E=1;   //E=1,才允許讀寫(xiě)
  39.         _nop_();   //空操作
  40.         _nop_();
  41.         _nop_();
  42.         _nop_();   //空操作四個(gè)機(jī)器周期,給硬件反應(yīng)時(shí)間
  43.         result=BF; //將忙碌標(biāo)志電平賦給result
  44.         E=0;   //將E恢復(fù)低電平
  45.         return result;
  46. }

  47. /********************************************
  48. 函數(shù)功能:寫(xiě)指令
  49. 入口參數(shù):dictate
  50. *********************************************/
  51. void Write_add(uchar dictate)
  52. {
  53.         while(BusyTest()==1);   //如果忙就等待
  54.         RS=0;  //根據(jù)規(guī)定,RS和R/W同時(shí)為低電平時(shí),可以寫(xiě)入指令
  55.         RW=0;
  56.         E=0;    //E置低電平(根據(jù)表8-6,寫(xiě)指令時(shí),E為高脈沖,
  57.                     //就是讓E從0到1發(fā)生正跳變,所以應(yīng)先置"0"
  58.         _nop_();
  59. _nop_();    //空操作兩個(gè)機(jī)器周期,給硬件反應(yīng)時(shí)間
  60.         P0=dictate;   //將數(shù)據(jù)送入P0口,即寫(xiě)入指令或地址
  61.         _nop_();
  62.         _nop_();
  63.         _nop_();
  64.         _nop_();   //空操作四個(gè)機(jī)器周期,給硬件反應(yīng)時(shí)間
  65.         E=1;     //E置高電平
  66.         _nop_();
  67.         _nop_();
  68.         _nop_();
  69.         _nop_();   //空操作四個(gè)機(jī)器周期,給硬件反應(yīng)時(shí)間
  70.         E=0;     //當(dāng)E由高電平跳變成低電平時(shí),液晶模塊開(kāi)始執(zhí)行命令
  71. }

  72. /*********************************************
  73. 函數(shù)功能:寫(xiě)數(shù)據(jù)
  74. 入口參數(shù):y(為字符常量)
  75. **********************************************/
  76. void Write_data(uchar y)
  77. {
  78.         while(BusyTest()==1);
  79.         RS=1;   //RS為高電平,RW為低電平時(shí),可以寫(xiě)入數(shù)據(jù)
  80.         RW=0;
  81.         E=0;   //E置低電平(根據(jù)表8-6,寫(xiě)指令時(shí),E為高脈沖,
  82.                //就是讓E從0到1發(fā)生正跳變,所以應(yīng)先置"0"
  83.         P0=y;  //將數(shù)據(jù)送入P0口,即將數(shù)據(jù)寫(xiě)入液晶模塊
  84.         _nop_();
  85.         _nop_();
  86.         _nop_();
  87.         _nop_();   //空操作四個(gè)機(jī)器周期,給硬件反應(yīng)時(shí)間
  88.         E=1;     //E置高電平
  89.         _nop_();
  90.         _nop_();
  91.         _nop_();
  92.         _nop_();   //空操作四個(gè)機(jī)器周期,給硬件反應(yīng)時(shí)間
  93.         E=0;     //當(dāng)E由高電平跳變成低電平時(shí),液晶模塊開(kāi)始執(zhí)行命令
  94. }

  95. /******************************************
  96. 函數(shù)功能:對(duì)LCD的顯示模式進(jìn)行初始化設(shè)置
  97. *******************************************/
  98. void LcdInitiate(void)
  99. {
  100.         uchar num;
  101.         
  102.         count=0;
  103.         k1num=0;

  104.         E=0;
  105.         delay(15);  //延時(shí)15ms,首次寫(xiě)指令時(shí)應(yīng)給LCD一段較長(zhǎng)的反應(yīng)時(shí)間
  106.         Write_add(0x38);  //顯示模式設(shè)置:16×2顯示,
  107.                                                          //5×7點(diǎn)陣,8位數(shù)據(jù)接口
  108.         delay(5);  //延時(shí)5ms?,給硬件一點(diǎn)反應(yīng)時(shí)間
  109.         Write_add(0x38);
  110.         delay(5);
  111.         Write_add(0x38);  //連續(xù)三次,確保初始化成功
  112.         delay(5);
  113.         Write_add(0x0c);  //顯示模式設(shè)置:顯示開(kāi),無(wú)光標(biāo),
  114.                                                          //光標(biāo)不閃爍
  115.         delay(5);
  116.         Write_add(0x06);  //顯示模式設(shè)置:光標(biāo)右移,字符不移
  117.         delay(5);
  118.         Write_add(0x01);  //清屏幕指令,將以前的顯示內(nèi)容清除
  119.         delay(5);

  120.         Write_add(0x80);
  121.         for(num=0;num<16;num++)  //讓液晶顯示日期
  122.         {
  123.                 Write_data(table[num]);
  124.                 delay(5);
  125.         }
  126.         Write_add(0x80+0x40);
  127.         for(num=0;num<14;num++)  //讓液晶顯示時(shí)間
  128.         {
  129.                 Write_data(table1[num]);
  130.                 delay(5);
  131.         }

  132.         TMOD=0x01;    //定時(shí)器中斷初始化
  133.         TH0=(65536-50000)/256;
  134.         TL0=(65536-50000)%256;
  135.         EA=1;
  136.         ET0=1;
  137.         TR0=1;
  138. }

  139. /**********寫(xiě)實(shí)時(shí)時(shí)分秒************/
  140. void write_sfm(uchar add,uchar date)
  141. {
  142.         uchar i,j;
  143.         i=date/10;
  144.         j=date%10;
  145.         Write_add(0x80+0x40+add);
  146.         Write_data(0x30+i);
  147.         Write_data(0x30+j);
  148. }

  149. /**********寫(xiě)鬧鐘時(shí)分秒************/
  150. void write_alarm(uchar add,uchar date)
  151. {
  152.         uchar i,j;
  153.         i=date/10;
  154.         j=date%10;
  155.         Write_add(0x80+add);
  156.         Write_data(0x30+i);
  157.         Write_data(0x30+j);
  158. }
  159. /**********寫(xiě)ON字符串************/
  160. void write_ON()
  161. {
  162.         char i;
  163.         char p[3] = "0N ";
  164.                
  165.         for(i=0;i<3;i++)
  166.         {
  167.                 Write_add(0x80+(13+i));
  168.                 Write_data(p[i]);
  169.         }
  170. }
  171. /**********寫(xiě)OFF字符串************/
  172. void write_OFF()
  173. {
  174.         char i;
  175.         char p[3] = "0FF";
  176.                
  177.         for(i=0;i<3;i++)
  178.         {
  179.                 Write_add(0x80+(13+i));
  180.                 Write_data(p[i]);
  181.         }
  182. }

  183. //鍵盤掃描
  184. void keyscan()
  185. {
  186.         if(k1==0)   //第一個(gè)鍵是否按下
  187.         {
  188.                 delay(5);
  189.                 if(k1==0)
  190.                 {
  191.                         while(!k1); //松手檢測(cè)
  192.                         k1num++;
  193.                         if(k1num>6)
  194.                                 k1num=1;
  195.                         if(k1num==1)   //k1按下 光標(biāo)跳轉(zhuǎn)
  196.                         {
  197.                                 TR0=0;//在調(diào)整界面停止計(jì)時(shí)
  198.                                 Write_add(0x80+0x40+11); //設(shè)置光標(biāo)位置
  199.                                 Write_add(0x0f);
  200.                         }
  201.                         if(k1num==2)
  202.                         {
  203.                                 Write_add(0x80+0x40+8);
  204.                         }
  205.                         if(k1num==3)
  206.                         {
  207.                                 Write_add(0x80+0x40+5);
  208.                         }
  209.                         if(k1num==4)
  210.                         {
  211.                                 Write_add(0x80+11);
  212.                         }
  213.                         if(k1num==5)
  214.                         {
  215.                                 Write_add(0x80+8);
  216.                         }
  217.                         if(k1num==6)
  218.                         {
  219.                                 Write_add(0x80+5);
  220.                         }
  221.                 }
  222.         }
  223.         if(k1num!=0)   //如果功能鍵被按下后
  224.         {
  225.                 if(k2==0)  //k2按下
  226.                 {
  227.                         delay(5);
  228.                         if(k2==0)
  229.                         {
  230.                                 while(!k2);  //松手檢測(cè)
  231.                                 if(k1num==1)   //k1鍵被按一次,時(shí)鐘 秒加一
  232.                                 {
  233.                                         sec++;
  234.                                         if(sec==60)
  235.                                                 sec=0;
  236.                                         write_sfm(10,sec);
  237.                                         Write_add(0x80+0x40+11);
  238.                                 }
  239.                                 if(k1num==2)   //k1鍵被按二次,時(shí)鐘 分加一
  240.                                 {
  241.                                         min++;
  242.                                         if(min==60)
  243.                                                 min=0;
  244.                                         write_sfm(7,min);
  245.                                         Write_add(0x80+0x40+8);
  246.                                 }
  247.                                 if(k1num==3)   //k1鍵被按三次,時(shí)鐘 時(shí)加一
  248.                                 {
  249.                                         hour++;
  250.                                         if(hour==24)
  251.                                                 hour=0;
  252.                                         write_sfm(4,hour);
  253.                                         Write_add(0x80+0x40+5);
  254.                                 }
  255.                                 if(k1num==4)   //k1鍵被按四次,鬧鐘 秒加一
  256.                                 {
  257.                                         s++;
  258.                                         if(s==60)
  259.                                                 s=0;
  260.                                         write_alarm(10,s);
  261.                                         Write_add(0x80+11);
  262.                                 }
  263.                                 if(k1num==5)   //k1鍵被按五次,鬧鐘 分加一
  264.                                 {
  265.                                         m++;
  266.                                         if(m==60)
  267.                                                 m=0;
  268.                                         write_alarm(7,m);
  269.                                         Write_add(0x80+8);
  270.                                 }
  271.                                 if(k1num==6)   //k1鍵被按六次,鬧鐘 時(shí)加一
  272.                                 {
  273.                                         h++;
  274.                                         if(h==24)
  275.                                                 h=0;
  276.                                         write_alarm(4,h);
  277.                                         Write_add(0x80+5);
  278.                                 }
  279.                         }
  280.                 }
  281.                 if(k3==0)    //k3鍵被按下
  282.                 {
  283.                         delay(5);
  284.                         if(k3==0)
  285.                         {
  286.                                 while(!k3);
  287.                                 if(k1num==1)    //時(shí)鐘 秒減一
  288.                                 {
  289.                                         sec--;
  290.                                         if(sec<=-1)
  291.                                                 sec=59;
  292.                                         write_sfm(10,sec);
  293.                                         Write_add(0x80+0x40+11);
  294.                                 }
  295.                                 if(k1num==2)   //時(shí)鐘 分減一
  296.                                 {
  297.                                         min--;
  298.                                         if(min<=-1)
  299.                                                 min=59;
  300.                                         write_sfm(7,min);
  301.                                         Write_add(0x80+0x40+8);
  302.                                 }
  303.                                 if(k1num==3)   //時(shí)鐘 時(shí)減一
  304.                                 {
  305.                                         hour--;
  306.                                         if(hour<=-1)
  307.                                                 hour=23;
  308.                                         write_sfm(4,hour);
  309.                                         Write_add(0x80+0x40+5);
  310.                                 }
  311.                                 if(k1num==4)    //鬧鐘 秒減一
  312.                                 {
  313.                                         s--;
  314.                                         if(s<=-1)
  315.                                                 s=59;
  316.                                         write_alarm(10,s);
  317.                                         Write_add(0x80+11);
  318.                                 }
  319.                                 if(k1num==5)   //鬧鐘 分減一
  320.                                 {
  321.                                         m--;
  322.                                         if(m<=-1)
  323.                                                 m=59;
  324.                                         write_alarm(7,m);
  325.                                         Write_add(0x80+8);
  326.                                 }
  327.                                 if(k1num==6)   //鬧鐘 時(shí)減一
  328.                                 {
  329.                                         h--;
  330.                                         if(h<=-1)
  331.                                                 h=23;
  332.                                         write_alarm(4,h);
  333.                                         Write_add(0x80+5);
  334.                                 }
  335.                         }
  336.                 }
  337.         }
  338.         if(k4==0)   //k4按鍵按下
  339.         {
  340.                 delay(5);
  341.                 if(k4==0)
  342.                 {
  343.                         while(!k4);
  344.                         if(buzz == 1)
  345.                         {
  346.                                 if(k1num!=0)//保存并退出
  347.                                 {
  348.                                         k1num=0;
  349.                                         Write_add(0x0c); //關(guān)閉光標(biāo)
  350.                                         TR0=1;    //開(kāi)始計(jì)時(shí)
  351.                                 }
  352.                                 else  //開(kāi)啟或關(guān)閉鬧鐘
  353.                                 {
  354.                                         if(alarm_flag == 0)
  355.                                         {
  356.                                                 alarm_flag = 1;
  357.                                                 write_OFF();
  358.                                         }
  359.                                         else
  360.                                         {
  361.                                                 alarm_flag = 0;
  362.                                                 write_ON();
  363.                                         }
  364.                                 }
  365.                         }
  366.                         else
  367.                         {
  368.                                 buzz = 1;//關(guān)閉蜂鳴器
  369.                                 num = 0;//清空計(jì)數(shù),方便下一次計(jì)數(shù)
  370.                         }
  371.                         
  372.                 }
  373.         }
  374. }

  375. /******************************************
  376. 主函數(shù)
  377. *******************************************/
  378. void main(void)
  379. {
  380.         LcdInitiate();   //調(diào)用LCD初始化函數(shù)
  381.         while(1)
  382. ……………………

  383. …………限于本文篇幅 余下代碼請(qǐng)從51黑下載附件…………
復(fù)制代碼


lcd1602簡(jiǎn)易鬧鐘.zip

100.45 KB, 下載次數(shù): 51, 下載積分: 黑幣 -5

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

使用道具 舉報(bào)

沙發(fā)
ID:923669 發(fā)表于 2021-6-19 22:07 | 只看該作者
有仿真嗎
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

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

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

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