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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

以簡易數字鐘為例 演示LCD1602的綜合運用 附仿真與源碼

[復制鏈接]
跳轉到指定樓層
樓主
以簡易數字鐘為例 演示LCD1602的綜合運用 程序+仿真+詳細注釋

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


單片機源程序如下:
  1. #include<reg52.h>                 
  2. #define uchar  unsigned char
  3. #define uint  unsigned int
  4.   
  5. sbit RS=P3^5;         //寄存器選擇位,將RS位定義為P2.0引腳
  6. //sbit RW=P2^1;         //讀寫選擇位,將RW位定義為P2.1引腳
  7. sbit E=P3^4;          //使能信號位,將E位定義為P2.2引腳
  8. //sbit BF=P0^7;         //忙碌標志位,將BF位定義為P0.7引腳
  9.    
  10. uchar code table[]="2018-06-04 WEEK1";    //初始化液晶顯示 1602
  11. uchar code table1[]="TIME: 08:01:44";        
  12. uchar count,s1num;  
  13. char second,minute,hour,day,month,year,week;

  14. sbit s1=P2^3;         //功能鍵
  15. sbit s2=P2^4;         //加鍵
  16. sbit s3=P2^5;         //減鍵  
  17. sbit s4=P2^6;         //保存并退出   

  18. void delay(uchar i)   // 延時函數
  19. {
  20.   uchar j;
  21.   while(i--)
  22.   for(j=110;j>0;j--);
  23. }

  24. //uchar BusyTest(void)  // 查忙程序
  25. //{  
  26. //  bit result;  
  27. //  RS=0;               //RS為低電平,RW為高電平時,可以讀狀態
  28. //  RW=1;  
  29. //  E=1;                //高脈沖寫數據
  30. //  delay(4);           //延時,給硬件反應時間  
  31. //  result=BF;          //將忙碌標志電平賦給
  32. //  E=0;                //將E恢復低電平  
  33. //  return result;
  34. //}
  35. void WriteInstruction(uchar dictate)   //寫命令操作
  36. {  
  37. //  while(BusyTest()==1);   //如果忙就等待  查忙指令  
  38.   RS=0;                   //RS和R/W同時為低電平時,可以寫入指令
  39. //  RW=0;
  40.   E=0;                    //E置低電平(根據指令表,寫指令時,E為高脈沖,
  41.   delay(2);               //延時,給硬件反應時間
  42.   P0=dictate;             //將數據送入P0口,即寫入指令或地址
  43.   delay(4);               
  44.   E=1;                    //寫入脈沖
  45.   delay(4);            
  46.   E=0;                    
  47. }

  48. void WriteData(uchar y)          //寫數據操作
  49. {
  50. //  while(BusyTest()==1);
  51.   RS=1;                   //RS為高電平,RW為低電平時,可以寫入數據
  52. //  RW=0;
  53.   E=0;                    //E置低電平(根據指令表,寫指令時,E為高脈沖,
  54.   P0=y;                   //將數據送入P0口,即將數據寫入液晶模塊
  55.   delay(4);              
  56.   E=1;                  
  57.   delay(4);
  58.   E=0;
  59. }
  60. void LcdInitiate(void)          //設定初始液晶屏顯示數據
  61. {
  62.   uchar num;
  63.   second=44;
  64.   minute=1;
  65.   hour=8;                                  //設定顯示時間為08-01-44
  66.   week=1;
  67.   day=4;
  68.   month=6;
  69.   year=18;                                  //設定初始年月日
  70.   count=0;
  71.   s1num=0;
  72.   E=0;
  73.   delay(15);                   //延時15ms,首次寫指令時應給LCD一段較長的反應時間
  74.   WriteInstruction(0x38);      //16×2顯示,5×7點陣,8位數據接口  0011 1000
  75.   delay(5);                    
  76.   WriteInstruction(0x0c);      //顯示開,無光標,光標不閃爍         0000 1100
  77.   delay(5);
  78.   WriteInstruction(0x06);      //光標自動右移,字符不移         0000 0110
  79.   delay(5);
  80.   WriteInstruction(0x01);      //清屏幕指令,將以前的顯示內容清除
  81.   delay(5);
  82.   WriteInstruction(0x80);           //設置數據地址指針
  83.   for(num=0;num<16;num++)      //設置第一行的16個顯示位·
  84.   {
  85.    WriteData(table[num]);
  86.    delay(5);
  87.   }                                                                                                                 
  88.   WriteInstruction(0x80+0x40); //將液晶屏的數據指針移到第二行第一個字處
  89.   for(num=0;num<14;num++)      //設置第二行的14個顯示位
  90.   {
  91.    WriteData(table1[num]);
  92.    delay(5);
  93.   }
  94.   TMOD=0x01;                   //定時器中斷初始化 方式1
  95.   TH0=(65536-50000)/256;           //取模  /*方式1低位使用了八位
  96.   TL0=(65536-50000)%256;           //求余   故最大數值為2^8=256       
  97.   EA=1;                                                   //開總中斷
  98.   ET0=1;                                           //開內部定時器0中斷
  99.   TR0=1;                                           //啟動定時器
  100. }




  101. /*      時間日期計算與換算函數和寫入輸出函數                 */

  102. void write_nyr(uchar add,uchar date)
  103. {
  104.   uchar i,j;
  105.   i=date/10;
  106.   j=date%10;
  107.   WriteInstruction(0x80+add);
  108.   WriteData(0x30+i);
  109.   WriteData(0x30+j);
  110. }
  111. void write_sfm(uchar add,uchar date)
  112. {
  113.   uchar i,j;
  114.   i=date/10;
  115.   j=date%10;
  116.   WriteInstruction(0x80+0x40+add);
  117.   WriteData(0x30+i);
  118.   WriteData(0x30+j);
  119. }
  120. void write_week(uchar add,uchar date)
  121. {
  122.   WriteInstruction(0x80+add);
  123.   WriteData(0x30+date);
  124. }
  125. bit leap_year()
  126. {
  127.   int leap;
  128.   if((year%4==0&&year%100!=0)||year%400==0)
  129.   leap=1;//是閏年
  130.   else  
  131.   leap=0;//非閏年
  132.   return leap;
  133. }

  134. /*      功能鍵判別函數                 */

  135. void keyscan()
  136. {
  137.   if(s1==0) //第一個鍵是否按下
  138.   {
  139.    delay(5);
  140.    if(s1==0)
  141.    {
  142.         while(!s1);
  143.         s1num++;
  144.         if(s1num>7)
  145.         s1num=1;
  146.         if(s1num==1)//第一個鍵被按一次
  147.         {
  148.          TR0=0;
  149.          WriteInstruction(0x80+0x40+13);
  150.          WriteInstruction(0x0f);
  151.         }
  152.         if(s1num==2)
  153.         {
  154.          WriteInstruction(0x80+0x40+10);
  155.         }      
  156.         if(s1num==3)
  157.         {
  158.          WriteInstruction(0x80+0x40+7);
  159.         }
  160.         if(s1num==4)
  161.         {
  162.          WriteInstruction(0x80+9);
  163.         }
  164.         if(s1num==5)
  165.         {
  166.          WriteInstruction(0x80+6);
  167.         }
  168.         if(s1num==6)
  169.         {
  170.          WriteInstruction(0x80+3);
  171.         }
  172.         if(s1num==7)
  173.         {
  174.          WriteInstruction(0x80+15);
  175.         }
  176.    }
  177.   }
  178.   if(s1num!=0) //如果功能鍵被按下
  179.   {
  180.    if(s2==0) //第二個按下
  181.    {
  182.     delay(5);
  183.         if(s2==0)
  184.         {
  185.          while(!s2);
  186.          if(s1num==1) //第一個鍵被按一次,秒鐘加一
  187.          {
  188.           second++;
  189.           if(second==60)
  190.           second=0;
  191.           write_sfm(12,second);
  192.           WriteInstruction(0x80+0x40+13);
  193.          }
  194.          if(s1num==2) //第一個鍵被按二次,分鐘加一
  195.          {
  196.           minute++;
  197.           if(minute==60)
  198.           minute=0;
  199.           write_sfm(9,minute);
  200.           WriteInstruction(0x80+0x40+10);
  201.          }
  202.          if(s1num==3) //第一個鍵被按三次,時鐘加一
  203.          {
  204.           hour++;
  205.           if(hour==24)
  206.           hour=0;
  207.           write_sfm(6,hour);
  208.           WriteInstruction(0x80+0x40+7);
  209.          }
  210.          if(s1num==4) //第一個鍵被按四次,日期加一
  211.          {
  212.           day++;
  213.           if(day==32)
  214.           day=1;
  215.           write_nyr(8,day);
  216.           WriteInstruction(0x80+9);
  217.          }
  218.          if(s1num==5) //第一個鍵被按五次,月加一
  219.          {
  220.           month++;
  221.       if(month==13)
  222.           month=1;
  223.           write_nyr(5,month);
  224.           WriteInstruction(0x80+6);
  225.          }
  226.          if(s1num==6) //年加一
  227.          {
  228.           year++;
  229.           if(year==99)
  230.           year=0;
  231.           write_nyr(2,year);
  232.           WriteInstruction(0x80+3);
  233.          }
  234.          if(s1num==7) //星期加一
  235.          {
  236.           week++;
  237.           if(week==8)
  238.           week=1;
  239.           write_week(15,week);
  240.           WriteInstruction(0x80+15);
  241.          }
  242.         }
  243.    }
  244.   if(s3==0) //第三個鍵被按下
  245.   {
  246.    delay(5);
  247.    if(s3==0)
  248.    {
  249.     while(!s3);
  250.     if(s1num==1)//秒減一
  251.     {
  252.             second--;
  253.          if(second==-1)
  254.          second=59;
  255.          write_sfm(12,second);
  256.          WriteInstruction(0x80+0x40+13);
  257.         }
  258.         if(s1num==2) //分減一
  259.         {
  260.          minute--;
  261.          if(minute==-1)
  262.          minute=59;
  263.          write_sfm(9,minute);
  264.          WriteInstruction(0x80+0x40+10);
  265.     }
  266.         if(s1num==3) //時減一
  267.         {
  268.          hour--;
  269.          if(hour==-1)
  270.          hour=23;
  271.          write_sfm(6,hour);
  272.          WriteInstruction(0x80+0x40+7);
  273.         }
  274.         if(s1num==4) //日減一
  275.         {
  276.          day--;
  277.          if(day==0)
  278.          day=31;
  279.          write_nyr(8,day);
  280.          WriteInstruction(0x80+9);
  281.         }
  282.         if(s1num==5) //月減一
  283.         {
  284.          month--;
  285.          if(month==0)
  286.          month=12;
  287.          write_nyr(5,month);
  288.          WriteInstruction(0x80+6);
  289.         }
  290.         if(s1num==6) //年減一
  291.         {
  292.          year--;
  293.          if(year==-1)
  294.          year=99;
  295.          write_nyr(2,year);
  296.          WriteInstruction(0x80+3);
  297.         }
  298.         if(s1num==7) //日期減一
  299.         {
  300.          week--;
  301.          if(week==0)
  302.          week=7;
  303.          write_week(15,week);
  304.          WriteInstruction(0x80+15);
  305.         }
  306.    }
  307.   }
  308.   if(s4==0)  //保存并退出   
  309.    {
  310.     s1num=0;
  311.     WriteInstruction(0x0c);
  312.     TR0=1;
  313.    }
  314.   }
  315. }
  316. void main(void)
  317. {
  318.   uchar k=0;
  319.   LcdInitiate(); //調用LCD初始化函數
  320.   while(1)
  321.   {
  322.    keyscan();
  323.    k=1;
  324.   }
  325. }
  326. void timer0() interrupt 1
  327. {
  328.   count++;
  329.   if(count==13)
  330.   {
  331.    count=0;
  332.    second++;
  333.    if(second==60) //秒計滿60,秒歸0,分+1
  334.    {
  335.     second=0;
  336.         minute++;
  337.         if(minute==60) //分計滿60,分歸0,時+1
  338.         {
  339.          minute=0;
  340.          hour++;
  341.          if(hour==24) //時計滿24,時歸0,星期+1,日+1
  342.      {
  343.           hour=0;
  344.           week++;
  345.           day++;
  346.           if(week==8)
  347.           week=1; //星期計滿7,星期歸1
  348.           if(month==1||month==3||month==5||month==7||month==8||month==10||month==12)//大月三十一天
  349.           {
  350.            if(day==32) //大月天數計滿31,日歸1,月+1
  351.            {
  352.             day=1;
  353.                 month++;
  354.            }
  355.           }
  356.           if(month==4||month==6||month==9||month==11) //小月三十天
  357.           {
  358.            if(day==31) //小月天數計滿30,日歸1,月+1
  359.            {
  360. ……………………

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

所有資料51hei提供下載:
20161111144-李作鑫-LCD顯示器.rar (81.24 KB, 下載次數: 46)



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

使用道具 舉報

沙發
ID:339500 發表于 2018-8-1 15:57 | 只看該作者
研究看看你的數字時鐘,我的連LCD都弄不上去字
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 国产精品1区2区3区 一区中文字幕 | 亚洲欧美一区二区三区在线 | 九九久久在线看 | 夜夜爽99久久国产综合精品女不卡 | 亚洲精品第一 | 在线成人免费视频 | 午夜爽爽爽男女免费观看 | 视频三区 | 亚洲精品视频免费观看 | 成人免费在线观看 | 在线观看www视频 | 99精品久久 | 日韩国产精品一区二区三区 | 亚洲视频免费观看 | zzzwww在线看片免费 | 亚洲成人毛片 | 国产精品亚洲一区 | 欧美男人天堂 | 91视频观看 | 超碰成人免费 | 日日噜噜噜夜夜爽爽狠狠视频, | 日韩一级精品视频在线观看 | 国产成人综合亚洲欧美94在线 | 久久成人国产精品 | 国产伦精品一区二区三区精品视频 | 国产精品一二区 | 精品91av| 免费一区二区三区 | 国产一区免费 | 亚洲第一在线视频 | 午夜日韩精品 | 国产精品久久久久久久久久99 | 欧美视频成人 | 伊人手机在线视频 | 日韩有码一区 | 一区二区三区 在线 | 成人免费视频7777777 | 99久久精品国产一区二区三区 | 国产不卡一区 | 一区二区中文字幕 | 久免费视频|