找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 6802|回复: 6
收起左侧

2051单片机4位数码管可以显示 时分,月日,年份;万年历,整点报时

[复制链接]
ID:76190 发表于 2015-4-5 18:18 | 显示全部楼层 |阅读模式
  1. //功能:4位数码管可以显示 时分,月日,年份;万年历,整点报时,定时自动(或手动)关闭显示器,空闲模式工作省电
  2. //硬件:2051单片机,P1.6到P1.0分别是 A到G,P1.7=DP,P3.5=D4,P3.4=D3,P3.1=D2,P3.0=D1,P3.7控制直流蜂鸣器(整点报时)。
  3. //       P3.2=0(改时间),P3.3=0(改状态),6Mhz晶振。
  4. //使用说明:默认时间为 2010年1月1日,0点0分,状态1显示时分
  5. //           按P3.2为0,状态++,状态功能分别为 1:显示时间 2:显示月日 3:显示年   4:修改分钟   5:修改时钟   6:修改年   7:修改月   8:修改日 ;
  6. //           用DP来表示状态,DP每秒闪烁1次(占空比3:1)。   对应的修改位置,闪烁。
  7. //           在显示年月日时分的状态启动P3.2为0,则进入关闭显示器模式,或打开显示器,在关闭显示器的模式中,按任意键打开显示器。
  8. //           在修改年月日时分的状态启动P3.2为0,则对应数字加一,一直按住,则一直加。注:改年份月份的时候为了不与万年历冲突,日期自动变为1号,年份范围是2010到2099年
  9. //注明:该程序不是最终程序,更新程序请联系中山董豪
  10. //实测参数:数码管工作时:2mA , 数码管不工作时:1mA
  11. //建议改进 选用更低频晶振 , 改用ATtiny2313代替。
  12. #include <reg52.h>              
  13. #include<intrins.h>
  14. #define uint unsigned int        
  15. #define uchar unsigned char     

  16. uchar second,minh,minl,hourh,hourl,hour,i,j,k,l,state,slient,dpi,dps,d2;
  17. uchar day,month,dayh,dayl,monthh,monthl;                                   //1,3,5,7,8,10,12 大 31
  18. uchar year1,year2,year3,year4,year;                                              //4,6,9,11,小30   
  19. //unsigned int d1,d0 ;                                                                    //2月闰年29天         year%4==0&&year%100!=0||year%400==0


  20. uchar code thourh[]={10,10,10,10,10,10,10,10,10,10,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2};
  21. uchar code thourl[]={0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4};
  22. uchar code tmonthh[]={10,10,10,10,10,10,10,10,10,10,1,1,1};
  23. uchar code tmonthl[]={ 0,1, 2, 3, 4, 5, 6, 7, 8, 9 ,0,1,2};
  24. uchar code tdayh[]={10,10,10,10,10,10,10,10,10,10,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,3,3};
  25. uchar code tdayl[]={ 0,1 ,2 ,3 ,4 ,5 ,6 ,7 ,8 ,9 ,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1};
  26. uchar code display[]={0x7E,0x30,0x6D,0x79,0x33,0x5B,0x5F,0x70,0x7F,0x7B,0x00}; //七段译码 P1.6=A
  27. sbit DP=P1^7;
  28. sbit int0=P3^2; //改时间
  29. sbit int1=P3^3;
  30. sbit bee=P3^7;
  31. sbit P3_0=P3^0;
  32. sbit P3_1=P3^1;
  33. sbit P3_4=P3^4;
  34. sbit P3_5=P3^5;
  35. void main()
  36. {
  37. TMOD=0x11;
  38. TH0=(65536-50000)/256;
  39. TL0=(65536-50000)%256;         //0.05s一次中断,时钟
  40. TH1=(65536-3000)/256;
  41. TL1=(65536-3000)%256;         //0.006s一次中断,扫描显示
  42.      IE=0X8A;                      //EA,ET0,ET1=1
  43. IP=0x02;                      //PT0=1;
  44. state=1; //    1:显示时间 2:显示月日 3:显示年   4:修改分钟   5:修改时钟   6:修改年   7:修改月   8:修改日 ;
  45. slient=1; // 1:正常显示    2:关闭显示
  46. second=0; //2010年0点0分0秒
  47. minl=0;
  48. minh=0;
  49. hour=0;
  50. day=1;
  51.      bee=0;
  52. month=1;
  53. year1=0;
  54. year2=1;
  55. year3=0;
  56. year4=2;
  57. TR1=1;
  58.      TR0=1;
  59. while(1)
  60. { PCON=0X01; //空闲模式}//while
  61. }
  62.    
  63. } //main   设置



  64. void timer0() interrupt 1 using 0 //时钟 改状态 改时间
  65. {
  66.      TH0=(65536-50000)/256;   //0.1s
  67. TL0=(65536-50000)%256;
  68. i++;
  69. if(i==10)
  70. {
  71. i=0;
  72.    bee=1;
  73.       if(slient==1)      //自动关闭显示器,剩电   10s自动关闭
  74. { d2++;
  75.    if(d2==10)
  76.     {d2=0;
  77.      //d3++;
  78.      //if(d3==200) //
  79.     // d3=0;
  80.      slient=0;
  81.    
  82.        }
  83.      }                    //自动关闭显示器,剩电
  84.    if(second<59)
  85.       second++;
  86.    else
  87.    {    second=0;
  88.    if(minl<9)
  89.       minl++;
  90.    else
  91.    {    minl=0;
  92.       if(minh<5)
  93.          minh++;
  94.       else
  95.       {
  96.         minh=0;
  97.      bee=0;               //整点报时
  98.       if(hour<23)
  99.          hour++;
  100.       else
  101.         { hour=0;

  102.             /////////////////////////////////////// 万年历
  103.                                 if(month==1 || month==3 || month==5 || month==7 || month==8 || month==10 || month==12) //1,3,5,7,8,10,12 大 31
  104.               {
  105.              if(day<31)
  106.             day++;
  107.           else
  108.             {day=1;
  109.              if(month<12)
  110.                month++;
  111.              else
  112.               { month=1;
  113.              if(year1<9)
  114.                year1++;
  115.              else
  116.                {year1=0;
  117.             if(year2<9)
  118.               year2++;
  119.             else
  120.               {year1=0;                //最高位2099年
  121.                   year2=1;
  122.                year3=0;
  123.                year4=2;
  124.               }
  125.                                              }
  126.            }
  127.              }
  128.                                    }
  129.            else if(month==4 || month==6 || month==9 || month==11)                                    //4,6,9,11,小30
  130.               {
  131.             if(day<30)
  132.             day++;
  133.           else
  134.             {day=1;
  135.              if(month<12)
  136.                month++;
  137.              else
  138.               { month=1;
  139.             if(year1<9)
  140.                year1++;
  141.              else
  142.                {year1=0;
  143.             if(year2<9)
  144.               year2++;
  145.             else
  146.               {year1=0;                //最高位2099年
  147.                   year2=1;
  148.                year3=0;
  149.                year4=2;
  150.               }
  151.                                              }
  152.            }
  153.             }
  154.             }
  155.            else if(month==2)                                              //2月闰年29天
  156.               { year=year4*1000+year3*100+year1*10+year1;
  157.           if((year%4==0&&year%100!=0)||year%400==0)
  158.            {if(day<29) //闰年
  159.                  day++;
  160.            else
  161.             {day=1;
  162.              if(month<12)
  163.                month++;
  164.              else
  165.               { month=1;
  166.             if(year1<9)
  167.                year1++;
  168.              else
  169.                {year1=0;
  170.             if(year2<9)
  171.               year2++;
  172.             else
  173.               {year1=0;                //最高位2099年
  174.                   year2=1;
  175.                year3=0;
  176.                year4=2;
  177.               }
  178.                                              }
  179.            }
  180.             }}
  181.                                       else
  182.                                        {if(day<28) //非闰年
  183.                  day++;

  184.              else
  185.              {day=1;
  186.              if(month<12)
  187.                month++;
  188.              else
  189.               { month=1;
  190.             if(year1<9)
  191.                year1++;
  192.              else
  193.                {year1=0;
  194.             if(year2<9)
  195.               year2++;
  196.             else
  197.               {year1=0;                //最高位2099年
  198.                   year2=1;
  199.                year3=0;
  200.                year4=2;}
  201.                                        }}}}
  202.            }
  203.                 ////////////////////////////////////////////
  204.                        }
  205.       }
  206.    }
  207.       }
  208. }
  209. /////////////////////////////////////////////////闪烁标志位
  210. dpi++;         //dps=0 的占空比为 3:1
  211. if(dpi==5)
  212. {
  213.     dpi=0;
  214.     dps++;
  215.     if(dps==2)
  216.     {dps=0;}
  217.       }//
  218. //    if(int1==0) //p3.3调状态 每秒看一次
  219. //       d2=0;
  220. //   }//dpi=5
  221. /////////////////////////////////////////////////////p3.3调状态
  222.    if(dpi==0 || dpi==2 || dpi==4) //0.2s 扫描一次
  223. { if(int1==0) //p3.3调状态
  224.        {   d2=0;
  225.          if(slient==1)
  226.      { if(state==8)

  227.      state=1;
  228.       else
  229.     state++;
  230.        }//slient==1
  231.         else
  232.          { slient=1;
  233.     ET1=1;}
  234. //       for(d1=1000000;d1>0;d1--);
  235.        } //调状态 int1==0
  236. ////////////////////////////////////////////////////////////p3.2改时间
  237. if(int0==0) //P3.2调节
  238.        {    d2=0;
  239.       if(state==1 || state==2 || state==3) //显示状态下按P3.2,进入不显示状态,按任意键退出。
  240.        {
  241.        if(slient==2)
  242.       { slient=1;
  243.     ET1=1;}
  244.     else
  245.        slient++;
  246.     }
  247.       else if(state==4)       //
  248.        {second=0;
  249.    if(minl<9)
  250.       minl++;
  251.    else
  252.    {    minl=0;
  253.       if(minh<5)
  254.          minh++;
  255.       else
  256.       {
  257.          minh=0;
  258.       }
  259.    }
  260.     }
  261.       else if(state==5)   //
  262.    {
  263.    if(hour<23)
  264.      hour++;
  265.    else
  266.      hour=0;
  267.    }
  268.    else if(state==8)   //
  269.      {            ///////////////////////////////////////
  270.                                 if(month==1 || month==3 || month==5 || month==7 || month==8 || month==10 || month==12)              //1,3,5,7,8,10,12 大 31
  271.               {
  272.              if(day<31)
  273.             day++;
  274.           else
  275.             day=1;
  276.                                     }
  277.            else if(month==4 || month==6 || month==9 || month==11)                                    //4,6,9,11,小30
  278.               {
  279.             if(day<30)
  280.             day++;
  281.           else
  282.                                        day=1;
  283.             }
  284.            else if(month==2)                                              //2月闰年29天
  285.               { year=year4*1000+year3*100+year1*10+year1;
  286.               if((year%4==0&&year%100!=0)||year%400==0)
  287.               {if(day<29) //闰年
  288.                  day++;
  289.            else
  290.               day=1;
  291.                                        }
  292.           else
  293.            {if(day<28) //非闰年
  294.                  day++;
  295.            else
  296.               day=1;
  297.            }
  298.            }
  299.                 ////////////////////////////////////////////
  300.      }
  301.    else if(state==7)   //
  302.      {
  303.               day=1;
  304.      if(month<12)
  305.       month++;
  306.      else
  307.      month=1;
  308.      }
  309.    else if(state==6)   // 1:显示时间 2:显示月日 3:显示年   4:修改分钟   5:修改时钟   6:修改年   7:修改月   8:修改日 ;
  310.      {     day=1;
  311.      if(year1<9)
  312.      year1++;
  313.      else
  314.     {   year1=0;
  315.       if(year2<9)
  316.        year2++;
  317.          else
  318.      {year1=0;                //最高位2099年
  319.       year2=1;
  320.       year3=0;
  321.       year4=2;
  322.      }
  323.              }
  324.      }//state=6
  325. //      for(d0=600000;d0>0;d0--);
  326.       }    //调时 int0
  327. //}
  328. } //dpi==0 ,2,4

  329. } //timer0 时间   调时   改状态




  330. void timer1() interrupt 3 using 3    //display
  331. {
  332. TH1=(65536-3000)/256;
  333. TL1=(65536-3000)%256;         //0.006s
  334.       monthl=tmonthl[month];
  335.    monthh=tmonthh[month];
  336.    dayl=tdayl[day];
  337.    dayh=tdayh[day];
  338.    hourl=thourl[hour];
  339.    hourh=thourh[hour];
  340.    if(slient==1)
  341.    {    if(j<4)
  342.        j++;
  343.      else
  344.        j=1;
  345.      if(state==1 || state==4 || state==5) //显示时间   1:显示时间 2:显示月日 3:显示年   4:修改分钟   5:修改时钟   6:修改年   7:修改月   8:修改日 ;
  346.       {
  347.          if(j==1)
  348.        {if(state==4 && dps==0 && int0!=0) // 闪烁,调节时不闪
  349.     P1=0x00;
  350.     else
  351.     {P1=display[minl];      //p3.5,p3.4,p3.1,p3.0 为势能端
  352.        }}    //11XX10
  353.       else if(j==2)
  354.        {if(state==4 && dps==0 && int0!=0) // 闪烁
  355.     P1=0x00;
  356.     else
  357.     {P1=display[minh];
  358.      }}    //11XX01
  359.           else if(j==3)
  360.        {if(state==5 && dps==0 && int0!=0) // 闪烁
  361.      P1=0x00;
  362.      else
  363.      {P1=display[hourl];
  364.      }}     //10XX11
  365.        else if(j==4)
  366.        {if(state==5 && dps==0 && int0!=0) // 闪烁
  367.      P1=0x00;
  368.      else
  369.      {P1=display[hourh];
  370.             }}        //01XX11
  371.            }
  372.     else if(state==2 || state==7 || state==8)    //显示月日     1:显示时间 2:显示月日 3:显示年   4:修改分钟   5:修改时钟   6:修改年   7:修改月   8:修改日 ;
  373.      {
  374.          if(j==1)
  375.        {if(state==8 && dps==0 && int0!=0) // 闪烁
  376.      P1=0x00;
  377.      else
  378.      {P1=display[dayl];      //p3.5,p3.4,p3.1,p3.0 为势能端
  379.       }}    //11XX10
  380.       else if(j==2)
  381.        {if(state==8 && dps==0 && int0!=0) // 闪烁
  382.      P1=0x00;
  383.      else
  384.      {P1=display[dayh];
  385.       }}    //11XX01
  386.           else if(j==3)
  387.        {if(state==7 && dps==0 && int0!=0) // 闪烁
  388.      P1=0x00;
  389.      else
  390.      {P1=display[monthl];
  391.       }}     //10XX11
  392.        else if(j==4)
  393.        {if(state==7 && dps==0 && int0!=0) // 闪烁
  394.      P1=0x00;
  395.      else
  396.      {P1=display[monthh];
  397.             }}        //01XX11
  398.      }
  399.    else if(state==3 || state==6)   //显示年
  400.    {   
  401.    if(state==6 && dps==0 && int0!=0)
  402.    P1=0x00;
  403.    else
  404.         {if(j==1)
  405.        {P1=display[year1];      //p3.5,p3.4,p3.1,p3.0 为势能端
  406.         }    //11XX10 3e
  407.       else if(j==2)
  408.        {P1=display[year2];
  409.      }    //11XX01 3d
  410.           else if(j==3)
  411.        {P1=display[year3];
  412.      }     //10XX11 2f
  413.        else if(j==4)
  414.        {P1=display[year4];
  415.            }        //01XX11 1f
  416.      }
  417.    }

  418.    if(j==1)
  419.     {P3_0=0;P3_1=1;P3_4=1;P3_5=1;}
  420.    else if(j==2)
  421.     {P3_0=1;P3_1=0;P3_4=1;P3_5=1;}
  422.    else if(j==3)
  423.     {P3_0=1;P3_1=1;P3_4=0;P3_5=1;}
  424.    else if(j==4)
  425.     {P3_0=1;P3_1=1;P3_4=1;P3_5=0;}
  426. /////////////////////////////////////////////////////////// DP
  427. /////////////////////////////////////////////////////////// 1:显示时间 2:显示月日 3:显示年   4:修改分钟   5:修改时钟   6:修改年   7:修改月   8:修改日 ;
  428.     if(dps==1)
  429.     {if(state==1 || state==2)
  430.     {    if(j==1)                  //DP,显示时间,月日
  431.        {DP=0;}   
  432.      else if(j==2)
  433.        {DP=0;}  
  434.           else if(j==3)
  435.        {DP=1;}   
  436.      else if(j==4)
  437.        {DP=0;}        }
  438.    else if(state==3)
  439.     {    if(j==1)                  //DP,显示年
  440.        {DP=0;}   
  441.      else if(j==2)
  442.        {DP=0;}  
  443.           else if(j==3)
  444.        {DP=0;}   
  445.      else if(j==4)
  446.        {DP=0;}        }
  447.    else if(state==4)
  448. {    if(j==1)                  //DP,改分钟
  449.        {DP=1;}   
  450.      else if(j==2)
  451.        {DP=1;}  
  452.           else if(j==3)
  453.        {DP=0;}   
  454.      else if(j==4)
  455.        {DP=0;}        }
  456.      else if(state==5)
  457. {    if(j==1)                  //DP,改时钟
  458.        {DP=0;}   
  459.      else if(j==2)
  460.        {DP=0;}  
  461.           else if(j==3)
  462.        {DP=1;}   

  463.     else if(j==4)
  464.        {DP=1;}        }
  465.     else if(state==8)
  466.     {      if(j==1)                  //DP,改日
  467.        {DP=0;}   
  468.      else if(j==2)
  469.        {DP=1;}  
  470.           else if(j==3)
  471.        {DP=0;}   
  472.      else if(j==4)
  473.        {DP=0;}
  474.     }
  475.        else if(state==7)
  476.     {      if(j==1)                  //DP,改月
  477.        {DP=0;}   
  478.      else if(j==2)
  479.        {DP=0;}  
  480.           else if(j==3)
  481.        {DP=0;}   
  482.      else if(j==4)
  483.        {DP=1;}
  484.     }
  485.       else if(state==6)
  486.     {         DP=0;                //DP, 改年
  487.     }}
  488.     else   //dps==0
  489.     DP=0;
  490.     //////////////////////////////////////////////////////////////////DP
  491.     }
  492.       else //slient==0
  493.      {P1=0x00;ET1=0;}   //省电,关闭显示器,关闭显示中断
  494. } //timer1 显示
复制代码




回复

使用道具 举报

ID:83279 发表于 2015-6-17 17:38 | 显示全部楼层
求大神给编个程序,用89C52系列单片机及六位数码管显示时、分、秒,以24小时计时方式运行,能整点提醒(短蜂鸣,次数代表整点时间),使用按键开关可以实现时分调整、秒表/时钟功能转换、省电(关闭显示)、定时设定提醒(蜂鸣器)等功能。
回复

使用道具 举报

ID:99341 发表于 2016-5-11 21:15 | 显示全部楼层
楼主,电路图发一个
回复

使用道具 举报

ID:79094 发表于 2024-3-26 22:56 | 显示全部楼层
是啊  大神  给个图纸 手残党 对着做个
回复

使用道具 举报

ID:1064915 发表于 2024-3-27 17:20 | 显示全部楼层
楼主都是2015年的,快十年了
回复

使用道具 举报

ID:961114 发表于 2024-3-28 09:10 | 显示全部楼层
joyb 发表于 2024-3-27 17:20
楼主都是2015年的,快十年了

是啊 现在芯片的RTC都是标配了,支持年、月、日、时、分、秒、次秒(1/128秒),并支持时钟中断和一组闹钟而且价格还美丽
回复

使用道具 举报

ID:127678 发表于 2024-4-1 10:51 | 显示全部楼层
都2024年了,帖子马上都十年了,我才开始接触单片机
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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