找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3342|回复: 3
打印 上一主题 下一主题
收起左侧

单片机可调电子钟proteus仿真

[复制链接]
跳转到指定楼层
楼主
电子钟仿真原理图



所有资料下载:
电子钟.rar (84.98 KB, 下载次数: 35)

单片机源码预览:
  1. #include<reg51.h>
  2. #define uchar unsigned char
  3. #define uint unsigned int
  4. sbit lcdrs=P2^0;  //定义1602液晶RS端
  5. sbit lcden=P2^1;//定义1602液晶LCDEN端
  6. sbit lcdrw=P2^4; //定义1602液晶RW端
  7. sbit s1=P3^0;   //定义按键--功能键
  8. sbit s2=P3^1;        //定义按键--增加键
  9. sbit s3=P3^2;        //定义按键--减小键
  10. sbit s4=P3^3;        //定义按键--闹钟键
  11. sbit beep=P2^2; //定义蜂鸣器端
  12. sbit led=P2^3;  //定义LED灯端
  13. uchar count,s1num,s4num;
  14. char year,month,day,week,miao,shi,fen,pshi;
  15. uchar code table[]=" 20  -  -   ";//定义初始上电时液晶默认显示状态
  16. void delay(uint z)  //延时函数
  17. {
  18.         uint x,y;
  19.         for(x=z;x>0;x--)
  20.                 for(y=110;y>0;y--);
  21. }
  22. void zhuanhuan()
  23. {
  24.         if(shi==0)
  25.             pshi=12;
  26.         if(shi<=12&&shi>=1)
  27.             pshi=shi;
  28.     if(shi>12)
  29.             pshi=shi-12;                                          
  30. }                                                                                     
  31. void di()//蜂鸣器发声函数
  32. {
  33.         beep=0;
  34.         delay(300);
  35.         beep=1;
  36.         delay(300);
  37. }
  38. void write_com(uchar com)//液晶写命令函数
  39. {
  40.         lcdrs=0;
  41.         lcdrw=0;
  42.         P0=com;
  43.         delay(5);
  44.         lcden=1;
  45.         delay(5);
  46.         lcden=0;       
  47. }
  48. void write_date(uchar date)//液晶写数据函数
  49. {
  50.         lcdrs=1;
  51.         lcdrw=0;
  52.         P0=date;
  53.         delay(5);
  54.         lcden=1;
  55.         delay(5);
  56.         lcden=0;       
  57. }
  58. void _shi()        //写"AM"、"PM"函数
  59. {
  60.    if(shi>=12)
  61.    {
  62.          write_com(0x80+0x40+1);//写出"PM"
  63.          write_date('P');
  64.          write_date('M');
  65.    }
  66.    else
  67.    {
  68.          write_com(0x80+0x40+1);//写出"AM"
  69.          write_date('A');
  70.          write_date('M');
  71.    }
  72. }
  73. void write_ymd(uchar add1,uchar date1)//写年月日函数
  74. {
  75.         uchar shi,ge;
  76.         shi=date1/10;//分解一个2位数的十位和个位
  77.         ge=date1%10;
  78.         write_com(0x80+add1);//设置显示位置
  79.         write_date(0x30+shi);//送去液晶显示十位
  80.         write_date(0x30+ge); //送去液晶显示个位
  81. }
  82. void write_sfm(uchar add,uchar date)//写时分秒函数
  83. {
  84.         uchar shi,ge;
  85.         shi=date/10;//分解一个2位数的十位和个位
  86.         ge=date%10;
  87.         write_com(0x80+0x40+add);//设置显示位置
  88.         write_date(0x30+shi);//送去液晶显示十位
  89.         write_date(0x30+ge); //送去液晶显示个位
  90. }
  91. void write_week(char week)           //写液晶星期显示函数
  92. {
  93.         write_com(0x80+12);
  94.         switch(week)
  95.         {
  96.                 case 1:        write_date('M');delay(5);
  97.                                 write_date('O');delay(5);
  98.                                 write_date('N');
  99.                                 break;
  100.                 case 2:        write_date('T');delay(5);
  101.                                 write_date('U');delay(5);
  102.                                 write_date('E');
  103.                                 break;
  104.                 case 3:        write_date('W');delay(5);
  105.                                 write_date('E');delay(5);
  106.                                 write_date('D');
  107.                                 break;
  108.                 case 4:        write_date('T');delay(5);
  109.                                 write_date('H');delay(5);
  110.                                 write_date('U');
  111.                                 break;
  112.                 case 5:        write_date('F');delay(5);
  113.                                 write_date('R');delay(5);
  114.                                 write_date('I');
  115.                                 break;
  116.                 case 6:        write_date('S');delay(5);
  117.                                 write_date('A');delay(5);
  118.                                 write_date('T');
  119.                                 break;
  120.                 case 7:        write_date('S');delay(5);
  121.                                 write_date('U');delay(5);
  122.                                 write_date('N');
  123.                                 break;
  124.         }
  125. }
  126. void writeym()
  127. {
  128.    day=1;
  129.    month++;
  130.    if(month==13)
  131.    {
  132.          month=1;
  133.          year++;
  134.          if(year==100)
  135.             year=0;
  136.          write_ymd(3,year);//年若变化则重新写入
  137.         }
  138.         write_ymd(6,month);//月若变化则重新写入
  139. }
  140. void init()//初始化函数
  141. {
  142.     uchar num;
  143.         lcden=0;
  144.         year=15;//初始化种变量值
  145.         month=6;
  146.         day=27;
  147.         week=6;
  148.         shi=13;
  149.         fen=59;
  150.         miao=58;
  151.         count=0;
  152.         s1num=0;
  153.         s4num=0;
  154.         write_com(0x38);//初始化1602液晶
  155.         write_com(0x0c);//设置开显示,不显示光标
  156.         write_com(0x06); //写一个字符后地址加1
  157.         write_com(0x01);   //显示清0,数据指针清0
  158.         write_com(0x80);//设置显示初始坐标
  159.         for(num=0;num<15;num++)//显示年月日星期
  160.         {
  161.                 write_date(table[num]);
  162.                 delay(5);
  163.         }
  164.                 delay(5);
  165.                 write_com(0x80+0x40+6);//写出时间显示部分的两个":"
  166.                 write_date(':');
  167.                 delay(5);
  168.                 write_com(0x80+0x40+9);
  169.                 write_date(':');
  170.                 delay(5);
  171.         write_week(week);
  172.         write_ymd(3,year);//分别送去液晶显示
  173.         write_ymd(6,month);
  174.         write_ymd(9,day);
  175.         write_sfm(10,miao);//分别送去液晶显示
  176.         write_sfm(7,fen);
  177.         write_sfm(4,shi);
  178.         TMOD=0x01;//设置定时器0工作模式1
  179.         TH0=(65536-50000)/256;//定时器装初值
  180.         TL0=(65536-50000)%256;
  181.         EA=1;        //开总中断
  182.         ET0=1;        //开定时器0中断
  183.         TR0=1;        //启动定时器0
  184. }
  185. void keyscan()//按键扫描函数
  186. {
  187.         if(s1==0)       
  188.         {
  189.                 delay(5);
  190.                 if(s1==0)//确认功能键被按下
  191.                 {       
  192.                     s1num++;//功能键按下次数记录
  193.                         while(!s1);//释放确认                       
  194.                         if(s1num==1)//第一次被按下时
  195.                         {
  196.                             TR0=0;  //关闭定时器
  197.                                 write_com(0x80+3);//光标定位到年位置
  198.                                 write_com(0x0f); //光标开始闪烁
  199.                         }
  200.                         if(s1num==2)//第二次按下光标闪烁定位到月位置
  201.                         {
  202.                                 write_com(0x80+6);
  203.                         }
  204.                         if(s1num==3)//第三次按下光标闪烁定位到日位置
  205.                         {
  206.                                 write_com(0x80+9);
  207.                         }
  208.                         if(s1num==4)//第四次按下光标闪烁定位到星期位置
  209.                         {
  210.                                 write_com(0x80+12);
  211.                         }
  212.                         if(s1num==7)//第七次被按下时光标定位到秒位置
  213.                         {
  214.                                 write_com(0x80+0x40+10);
  215.                         }
  216.                         if(s1num==6)//第六次按下光标闪烁定位到分位置
  217.                         {
  218.                                 write_com(0x80+0x40+7);
  219.                         }
  220.                         if(s1num==5)//第五次按下光标闪烁定位到时位置
  221.                         {
  222.                                 write_com(0x80+0x40+4);
  223.                         }
  224.                         if(s1num==8)//第七次按下
  225.                         {
  226.                                 s1num=0;//记录按键数清零
  227.                                 write_com(0x0c);//取消光标闪烁
  228.                                 TR0=1;        //启动定时器使时钟开始走
  229.                         }               
  230.                 }
  231.         }
  232.         if(s1num!=0)//只有功能键被按下后,增加和减小键才有效
  233.         {
  234.                 if(s2==0)
  235.                 {
  236.                         delay(5);
  237.                         if(s2==0)//增加键确认被按下
  238.                         {
  239.                                 while(!s2);//按键释放
  240.                                 if(s1num==1)//若功能键第一次按下
  241.                                 {
  242.                                         year++; //则调整年加1
  243.                                         if(year==100)//若满100后将清零
  244.                                                 year=0;
  245.                                         write_ymd(3,year);//每调节一次送液晶显示一下
  246.                                         write_com(0x80+3);//显示位置重新回到调节处
  247.                                 }
  248.                                 if(s1num==2)//若功能键第二次按下
  249.                                 {
  250.                                         month++;//则调整月加1
  251.                                         if(month==13)//若满12后将置一
  252.                                                 month=1;
  253.                                         write_ymd(6,month);//每调节一次送液晶显示一下
  254.                                         write_com(0x80+6);//显示位置重新回到调节处
  255.                                 }
  256.                                 if(s1num==3)//若功能键第三次按下
  257.                                 {
  258.                                         day++;//则调整日加1
  259.                                         if(year%4==0&&month==2)
  260.                                         {
  261.                                             if(day==30)//若满29后将置一
  262.                                                 day=1;
  263.                                          }
  264.                                          if(year%4!=0&&month==2)
  265.                                         {
  266.                                             if(day==29)//若满28后将置一
  267.                                                 day=1;
  268.                                          }
  269.                                          if(month!=2&&month!=4&&month!=6&&month!=9&&month!=11)
  270.                                          {
  271.                                             if(day==32)//若满31后将置一
  272.                                                 day=1;
  273.                                          }
  274.                                          if(month==4||month==6||month==9||month==11)
  275.                                          {         
  276.                                                 if(day==31)//若满30后将置一
  277.                                                 day=1;
  278.                                          }
  279.                                         write_ymd(9,day);;//每调节一次送液晶显示一下
  280.                                         write_com(0x80+9);//显示位置重新回到调节处
  281.                                 }
  282.                                 if(s1num==4)//若功能键第四次按下
  283.                                 {
  284.                                         week++;//则调整星期加1
  285.                                         if(week==8)//若满8后将置一
  286.                                                 week=1;
  287.                                         write_week(week);//每调节一次送液晶显示一下
  288.                                         write_com(0x80+12);//显示位置重新回到调节处
  289.                                 }
  290.                                 if(s1num==7)//若功能键第七次按下
  291.                                 {
  292.                                         miao++; //则调整秒加1
  293.                                         if(miao==60)//若满60后将清零
  294.                                                 miao=0;
  295.                                         write_sfm(10,miao);//每调节一次送液晶显示一下
  296.                                         write_com(0x80+0x40+10);//显示位置重新回到调节处
  297.                                 }
  298.                                 if(s1num==6)//若功能键第二次按下
  299.                                 {
  300.                                         fen++;//则调整分钟加1
  301.                                         if(fen==60)//若满60后将清零
  302.                                                 fen=0;
  303.                                         write_sfm(7,fen);//每调节一次送液晶显示一下
  304.                                         write_com(0x80+0x40+7);//显示位置重新回到调节处
  305.                                 }
  306.                                 if(s1num==5)//若功能键第五次按下
  307.                                 {                                       
  308.                                         shi++;
  309.                                         if(shi==24)//若满24后将清零
  310.                             {
  311.                                            shi=0;
  312.                                         }
  313.                                            if(s4num==0)
  314.                                            {                                                                                      
  315.                                               write_sfm(4,shi);;//每调节一次送液晶显示一下
  316.                                               write_com(0x80+0x40+4);//显示位置重新回到调节处
  317.                                            }                                          
  318.                                            if(s4num==1)
  319.                                            {
  320.                                                      zhuanhuan();
  321.                                               _shi();
  322.                                               write_sfm(4,pshi);;//每调节一次送液晶显示一下
  323.                                               write_com(0x80+0x40+4);//显示位置重新回到调节处
  324.                                        }                                       
  325.                               }
  326.                         }
  327.                 }
  328.         }
  329.                 if(s3==0)
  330.                 {
  331.                         delay(5);
  332.                         if(s3==0)//确认减小键被按下
  333.                         {
  334.                                 while(!s3);//按键释放
  335.                                 if(s1num==1)//若功能键第一次按下
  336.                                 {
  337.                                         year--;//则调整秒减1
  338.                                         if(year==-1)//若减到负数则将其重新设置为99
  339.                                                 year=99;
  340.                                         write_ymd(3,year);//每调节一次送液晶显示一下
  341.                                         write_com(0x80+3);//显示位置重新回到调节处
  342.                                 }
  343.                                 if(s1num==2)//若功能键第二次按下
  344.                                 {
  345.                                         month--;//则调整分钟减1
  346.                                         if(month==0)//若减到负数则将其重新设置为59
  347.                                                 month=12;
  348.                                         write_ymd(6,month);//每调节一次送液晶显示一下
  349.                                         write_com(0x80+6);//显示位置重新回到调节处
  350.                                 }
  351.                                 if(s1num==3)//若功能键第二次按下
  352.                                 {
  353.                                         day--;//则调整日加1
  354.                                         if(year%4==0&&month==2)
  355.                                         {
  356.                                             if(day==0)//若满29后将置一
  357.                                                 day=29;
  358.                                          }
  359.                                          if(year%4!=0&&month==2)
  360.                                         {
  361.                                             if(day==0)//若满28后将置一
  362.                                                 day=28;
  363.                                          }
  364.                                          if(month!=2&&month!=4&&month!=6&&month!=9&&month!=11)
  365.                                          {
  366.                                             if(day==0)//若满31后将置一
  367.                                                 day=31;
  368.                                          }
  369.                                          if(month==4||month==6||month==9||month==11)
  370.                                          {         
  371.                                                 if(day==0)//若满30后将置一
  372.                                                 day=30;
  373.                                          }
  374.                                         write_ymd(9,day);;//每调节一次送液晶显示一下
  375.                                         write_com(0x80+9);//显示位置重新回到调节处
  376.                                 }
  377.                                 if(s1num==4)//若功能键第二次按下
  378.                                 {
  379.                                         week--;//则调整小时减1
  380.                                         if(week==0)//若减到负数则将其重新设置为23
  381.                                                 week=7;
  382.                                         write_week(week);//每调节一次送液晶显示一下
  383.                                         write_com(0x80+12);//显示位置重新回到调节处
  384.                                 }
  385.                                 if(s1num==7)//若功能键第一次按下
  386.                                 {
  387.                                         miao--;//则调整秒减1
  388.                                         if(miao==-1)//若减到负数则将其重新设置为59
  389.                                                 miao=59;
  390.                                         write_sfm(10,miao);//每调节一次送液晶显示一下
  391.                                         write_com(0x80+0x40+10);//显示位置重新回到调节处
  392.                                 }
  393.                                 if(s1num==6)//若功能键第二次按下
  394.                                 {
  395.                                         fen--;//则调整分钟减1
  396.                                         if(fen==-1)//若减到负数则将其重新设置为59
  397.                                                 fen=59;
  398.                                         write_sfm(7,fen);//每调节一次送液晶显示一下
  399.                                         write_com(0x80+0x40+7);//显示位置重新回到调节处
  400.                                 }
  401.                                 if(s1num==5)//若功能键第二次按下
  402.                                 {
  403.                                         shi--;
  404.                                         if(shi==-1)//若满24后将清零
  405.                                            shi=23;
  406.                                            if(s4num==0)
  407.                                            {                                                                                   
  408.                                               write_sfm(4,shi);;//每调节一次送液晶显示一下
  409.                                               write_com(0x80+0x40+4);//显示位置重新回到调节处                                                    
  410.                                            }
  411.                                            if(s4num==1)
  412.                                            {                                          
  413.                               zhuanhuan();
  414.                                               _shi();
  415.                                               write_sfm(4,pshi);;//每调节一次送液晶显示一下
  416.                                               write_com(0x80+0x40+4);//显示位置重新回到调节处
  417.                                        }                                       
  418.                              }
  419.                 }
  420.         }
  421.         if(s1num==0)
  422.         {
  423.           if(s4==0)       
  424.           {
  425.                 delay(5);
  426.                 if(s4==0)//确认功能键被按下
  427.                 {       
  428.                     s4num++;//功能键按下次数记录
  429.                         while(!s4);//释放确认                       
  430.                         if(s4num==1)//第一次被按下时
  431.                         {
  432.                             zhuanhuan();
  433.                                 _shi();
  434.                                 write_sfm(4,pshi);
  435.                         }                       
  436.                         if(s4num==2)//第二次按下
  437.                         {
  438.                                 s4num=0;//记录按键数清零
  439.                                 write_com(0x80+0x40+1);
  440.                                 write_date(' ');
  441.                                 write_date(' ');
  442.                                 write_sfm(4,shi);
  443.                         }               
  444.                 }
  445.       }
  446.         }   
  447. }
  448. void main()//主函数
  449. {
  450.         init();//首先初始化各数据               
  451.         while(1)//进入主程序大循环
  452.         {
  453.                 keyscan();//不停的检测按键是否被按下
  454.                 if(s1num!=0)
  455.                    led=0;
  456.                 else           
  457.                    led=miao%2;       
  458.                 if((shi>7&&shi<23)&&(fen==0)&&(miao==0))
  459.                 {
  460.                  di();                 
  461.                  }                               
  462.         }
  463. }
  464. void timer0() interrupt 1//定时器0中断服务程序
  465. {
  466.         TH0=(65536-50000)/256;//再次装定时器初值
  467.         TL0=(65536-50000)%256;
  468.         count++;                //中断次数累加
  469.         if(count==20) //20次50毫秒为1秒
  470.         {
  471.                 count=0;
  472.                 miao++;
  473.                 if(miao==60)//秒加到60则进位分钟
  474.                 {
  475.                         miao=0;//同时秒数清零
  476.                         fen++;
  477.                         if(fen==60)//分钟加到60则进位小时
  478.                         {
  479.                                 fen=0;//同时分钟数清零
  480.                                 shi++;                               
  481.                                 if(shi==24)//小时加到24则小时清零
  482.                                 {
  483.                                         shi=0;
  484.                                         week++;
  485.                                            if(week==8)
  486.                                            {
  487.                                                week=1;
  488.                                            }
  489.                                            write_week(week);//星期若变化则重新写入
  490.                                         day++;
  491.                                            if(year%4==0&&month==2)//判断是否为闰年的2月
  492.                                            {
  493.                                               if(day==30)
  494.                                                   {
  495.                                                      writeym();                                                                                                                                                          
  496.                                                   }
  497.                                                   write_ymd(9,day);//日若变化则重新写入
  498.                                            }
  499.                                            if(year%4!=0&&month==2)//判断是否为平年的2月
  500.                                            {
  501.                                               if(day==29)
  502.                                                   {
  503.                                                      writeym();                                                                                                  
  504.                                                   }
  505.                                                   write_ymd(9,day);//日若变化则重新写入
  506.                                            }
  507.                                            if(month!=2&&month!=4&&month!=6&&month!=9&&month!=11)
  508.                                            {
  509.                                               if(day==32)
  510.                                                   {
  511.                                                      writeym();                                                                                                  
  512.                                                   }
  513.                                                   write_ymd(9,day);//日若变化则重新写入
  514.                                            }
  515.                                            if(month==4||month==6||month==9||month==11)
  516.                                            {
  517.                                               if(day==31)
  518.                                                   {
  519.                                                      writeym();                                                                                                  
  520.                                                   }
  521.                                                   write_ymd(9,day);//日若变化则重新写入
  522.                                            }
  523.                                 }
  524.                                 if(s4num==1)
  525.                                   {
  526.                                      zhuanhuan();
  527.                                          _shi();                                 
  528.                                      write_sfm(4,pshi);//12小时制小时若变化则重新写入
  529.                                   }
  530.                                 else write_sfm(4,shi);//24小时制小时若变化则重新写入                               
  531.                         }
  532.                         write_sfm(7,fen);//分钟若变化则重新写入
  533.                 }
  534.                 write_sfm(10,miao);//秒若变化则重新写入       
  535.         }       
  536. }
复制代码


评分

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

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏2 分享淘帖 顶1 踩
回复

使用道具 举报

沙发
ID:1 发表于 2017-1-3 22:13 | 只看该作者
51黑有你更精彩!!!
回复

使用道具 举报

板凳
ID:505337 发表于 2019-4-28 22:14 来自手机 | 只看该作者
谢谢楼主,已下
回复

使用道具 举报

地板
ID:505337 发表于 2019-5-5 08:07 来自手机 | 只看该作者
不能定时呀
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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