找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2705|回复: 2
收起左侧

基于LCD1602的万年历单片机源码 带闹钟

[复制链接]
ID:279910 发表于 2018-1-26 12:35 | 显示全部楼层 |阅读模式
基于LCD1602的万年历,带闹钟

单片机源程序如下:
  1.   #include <reg52.h>                         
  2. #define uint unsigned int          
  3. #define uchar unsigned char

  4. sbit lcd_rs=P2^6;        //rs为寄存器选择 高电平时选择数据寄存器,低电平选择指令寄存器
  5. sbit lcd_rw=P2^5;        //R/W 为读写信号线,高电平时进行读操作,低电平进行写操作
  6.                     //当 RS 和 R/W 共同为低电平时,可以写入指令或显示地址
  7. sbit lcd_en=P2^7; //液晶控制端
  8. sbit key_set=P1^4;//设置键
  9. sbit key_up=P1^5;        //加键同时也是闹钟能够停止按钮
  10. sbit key_down=P1^6; //  减键同时也是翻屏按钮
  11. sbit key_out=P1^7;  //键 盘控制端口
  12. uchar count;      //定时器计数变量
  13. uchar hour,min,sec,hour1,hour2,sec1,sec2,min1,min2;    //时间变量
  14. uchar  yue, ri,nian1, nian2, nian3, nian4, yue1, yue2, ri1, ri2;  //月日变量
  15. uint  nian; // 年变量
  16. uchar nao1=0, nao2=0, nao3=0, nao11, nao12, nao21, nao22;  //设置闹钟变量
  17. uchar count1;  // 星期计数变量
  18. uchar ww=0,qq=0,nao=1,flag;  //计数变量键盘设置端口,闹钟时间是否设置标志量,闹钟标志变量,设置键标志量
  19. uchar code table[]={
  20.    0x00,0x04,0x0E,0x0E,0x0E,0x0E,0x1F,0x1F,
  21.    0x04,0x08,0x00,0x1E,0x00,0x08,0x04,0x00
  22. };//设置闹钟图片

  23. void lcd_delay(uint m)          //延时函数 (字符型变量m定义)
  24. {
  25.                 while(m--);                                                                  //无限循环体
  26. }

  27. void read1602()                //忙检测 作用防止乱码
  28. {
  29.         uchar i;
  30.                 i=254;
  31.                 P0=0xff;  //
  32.                 lcd_rs=0; //读写命令
  33.                 lcd_rw=1; //读命令/数据
  34.                 lcd_en=1; //液晶模块执行命令
  35.                 while(i--);//若一段时间以后仍低,则认为是不忙
  36.                 lcd_en=0;
  37. }

  38. void write1602(uchar wdata,bit rw)//向LCD1602写数据(rw=1)或者命令(rw=0)
  39. {      
  40.         read1602();        //防止数据丢失
  41.                 lcd_rs=rw;                     
  42.                 P0=wdata;
  43.         lcd_rw=0;
  44.                 lcd_delay(1);           
  45.                 lcd_en=1;
  46.                 lcd_delay(1);
  47.                 lcd_en=0;
  48. }

  49. void lcd_init()           //LCD1602液晶的初始化
  50. {
  51.                
  52.                 lcd_delay(1500);
  53.                
  54.             write1602(0x38,0);         //置功能,8位数据,2行显示,5x7字符(指令6)
  55.        
  56.                 write1602(0x0c,0);         //只打开屏显 (指令4)
  57.        
  58.                 write1602(0x06,0);         //左到右显示,自加1  (指令3)
  59.        
  60.             write1602(0x01,0);         //清屏         (指令1)
  61.         
  62.                 write1602(0x80,0);           //(指令8)

  63. }

  64. void init()                                                //定时器初始化
  65. {
  66.         count=0;
  67.         hour=23; //小时初值
  68.         min=59;  //分钟初值
  69.         sec=50;  //秒初值                                                                                                                                                                          
  70.         nian=2018; //年初值
  71.         yue=01;  //月初值
  72.         ri=01;   //日初值
  73.         count1=1;//星期初值
  74.         TMOD=0x01; //中断T0工作方式,方式1,16位定时器
  75.         TH0=(65536-50000)/256;
  76.         TL0=(65536-50000)%256; //计数器初值,为50ms进入一次中断子程序
  77.         TR0=1; //允许T0计数
  78.         ET0=1; //定时器T0溢出中断允许
  79.         EA=1; //开中断
  80. }

  81. void lcd_printf(uchar *str)//显示字符串
  82. {   read1602();
  83.         while(*str!='\0')  
  84.         {
  85.                 write1602(*str,1);          //写入数据
  86.                 str++;
  87.                 lcd_delay(1);
  88.         }
  89. }

  90. void lcd_moveto(uchar x,uchar y)//指定显示的行列坐标
  91. {
  92.         if(x==0)
  93.                 write1602(0x80|y,0);   
  94.         if(x==1)
  95.                 write1602(0xc0|y,0);
  96. }

  97. void fengjie1(uchar a,uchar b, uchar c )//将时分秒两位数分解为两个数
  98. {
  99.             hour1=a/10;
  100.                         hour2=a%10;
  101.                         min1=b/10;
  102.                         min2=b%10;
  103.                         sec1=c/10;
  104.                         sec2=c%10;       
  105. }

  106. void fengjie2(uint a,uchar b, uchar c ) //将年月日分解为两个数
  107. {
  108.             nian4=a%10;
  109.             a=(a-nian4)/10;
  110.             nian3=a%10;
  111.             a=(a-nian3)/10;
  112.             nian2=a%10;
  113.             nian1=a/10;
  114.                         yue1=b/10;
  115.                         yue2=b%10;
  116.                         ri1=c/10;
  117.                         ri2=c%10;
  118. }
  119. void fengjie3(uchar a, uchar b )//将闹钟分解为两个数
  120. {
  121.             nao11=a/10;
  122.                         nao12=a%10;
  123.                         nao21=b/10;
  124.                         nao22=b%10;
  125. }
  126. void display1(uchar hour1,uchar hour2,uchar min1,uchar min2,uchar sec1,uchar sec2)         //显示时间程序
  127. {
  128.        
  129.     lcd_moveto(1,0); //定位在第二行第一列
  130.         write1602(hour1+48,1);                   //字符0-9对应十进制48-57
  131.         write1602(hour2+48,1);
  132.         lcd_printf(":");
  133.         write1602(min1+48,1);
  134.         write1602(min2+48,1);
  135.         lcd_printf(":");
  136.         write1602(sec1+48,1);
  137.         write1602(sec2+48,1);

  138. }

  139. void display2(uchar nian1,uchar nian2,uchar nian3,uchar nian4,uchar yue1,uchar yue2, uchar ri1, uchar ri2 )  //显示日期程序
  140. {
  141.     lcd_moveto(0,0); //定位在第一行第一列
  142.         write1602(nian1+48,1);
  143.         write1602(nian2+48,1);
  144.         write1602(nian3+48,1);
  145.         write1602(nian4+48,1);
  146.         lcd_printf("-");
  147.         write1602(yue1+48,1);
  148.         write1602(yue2+48,1);
  149.         lcd_printf("-");
  150.         write1602(ri1+48,1);
  151.         write1602(ri2+48,1);
  152. }

  153. void display3(uchar we)                 //星期送显示
  154. {
  155.         lcd_moveto(0,12);
  156.         switch(we)
  157.         {
  158.                 case 1: lcd_printf("M");
  159.                                 lcd_printf("0");
  160.                                  lcd_printf("N");
  161.                                  break;
  162.                 case 2: lcd_printf("T");
  163.                                 lcd_printf("U");
  164.                                  lcd_printf("E");
  165.                                  break;
  166.                 case 3: lcd_printf("W");
  167.                                 lcd_printf("E");
  168.                                  lcd_printf("D");
  169.                                  break;
  170.                 case 4: lcd_printf("T");
  171.                                 lcd_printf("H");
  172.                                  lcd_printf("U");
  173.                                  break;       
  174.                 case 5: lcd_printf("F");
  175.                                 lcd_printf("R");
  176.                                  lcd_printf("T");
  177.                                  break;
  178.                 case 6: lcd_printf("S");
  179.                                 lcd_printf("A");
  180.                                  lcd_printf("T");
  181.                                  break;
  182.                 case 7: lcd_printf("S");
  183.                                 lcd_printf("U");
  184.                                  lcd_printf("N");
  185.                                  break;                                                                                                                  
  186.         }       
  187. }

  188. void display4(uchar nao11,uchar nao12,uchar nao21, uchar nao22) //显示闹钟时刻
  189. {
  190.     lcd_moveto(1,6); //定位在第二行第6列
  191.     if(nao==1)        //打开闹钟
  192.         {write1602(nao11+48,1);//显示闹钟时间
  193.         write1602(nao12+48,1);
  194.         lcd_printf(":");
  195.         write1602(nao21+48,1);
  196.         write1602(nao22+48,1);
  197.         }
  198.         if(nao==0)         //关闭闹钟
  199.         {lcd_printf("N");
  200.         lcd_printf("O");
  201.     lcd_printf(":");
  202.     lcd_printf("N");
  203.         lcd_printf("O");
  204.         }
  205. }

  206. void display5()          //显示闹钟图片
  207. {
  208. lcd_moveto(1,13);
  209.         if(nao==1)//如果闹钟打开显示闹钟图片
  210.         {
  211.   write1602(0x00,1); //
  212.         write1602(0x01,1); //?
  213.         }
  214.         if(nao==0)
  215.         {
  216.          lcd_printf(" ");
  217.          lcd_printf(" ");
  218.         }
  219. }
  220. void zimo()         //字模显示
  221. {
  222.                 uint i;
  223.                 write1602(0x40,0); //写图片的指令
  224.                 for(i=0;i<16;i++)
  225.                 {
  226.                 write1602(table[i],1);                                                  
  227.                 }
  228. }
  229. void key()  //键盘程序
  230. {

  231.      if(key_set==0)
  232.      {
  233.          flag=1;
  234.      ww++;
  235.          if(ww==8)
  236.          ww=0;
  237.          while(!key_set);
  238.          }
  239.          switch(ww)
  240.         {
  241.         case 0:  //        清零
  242.                if(key_up==0)
  243.                {
  244.            while(!key_up);
  245.                     if(qq==1)
  246.                                          {
  247.                                                  qq=0;
  248.                                          }
  249.                                          else
  250.                                          {
  251.                    nao=!nao;   //开关闹钟的作用
  252.                    } }
  253.                break;
  254.         case 1:  //键盘调整年
  255.            lcd_delay(1000);
  256.                lcd_moveto(0,3);
  257.            lcd_printf("-");
  258.            lcd_delay(1000);
  259.                if(key_up==0)
  260.                    {
  261.            while(!key_up);        //按键是否抬起
  262.                    nian++;
  263.                    }
  264.                    if(key_down==0)
  265.                    {
  266.            while(!key_down);
  267.                    nian--;
  268.                    }
  269.                break;
  270.                           
  271.     case 2:  //键盘调整月
  272.                lcd_delay(1000);
  273.                lcd_moveto(0,6);
  274.            lcd_printf("-");
  275.            lcd_delay(1000);
  276.            if(key_up==0)
  277.                    {
  278.            while(!key_up);
  279.                    yue++;
  280.                    if(yue>12)
  281.                    yue=1;
  282.                    }
  283.                    if(key_down==0)
  284.                    {
  285.            while(!key_down);
  286.                    if(yue==1)
  287.                    yue=12;
  288.                    else
  289.                    yue--;
  290.                    }
  291.                break;

  292.     case 3: //键盘调节日期
  293.            lcd_delay(1000);
  294.                lcd_moveto(0,9);
  295.            lcd_printf("-");
  296.            lcd_delay(1000);
  297.                if(key_up==0)
  298.                    {
  299.            while(!key_up);
  300.                    ri++;
  301.                    if(ri>31)
  302.                    ri=1;
  303.                    }
  304.                    if(key_down==0)
  305.                    {
  306.            while(!key_down);
  307.                    if(ri==1)
  308.                    ri=31;
  309.                    else
  310.                    ri--;
  311.                    }
  312.                break;

  313.     case 4:  //键盘调整星期
  314.            lcd_delay(1000);
  315.                lcd_moveto(0,12);
  316.            lcd_printf("-");
  317.            lcd_printf("-");
  318.            lcd_printf("-");
  319.            lcd_delay(1000);

  320.                if(key_up==0)
  321.                    {
  322.            while(!key_up);
  323.                    count1++;
  324.                    if(count1>7)
  325.                    count1=1;
  326.                    }
  327.                    if(key_down==0)
  328.                    {
  329.            while(!key_down);
  330.                    if(count1==1)
  331.                    count1=7;
  332.                    else
  333.                    count1--;
  334.                    }
  335.                break;
  336.     case 5: //键盘调整时
  337.            lcd_delay(1000);
  338.                lcd_moveto(1,1);
  339.            lcd_printf("-");
  340.            lcd_delay(1000);
  341.            if(key_up==0)
  342.                    {
  343.            while(!key_up);
  344.                    hour++;
  345.                    if( hour>23)
  346.                     hour=0;
  347.                    }
  348.                    if(key_down==0)
  349.                    {
  350.            while(!key_down);
  351.                    if( hour==0)
  352.                     hour=23;
  353.                    else
  354.                     hour--;
  355.                    }
  356.                break;
  357.         case 6: //键盘调整分
  358.           lcd_delay(1000);
  359.                lcd_moveto(1,4);
  360.            lcd_printf("-");
  361.            lcd_delay(1000);
  362.            if(key_up==0)
  363.                    {
  364.            while(!key_up);
  365.                    min++;
  366.                    if( min>59)
  367.                     min=0;
  368.                    }
  369.                    if(key_down==0)
  370.                    {
  371.            while(!key_down);
  372.                    if( min==0)
  373.                     min=59;
  374.                    else
  375.                     min--;
  376.                    }
  377.                break;
  378.     case 7: //键盘调整秒

  379.            lcd_delay(1000);
  380.                lcd_moveto(1,7);
  381.            lcd_printf("-");
  382.            lcd_delay(1000);
  383.            if(key_up==0)
  384.                    {
  385.            while(!key_up);
  386.                    sec++;
  387.                    if( sec>59)
  388.                    sec=0;
  389.                    }
  390.                    if(key_down==0)
  391.                    {
  392.            while(!key_down);
  393.                    if(sec==0)
  394.                     sec=59;
  395.                    else
  396.                     sec--;
  397.                    }
  398.                break;
  399.                    }
  400.         if(key_out==0)
  401.         {
  402.      while(!key_out);
  403.                 flag=0;
  404.          ww=0;
  405.         }
  406. }
  407. void key1()  //        调整闹钟时间
  408. {
  409.      if(key_set==0)
  410.      {
  411.                          flag=1;
  412.      ww++;
  413.          if(ww==3)
  414.          ww=0;
  415.          while(!key_set);
  416.          }
  417.          switch(ww)
  418.         {
  419.                    case 0:  //退出设置
  420.                if(key_up==0)
  421.                {
  422.            while(!key_up);
  423.                    nao=!nao;   //如果闹钟开按下后则关,反之同理
  424.                    }
  425.                if(key_down==0)
  426.                {
  427.            while(!key_down);
  428.                qq=0; //
  429.                }
  430.                break;
  431.                 case 1: // 调试闹钟的时
  432.           lcd_delay(1000);                       
  433.                lcd_moveto(1,7);
  434.            lcd_printf("-");
  435.            lcd_delay(1000);
  436.          
  437.                if(nao==1)
  438.            {if(key_up==0)
  439.                    {
  440.            while(!key_up);
  441.                    nao1++;
  442.                    if( nao1>23)
  443.                     nao1=0;
  444.                    }
  445.                    if(key_down==0)
  446.                    {
  447.            while(!key_down);
  448.                    if( nao1==0)
  449.                     nao1=23;
  450.                    else
  451.                     nao1--;
  452.                    }
  453.                break;
  454.                    }
  455.                    else break;

  456.     case 2: // 调试闹钟的分
  457.          lcd_delay(1000);
  458.                lcd_moveto(1,10);
  459.            lcd_printf("-");
  460.            lcd_delay(1000);
  461.                if(nao==1)
  462.            {if(key_up==0)
  463.                    {
  464.            while(!key_up);
  465.                    nao2++;
  466.                    if( nao2>59)
  467.                     nao2=0;
  468.                    }
  469.                    if(key_down==0)
  470.                    {
  471.            while(!key_down);
  472.                    if( nao2==0)
  473.                     nao2=59;
  474.                    else
  475.                     nao2--;
  476.                    }
  477.                break;
  478.                    }
  479.                    else break;
  480.                   
  481.            default:break;
  482.         }
  483.         if(key_out==0)
  484.         {
  485.      while(!key_out);
  486.                 flag=0;
  487.          ww=0;
  488.         }
  489. }

  490. void count0(void) interrupt 1  //中断函数,进行时期的累加  12m晶振
  491. {
  492.         TH0=(65536-50000)/256;
  493.         TL0=(65536-50000)%256;
  494.         count++;
  495.         if(count==20) //计时到达一秒
  496.          {
  497.                  count=0;
  498.                  sec++;
  499.                   if(sec==60) //计时到达一分
  500.                   {
  501.                         sec=0;
  502.                         min++;
  503.                          if(min==60) //计时到达一小时
  504.                          {
  505.                                 min=0;
  506.                                 hour++;
  507.                                  if(hour==24) //计时到达一天
  508.                                         {
  509.                                                   hour=0;
  510.                                                 ri++;
  511.                                                 count1++;
  512.                                                 if(count1==8) //计时到达一周
  513.                                                 {
  514.                          count1=1;
  515.                                                 }
  516.                                                 if(yue==1|yue==3|yue==5|yue==7|yue==8|yue==10|yue==12)
  517.                                                 {
  518.                          if(ri>31) //计时到达一个月31天
  519.                                                  {
  520.                                                  ri=1;
  521.                                                  yue++;
  522.                                                  if(yue>12) //计时到达一年
  523.                                                  {
  524.                                                  yue=1;
  525.                                                  nian++;
  526.                                                  }
  527.                                                  }
  528.                                                 }
  529.                                                 if(yue==4|yue==6|yue==9|yue==11)
  530.                                                 {
  531.                                                 if(ri>30) //计时到达一个月30天
  532.                                                  {
  533.                                                  ri=1;
  534.                                                  yue++;
  535.                                                  if(yue>12) //计时到达一年
  536.                                                  {
  537.                                                  yue=1;
  538.                                                  nian++;
  539.                                                  }
  540.                                                  }
  541.                                                 }
  542.                                                 if(yue==2)
  543.                                                 {
  544.                                                 if(nian%4==0)
  545.                                                 {
  546.                                                 if(ri>29)//计时到达一个月29天
  547.                                                  {
  548.                                                  ri=1;
  549.                                                  yue++;
  550.                                                  if(yue>12)
  551.                                                  {
  552.                                                  yue=1;
  553.                                                  nian++;
  554.                                                  }
  555.                                                  }
  556.                                                 }
  557.                                                 else
  558.                                                 {
  559.                                                 if(ri>28) //计时到达一个月28天
  560.                                                  {
  561.                                                  ri=1;
  562.                                                  yue++;
  563.                                                  if(yue>12)
  564.                                                  {
  565.                                                  yue=1;
  566.                                                  nian++;
  567.                                                  }
  568.                                                  }
  569.                                                 }

  570.                                                 }
  571.                                         }
  572.                          }
  573.                   }

  574.          }
  575. }

  576. void linsheng()  //闹钟发生器
  577. {    if(nao==1)
  578.      {if(hour==nao1&min==nao2&sec==nao3)//满足时间?
  579.          qq=1;//是否设置闹钟时间
  580.          if(qq==1)
  581.          {
  582.       key_out=0;
  583.       lcd_delay(10000);
  584.           key_out=1;
  585.           lcd_delay(1000);
  586.          }
  587.          }
  588. }
  589. void main()
  590. ……………………

  591. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

所有资料51hei提供下载:
新建文件夹.rar (47.06 KB, 下载次数: 44)
回复

使用道具 举报

ID:684165 发表于 2020-1-11 16:33 | 显示全部楼层
这个闹钟订好时间后,好像不响啊!
回复

使用道具 举报

ID:684165 发表于 2020-1-11 16:34 | 显示全部楼层
闹钟定好时间后,好像不响啊! 难受&#128555;
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表