找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2152|回复: 0
收起左侧

带开机画面与蜂鸣器的51单片机电子时钟(Proteus仿真电路源程序)1602显示

[复制链接]
ID:892621 发表于 2021-11-2 23:49 | 显示全部楼层 |阅读模式
功能有闹钟、温度显示、可修改时间、有高温报警和低温报警,是用1602显示,使用ds1302时钟芯片,使用18b20温度传感器
51hei.gif

单片机源程序如下:
  1. #include <reg52.h>
  2. #include <LCD1602.h>  //LCD1602头文件
  3. #include <ds1302.h>          //时钟芯片头文件
  4. #include <tem.h>          //温度18b20头文件
  5. #define u8 unsigned char  //重定义
  6. #define u16 unsigned int

  7. sbit KEY1=P3^0;         //定义界面功能按键、确定键
  8. sbit add=P3^1;         //定义加按键
  9. sbit sub=P3^2;         //定义减按键
  10. sbit KEY4=P3^3;  //定义改变功能键、返回键
  11. sbit beep=P1^5;         //蜂鸣器输出口

  12. int con=0,mon=0;
  13. bit bcon=0;
  14. char mm,ff,ss,ww;       //秒表的时分秒微秒;
  15. bit cool,teel;
  16. bit  miao=0,nao=0,wen=0;//nao为闹钟标志位,wen为温度标志位

  17. u16 win0,win1;//win0为行数win1为位置数
  18. u16 hin=0;
  19. char  t[][16]={"H33 L20 12/09/25",        //显示日期        放在随机存储器中
  20.                "21.3C 14:00:00 6"}; //显示时间、周  放在程序存储器

  21. char  c1[]="Clock 10:02:00  ";        //显示闹钟时间
  22. char code c2[]=" Good  Everyday ";        // Good Everyday
  23. char code c3[]=" Open OR Close  ";        //  Open OR Close  开启还是关闭
  24. char code c4[]="   miao-biao    ";
  25. char code c5[]="   00:00:00:0   ";                           
  26. char code M1[][16]={">     Time     <",">    Clock     <",
  27.                     ">  Tem_Aralm   <"};          //  时间调整,闹钟,温度上下限
  28. char K1[16]=" ";
  29. u8 code kai[]={"          The design by zhangkewei   welcome to ccdugt        "};
  30. uchar code SONG_TONE[]={212,212,190,212,159,169,212,212,190,212,142,159,
  31. 212,212,106,126,159,169,190,119,119,126,159,142,159,0};

  32. uchar code SONG_LONG[]={9,3,12,12,12,24,9,3,12,12,12,24,
  33. 9,3,12,12,12,12,12,9,3,12,12,12,24,0};
  34. //*********延时函数***********//
  35. void delay(u16 i)
  36. {
  37.   while(i--);
  38. }

  39. //*********开机画面*********//
  40. void open()
  41. {
  42.    int i=0,j;
  43.    while(kai[i]!='\0')
  44.     i++;
  45.         i--;
  46.    for(i;i!=0;i--)
  47.    {
  48.       K1[0]=kai[i];
  49.           LCD1602_WRITERCOM(0x80);
  50.       for(j=0;j<16;j++)
  51.       {
  52.          LCD1602_WRITERDAT(K1[j]);
  53.       }
  54.       LCD1602_WRITERCOM(0xC0);
  55.       for(j=0;j<16;j++)
  56.       {
  57.          LCD1602_WRITERDAT(K1[j]);
  58.       }
  59.           for(j=14;j>=0;j--)
  60.           {
  61.              K1[j+1]=K1[j];         
  62.           }
  63.           delay(10000);
  64.    }
  65. }

  66. //**********定时器0初始化函数*********//
  67. void TIME0_INIT()
  68. {
  69.    TMOD=0x01;
  70.    TH0=0x00;
  71.    TL0=0x00;
  72.    ET0=1;
  73.    EA=1;
  74.    TR0=0;
  75. }

  76. //**********定时器1初始化函数*********//
  77. void TIME1_INIT()
  78. {
  79.    TMOD=0x10;
  80.    TH1=0xFA;
  81.    TL1=0x15;
  82.    ET1=1;
  83.    EA=1;
  84.    TR1=0;
  85. }

  86. //*********显示函数************//
  87. void display(char *p,char *q)
  88. {
  89.    int i;
  90.    LCD1602_WRITERCOM(0x80);
  91.    for(i=0;i<16;i++)
  92.    {
  93.        LCD1602_WRITERDAT(*p++);
  94.    }
  95.    LCD1602_WRITERCOM(0xC0);
  96.    for(i=0;i<16;i++)
  97.    {
  98.        LCD1602_WRITERDAT(*q++);
  99.    }
  100. }

  101. //*********数据处理函数**********//
  102. void change()
  103. {
  104.    t[1][12]=time[0]/16+'0';           //秒
  105.    t[1][13]=time[0]%16+'0';
  106.    t[1][9]=time[1]/16+'0';           //分
  107.    t[1][10]=time[1]%16+'0';
  108.    t[1][6]=time[2]/16+'0';           //时
  109.    t[1][7]=time[2]%16+'0';
  110.    t[0][14]=time[3]/16+'0';           //日
  111.    t[0][15]=time[3]%16+'0';
  112.    t[0][11]=time[4]/16+'0';           //月
  113.    t[0][12]=time[4]%16+'0';
  114.    t[1][15]=time[5]%16+'0';           //周
  115.    t[0][8]=time[6]/16+'0';           //年
  116.    t[0][9]=time[6]%16+'0';
  117. }

  118. //*******字符移动动画函数********//
  119. void move1(char *m)
  120. {
  121.   int i,n;
  122.   char bin;
  123.   m=m+15;
  124.   bin=con?0xC0:0x80;
  125.   n=17;
  126.   while(n--)
  127.   {         
  128.          LCD1602_WRITERCOM(bin);
  129.       for(i=0;i<16;i++)
  130.       {
  131.          LCD1602_WRITERDAT(K1[i]);
  132.       }
  133.           for(i=14;i>=0;i--)
  134.           {
  135.              K1[i+1]=K1[i];         
  136.           }
  137.         K1[0]=*m--;
  138.         delay(1000);         
  139.    }
  140. }

  141. //**************时间修改函数****************//
  142. void TimeChange()
  143. {
  144.    int b=1;
  145.    int i;
  146.    u8 max,min;     //日历最大值与最小值
  147.    TIME0_INIT();  // 定时器0
  148.    DS1302_Writer(0x8e,0x00);
  149.    DS1302_Writer(0x80,time[0]|0x80);//暂停DS1302计时
  150.    delay(1000);
  151.    while(!KEY1);//判断按键是否松开
  152.    for(i=0;i<7;i++)
  153.    {
  154.       switch (i)
  155.           {
  156.             case 0 :
  157.                     win0=1; win1=12; max=0x59; min=0; break;  //秒位置
  158.                 case 1 :
  159.                     win0=1; win1=9; max=0x59; min=0; break;          //分位置
  160.                 case 2 :
  161.                     win0=1; win1=6; max=0x24; min=0; break;   //时位置
  162.                 case 3 :
  163.                     win0=0; win1=14; max=0x31; min=0x01; break;   //日位置
  164.                 case 4 :
  165.                     win0=0; win1=11; max=0x12; min=0x01; break;   //月位置
  166.                 case 5 :
  167.                     win0=1; win1=15; max=0x07; min=0x01; break;   //周位置
  168.                 case 6 :
  169.                     win0=0; win1=8; max=0x99; min=0x01; break;      //年位置
  170.                 default :
  171.                                                                                             break;
  172.           }
  173.      while(1)         
  174.      {
  175.          TR0=1;                  //开启定时器0
  176.        if(!add)                  //判断是否按下加按键
  177.            {
  178.              delay(1000);  //消抖,必须要有
  179.                   if(!add)
  180.                   {
  181.                 TR0=0;          //关闭定时器0
  182.                 time[i]++;
  183.                     if((time[i]&0x0f)>0x09)   //因为是BCD码
  184.                      time[i]=time[i]+6;
  185.                     while(!add);  //判断按键是否松开
  186.                   }
  187.            }         
  188.            if(!sub)                         //判断是否按下加按键
  189.            {
  190.              delay(1000);         //消抖,必须要有
  191.                   if(!sub)
  192.                   {
  193.                  TR0=0;                  //关闭定时器0
  194.                 if(time[i]==min) //判断是否减到最小值
  195.                      b--;
  196.                     time[i]--;
  197.                     if((time[i]&0x0f)>0x09)         //因为是BCD码
  198.                      time[i]=time[i]-6;
  199.                     while(!sub);
  200.                   }
  201.            }   
  202.            if(time[i]>max)
  203.             time[i]=min;           //不能超过最大值和最小值
  204.            if(!b)
  205.            {
  206.                  time[i]=max;
  207.                  b=1;
  208.            }
  209.            if(!KEY1)                 //判断是否按下确定键
  210.            {
  211.               delay(1000);        //消抖
  212.                   if(!KEY1)
  213.                   break;
  214.            }        
  215.     }
  216.         TR0=0;                   //
  217.         delay(1000);
  218.     while(!KEY1);     
  219.   }   
  220.    DS1302_STOP();        //DS1302获取改变后的值
  221.    change();
  222.    display(t[0],t[1]);
  223.   DS1302_INIT();
  224. //   while(KEY1);        //显示改变后的值,等待按键KEY1按下确认时间
  225. //   if(!KEY1)
  226. //   {
  227. //      delay(1000);
  228. //          if(!KEY1)
  229. //         

  230. //   }        
  231. //   TR0=0;
  232. //   while(!KEY1);//判断按键是否松开
  233. }





  234. //********闹钟设置函数*******//
  235. u16 ClockChange()
  236. {
  237.    u16 b=1;
  238.    display(c1,c2);
  239.    TIME0_INIT();   //定时器0初始化
  240.    delay(1000);
  241.    while(!KEY1);
  242.    win0=0;
  243.    win1=9;
  244.    hin=(c1[9]-'0')*10+(c1[10]-'0');          //分位置        
  245.    while(1)
  246.    {
  247.        TR0=1;         
  248.         if(!add)
  249.             {
  250.                delay(1000);
  251.                    if(!add)
  252.                    {
  253.                  TR0=0;
  254.                  hin++;
  255.                      while(!add);
  256.                }
  257.             }         
  258.             if(!sub)
  259.             {
  260.                delay(1000);
  261.                if(!sub)
  262.                    {                  
  263.                   TR0=0;
  264.                   if(hin==0)
  265.                        b--;
  266.                       hin--;
  267.                       while(!sub);
  268.                   }
  269.            }
  270.            if(!KEY1)
  271.            {
  272.               delay(1000);
  273.                   if(!KEY1)
  274.                   {
  275.                      break;
  276.                   }
  277.            }           
  278.            if(hin>59)
  279.             hin=0;           //不能超过最大值和最小值
  280.            if(!b)
  281.            {
  282.                  hin=59;
  283.                   b=1;
  284.            }        
  285.     }
  286.     while(!KEY1)
  287.     TR0=0;
  288.    c1[win1]=hin/10+'0';
  289.    c1[win1+1]=hin%10+'0';
  290.    win0=0;
  291.    win1=6;
  292.    hin=(c1[6]-'0')*10+(c1[7]-'0');
  293.    while(KEY1)
  294.    {
  295.       TR0=1;
  296.           win0=0;        //时位置
  297.           win1=6;
  298.       if(!add)
  299.           {
  300.             delay(1000);
  301.                 if(!add)
  302.                 {
  303.                TR0=0;
  304.                hin++;
  305.                    while(!add);
  306.                 }
  307.           }         
  308.           if(!sub)
  309.           {
  310.              delay(1000);
  311.                  if(!sub)
  312.                  {
  313.                 TR0=0;
  314.                 if(hin==0)
  315.                      b--;
  316.                     hin--;
  317.                     while(!sub);
  318.                 }
  319.           }           
  320.           if(hin>24)
  321.            hin=0;           //不能超过最大值和最小值
  322.           if(!b)
  323.           {
  324.                 hin=24;
  325.                 b=1;
  326.           }        
  327.    }
  328.    while(!KEY1)
  329.     TR0=0;
  330.    c1[win1]=hin/10+'0';
  331.    c1[win1+1]=hin%10+'0';
  332.    display(c1,c3);
  333.    while(1)
  334.    {
  335.      if(!KEY1)
  336.          {
  337.             delay(1000);
  338.                 if(!KEY1)
  339.                 {
  340.                   return 1;
  341.                 }
  342.          }
  343.          if(!KEY4)
  344.          {
  345.             delay(1000);
  346.                 if(!KEY4)
  347.                 {
  348.                   return 0;
  349.                 }
  350.          }
  351.    }
  352. }

  353. //*************温度读取函数*********//
  354. void Tem_display( int d )
  355. {     
  356.     if(d>9999) d=9999;  //温度显示在0~100度之间
  357.         if(d<0) d=0;
  358.         t[1][0] = d / 1000 + '0';
  359.         t[1][1] = d % 1000 / 100 + '0' ;
  360.         t[1][3] = d % 100 / 10 + '0';
  361. }

  362. //***********温度上下限设置函数***********//
  363. bit AralmChange()
  364. {
  365.    u16 b=1,i;
  366.    display(t[0],c2);
  367.    TIME0_INIT();
  368.    delay(1000);
  369.    while(!KEY1);
  370.    for(i=0;i<2;i++)
  371.    {
  372.       switch (i)
  373.          {
  374.                case (0) :
  375.                         win0=0;win1=1;hin=(t[win0][win1]-'0')*10+(t[win0][win1+1]-'0');break;        //最低温度位置
  376.                    case (1) :
  377.                         t[win0][win1]=hin/10+'0';t[win0][win1+1]=hin%10+'0';
  378.                                 win0=0;win1=5;hin=(t[win0][win1]-'0')*10+(t[win0][win1+1]-'0');break;        //最高温度位置
  379.          }   
  380.    while(1)
  381.    {
  382.           TR0=1;         
  383.       if(!add)
  384.           {
  385.             delay(1000);
  386.                 if(!add)
  387.                 {
  388.                TR0=0;
  389.                hin++;
  390.                    while(!add);
  391.                 }
  392.           }         
  393.           if(!sub)
  394.           {
  395.              delay(1000);
  396.                  if(!sub)
  397.                  {
  398.                 TR0=0;
  399.                 if(hin==0)
  400.                      b--;
  401.                     hin--;
  402.                     while(!sub);
  403.                  }
  404.           }
  405.           if(!KEY1)
  406.           {
  407.              delay(1000);
  408.                  if(!KEY1)
  409.                  {
  410.                    TR0=0;
  411.                    break;
  412.                  }
  413.           }           
  414.           if(hin>99)
  415.            hin=0;           //不能超过最大值和最小值
  416.           if(!b)
  417.           {
  418.                 hin=99;
  419.                 b=1;
  420.           }        
  421.     }
  422.         while(!KEY1);
  423.   }
  424.    t[win0][win1]=hin/10+'0';
  425.    t[win0][win1+1]=hin%10+'0';   
  426.    display(t[0],c3);
  427.    while(1)
  428.    {
  429.      if(!KEY1)
  430.          {
  431.             delay(1000);
  432.                 if(!KEY1)
  433.                 {
  434.                   return 1;
  435.                 }
  436.          }
  437.          if(!KEY4)
  438.          {
  439.             delay(1000);
  440.                 if(!KEY4)
  441.                 {
  442.                   return 0;
  443.                 }
  444.          }
  445.    }
  446. }


  447. //*************按键处理函数**************//
  448. int button()
  449. {
  450.    if(!KEY1)
  451.    {
  452.       delay(100);
  453.           if(!KEY1)
  454.           {
  455.              switch (mon)//mon,为菜单标志位
  456.                  {
  457.                     case 0:TimeChange(); break;
  458.                         case 1:cool=ClockChange();break;                        
  459.                         case 2:teel=AralmChange();break;

  460.                  }
  461.           }
  462.          while(!KEY1);
  463.    }
  464.    if(!add)
  465.    {
  466.       delay(1000);
  467.           if(!add)
  468.           {
  469.         if(mon==0)
  470.             {
  471.               mon=3;
  472.                   con=1;
  473.             }
  474.                  mon=mon-1;
  475.                  con=con-1;
  476.                if(mon==1)
  477.                    {
  478.                      con=1;
  479.                          display(M1[1],M1[0]);
  480.                    }
  481.            }
  482.           while(!add); //判断按键是否松开
  483.         }
  484.    if(!sub)
  485.    {
  486.       delay(1000);
  487.           if(!sub)
  488.           {
  489.         if(mon==3)
  490.             {
  491.               mon=-1;
  492.                   con=0;
  493.             }
  494.              mon=mon+1;
  495.              con=con+1;
  496.              if(mon==2)
  497.              {
  498.                         
  499.                     con=1;
  500.                         display(M1[1],M1[2]);
  501.                  }
  502.            }
  503.           while(!sub);
  504.         }
  505.    if(!KEY4)
  506.    {
  507.       delay(100);
  508.           if(!KEY4)
  509.           {
  510.              while(!KEY4);
  511.              return 0;
  512.           }
  513.    }   
  514.    return 1;
  515. }
  516. //**************音乐播放函数**************//
  517. void PlayMusic(u8 flag)//音乐函数
  518. {
  519.         if(flag==1)
  520.         {
  521.         uint i=0,j,k;
  522.         for(i=0;i<13;i++)
  523.         { //播放各个音符,SONG_LONG 为拍子长度
  524.                         for(j=0;j<SONG_LONG[i]*20;j++)
  525.                 {
  526.                         beep=~beep;
  527.                 //SONG_TONE 延时表决定了每个音符的频率
  528.                         for(k=0;k<SONG_TONE[i]/3;k++);
  529.                 }
  530.         }
  531.         flag=0;
  532.         }        
  533.    
  534. }


  535. //**************判断是否有报警**************//
  536. void nao_baojing()
  537. {
  538.    int i;
  539.    
  540.       for(i=6;i<11;i++)
  541.           {
  542.             if(c1[i]!=t[1][i])//对闹钟是否相同进行比较
  543.                   break;
  544.           }
  545.           if(i==11)//如果比较到最后一位都一样时
  546.                 nao=1;//闹钟响
  547.           else
  548.            nao=0;//闹钟不响
  549.    
  550.    
  551. }
  552. void wen_baojing()
  553. {
  554. ……………………

  555. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
7d7681425c5f23ade87d61084f6404c1.png
所有资料51hei附件下载:
LCD1602显示.zip (200.04 KB, 下载次数: 53)

评分

参与人数 1黑币 +40 收起 理由
admin + 40 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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