找回密码
 立即注册

QQ登录

只需一步,快速开始

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

用LED制作数码管万年历 单片机+ds12c887+max7219 附源程序

[复制链接]
跳转到指定楼层
楼主
长期以来,一直想做一个大数码管万年历,但大数码管笔段大都为几个LED串联组成,显示部分需要较高的电压,不能与单片机共用5v电源。这将使电路复杂化。前些时候受本论坛一个网友的启发,时间显示部分用多只LED并联组成8字形“数码管”,公历农历日期温度都用0.8吋数码管,制作万年历成功,用手机充电器供电,十分方便。单片机用STC89c52RC,时间获取用DS12C887,显示驱动用三支7219级联完成。电路图手工谅解制作,画的不好,望网友们谅解。

电路原理图如下:


单片机源程序如下:

  1. /*************说明*************************************************
  2. 1.程序主体部分参照ds1302+max7219级联驱动24位数码管万年历程序编辑修改
  3. 2.7219初始化要设置0x09,0x0a,0x0b,0x0c,0x0f五个控制寄存器,并且要在
  4.   显示之前初始化,否则可能出现显示错误
  5. 3.ds12c887初始化程序两项主要内容1为控制寄存器参数,2为初次设置的时间
  6. 日期。两项可合为一函数,887初始化仅限1次,一旦开启887运行,由于887由
  7. 芯片内部电池供电,数据不会丢失,因此不需要再次写入
  8. 4.由于7219选择不译码和语音报时函数都需要十进制数据,887设置为二进制,
  9. 即B寄存器设置DM=1 (要注意,一些中文资料DM=0是错误的)
  10. *************************************************************************/
  11. #include <reg52.h>
  12. #include <intrins.h>
  13. #include <yyxp.h>
  14. #include <string.h>
  15. #include <absacc.h>                //头文件
  16. #include "eeprom52.h"
  17. #include "ds18b20.h"
  18. #include "max7219.h"
  19. #define uc unsigned char //宏定义
  20. #define ui unsigned int
  21. #include "gton.h"

  22. /*----定义DS12C887数据线---*/
  23. //#define Ds_DATA P0  //DS12CR887数据总线,P0.0-P0.7对应连接AD0-AD7
  24. sbit ds_cs = P2^4;
  25. sbit ds_as = P2^5;
  26. sbit ds_rw = P2^6;
  27. sbit ds_ds = P2^7;

  28. /*----定义其它数据线---*/
  29. sbit s1=P1^4;                         //按键设置+确认
  30. sbit s2=P1^5;                          //加 ,运行状态下为语音播报模式设置
  31. sbit s3=P1^6;                          //减, 运行状态下为闹钟开关设置
  32. sbit s4=P1^7;                          //运行状态下为语音报时开关
  33. sbit s5=P3^4;                          //运行状态下为关闭报警
  34. sbit LED1 =P3^6;                  //闹钟指示灯
  35. sbit deng=P3^7;                         //秒灯
  36. sbit fmq=P2^3;                         //蜂鸣器
  37. sbit ACC0=ACC^0;
  38. sbit ACC7=ACC^7;

  39. void display();                                //显示函数
  40. void sec_led();                                //控制秒灯的函数
  41. void bofang(uc ms,uc *df);
  42.                           //        0         1           2         3          4           5          6           7          8           9
  43. uc code tab[]={0x7e,0x30,0x6d,0x79,0x33,0x5b,0x5f,0x70,0x7f,0x7b,0x00,0x0d};        //不译码段选
  44. uc code tab1[]={0xfe,0xb0,0xed,0xf9,0xb3,0xdb,0xdf,0xf0,0xff,0xfb};                //带小数点
  45. uc code dxy[]={0,1,2,1,0,1,0,1,1,0,1,0,1};
  46. uc set=0,ee;  //设置键按下次数(菜单),定时器溢出次数

  47. char nian,yue,ri,xq,shi,fen,miao,nz_shi,nz_fen;        //定义公历年月日星期时分秒(十进制码)

  48. bit bdata bs,tt,h;          //整点报时标志位,设置完成标志位,秒灯控制标志位
  49. bit bj=0;          //闹铃标志位
  50. bit zdbj=0;                //中断报警标志
  51. bit bjkg=0;                //闹铃开关
  52.                                  
  53. uc mode=0;                                //语音播报模式:1报时间;2报日期和时间;3报时间和温度;4三项全报;5关闭
  54. uc disbuff[16]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};                 //数组用于存放时间温度距离等信息
  55. uc nl_nian,nl_yue,nl_ri;                 //        定义农历年,月,日
  56. bit bdata bs,tt,h;    //语音报时标志,时间设置完成标志位,秒灯标志位,
  57.                                    
  58.                                                                   
  59. /******************把数据保存到单片机内部eeprom中******************/
  60. void write_eeprom()
  61. {
  62.         SectorErase(0x2000);
  63.         byte_write(0x2000, nz_shi);
  64.         byte_write(0x2001, nz_fen);
  65.         byte_write(0x2002, bjkg);
  66.         byte_write(0x2003, mode);
  67.         byte_write(0x2060, a_a);        
  68. }

  69. /******************把数据从单片机内部eeprom中读出来*****************/
  70. void read_eeprom()
  71. {
  72.         nz_shi   = byte_read(0x2000);
  73.         nz_fen = byte_read(0x2001);
  74.         bjkg = byte_read(0x2002);
  75.         mode = byte_read(0x2003);
  76.         a_a      = byte_read(0x2060);
  77. }
  78.                                                                                                                   
  79. /**************开机自检eeprom初始化*****************/
  80. void init_eeprom()
  81. {
  82.         read_eeprom();                //先读
  83.         if(a_a != 1)                //新的单片机初始单片机内问eeprom
  84.         {
  85.                 nz_shi   = 12;
  86.                 nz_fen = 30;
  87.                 bjkg=0;
  88.                 mode=4;
  89.                 a_a = 1;
  90.                 write_eeprom();           //保存数据
  91.         }        

  92. }
  93. void delayms(ui x)                                        //延时x毫秒
  94. {
  95.         ui i,j;
  96.         for(i=0;i<x;i++)
  97.         for(j=0;j<110;j++);

  98. }                                                   


  99.                                                   
  100. /*****ds12c887函数*****/
  101. void write_ds12c887(uc add,uc date)        //写入地址和数据
  102. {
  103.      
  104.     //date=((date/10)*16)+(date%10); //        十进制转换成DCB码(仅在887设置为BCD数据格式时使用)
  105.         ds_cs=0;
  106.         ds_as=1;
  107.         ds_ds=1;
  108.         ds_rw=1;
  109.         P0=add;
  110.     ds_as=0;
  111.         ds_rw=0;
  112.         P0=date;
  113.     ds_rw=1;
  114.         ds_as=1;
  115.         ds_cs=1;
  116. }

  117. uc read_ds12c887(uc add)  //读数据
  118. {
  119.         uc time;
  120.         ds_as=1;
  121.         ds_ds=1;
  122.         ds_rw=1;
  123.         ds_cs=0;
  124.         P0=add;
  125.     ds_as=0;
  126.         ds_ds=0;
  127.         P0=0xff;
  128.         time=P0;
  129.     ds_as=1;
  130.         ds_ds=1;
  131.         ds_cs=1;
  132. //   time=time/16*10+time%16; //BCD转十进制
  133.         return time;
  134. }

  135. void ds12c887()        //读取写入ds12c887函数
  136. {
  137.         if((tt==1)&&(set==0)) //当退出时间设定时,首先将设定的时间写入芯片
  138.         {
  139.                 tt=0;
  140.                 write_ds12c887(0x00,miao);                //秒
  141.                 write_ds12c887(0x02,fen);                //分
  142.                 write_ds12c887(0x04,shi);                //时
  143.                 write_ds12c887(0x06,xq);                //星期
  144.                 write_ds12c887(0x07,ri);                //日
  145.                 write_ds12c887(0x08,yue);                //月
  146.                 write_ds12c887(0x09,nian);                //年
  147.                         
  148.         }
  149.         if(set==0)                        
  150.         {
  151.                  miao=read_ds12c887(0x00);
  152.              fen=read_ds12c887(0x02);
  153.                  shi=read_ds12c887(0x04);
  154.                  xq=read_ds12c887(0x06);
  155.                  ri=read_ds12c887(0x07);
  156.                  yue=read_ds12c887(0x08);
  157.                  nian=read_ds12c887(0x09);
  158.                  
  159.     }
  160.            
  161. }
  162. /*void DS12C887_init()           //887初始化,设置887寄存器初始参数,仅限初次上电使用
  163. {
  164.          write_ds12c887(10, 0x20);                //DS12CR887寄存器A功能设置,开启时钟振荡器
  165.          write_ds12c887(11, 0x06);                //寄存器B功能设置,不开启闹钟中断使能,数据模式为二进制,24小时模式。
  166.         write_ds12c887(9, 22);
  167.         write_ds12c887(8, 10);
  168.         write_ds12c887(7, 6);
  169.         write_ds12c887(6, 4);
  170.         write_ds12c887(4, 12);
  171.         write_ds12c887(2, 55);
  172.         write_ds12c887(0, 58);        
  173. }                                                           */

  174. /*****按键函数*****/
  175. void key()
  176. {
  177.         ui out_set=0;          //退出设置时间记数
  178.         //out_clear=0;
  179.         
  180.         if(s1==0)                                  //如果s1设置键按下
  181.         {                                                  //
  182.                 delayms(5);                          //延时消抖 ()
  183.                 if(s1==0)                          //确认s1按下
  184.                 {
  185.                         while((s1==0)&&(set!=0))        //已确认s1按下并弹回时
  186.                         {
  187.                                 display();                                //显示初始化数据
  188.                                 out_set++;                                //
  189.                                 if(out_set==300)        // 如果设置键弹开时间达300毫秒
  190.                                 {
  191.                                         set=0;
  192.                                         out_set=0;
  193.                                         tt=0;
  194.                                         fmq=0;                        //蜂鸣器短响一声
  195.                                         delayms(20);
  196.                                         fmq=1;
  197.                                         delayms(100);
  198.                                         fmq=0;
  199.                                         delayms(20);
  200.                                         fmq=1;
  201.                                         goto x;
  202.                                 }
  203.                         }
  204.                         
  205.                         set++;                                        //进入设置方式1
  206.                         if(set<10)                                //如果设置次数小于8
  207.                         {
  208.                                 out_set=0;                        //退出设置
  209.                                 fmq=0;
  210.                                 delayms(10);
  211.                                 fmq=1;
  212.                         }
  213.                         else
  214.                         {
  215.                                 set=0;                                //设置次数归0
  216.                                 tt=1;                                //设置完成
  217.                                 fmq=0;
  218.                                 delayms(200);
  219.                                 fmq=1;
  220.                         }

  221. x:                        while(!s1)                                //等待s1弹起
  222.                         {
  223.                                 display();
  224.                                 sec_led();
  225.                         }
  226.                 }
  227.         }
  228.         
  229.         if(set!=0)
  230.         {
  231.                 if(s2==0)                                        //如果加键按下
  232.                 {
  233.                         delayms(5);
  234.                         if(s2==0)
  235.                         {
  236.                                 fmq=0;
  237.                                 delayms(10);
  238.                                 fmq=1;
  239.                                 if(set==1)                        //如果设置键按下次数为1(菜单1,设置年)
  240.                                 {
  241.                                         nian++;                        //年增加(随着加键按下)
  242.                                         if(nian==100)
  243.                                         nian=0;
  244.                                         if((dxy[yue]==2)&&(nian%4!=0)&&(ri>28)==1)//当平年二月day大于28时
  245.                                         ri=28;
  246.                                 }
  247.                                 if(set==2)                        //如果设置菜单为2(设置月)
  248.                                 {
  249.                                         yue++;                        //月增加
  250.                                         if(yue==13)
  251.                                         yue=1;
  252.                                         if((dxy[yue]==0)&&(ri>30)==1)        //当小月day大于30时
  253.                                         ri=30;
  254.                                         if((dxy[yue]==2)&&(nian%4==0)&&(ri>28)==1)//当平年二月day大于28时
  255.                                         ri=28;
  256.                                         if((dxy[yue]==2)&&(nian%4!=0)&&(ri>29)==1)//当闰年二月day大于29时
  257.                                         ri=29;
  258.                                 }
  259.                                 if(set==3)                        //如果设置菜单为3(设置日)
  260.                                 {
  261.                                         ri++;                        //日增加
  262.                                          
  263.                                         if((dxy[yue]==0)&&(ri==31)==1)        //当小月day被加到了31时
  264.                                         ri=1;
  265.                                         if((dxy[yue]==1)&&(ri==32)==1)        //当大月day被加到32时
  266.                                         ri=1;
  267.                                         if((dxy[yue]==2)&&(nian%4==0)&&(ri==29)==1) //当平年二月day被加到29时
  268.                                         ri=1;
  269.                                         if((dxy[yue]==2)&&(nian%4!=0)&&(ri==30)==1) //当闰年二月day被加到30时
  270.                                         ri=1;
  271.                                 }
  272.                                 if(set==4)                          //如果设置菜单为4(设置星期)
  273.                                 {
  274.                                     xq++;
  275.                                         if(xq==8)
  276.                                         xq=1;
  277.                                        
  278.                                 }
  279.                                 if(set==5)                           //如果设置菜单为5(设置时)
  280.                                 {
  281.                                     shi++;
  282.                                         if(shi==24)
  283.                                         shi=0;
  284.                                        
  285.                                 }
  286.                                 if(set==6)                           //如果设置菜单为6(设置分)
  287.                                 {
  288.                                     fen++;
  289.                                         if(fen==60)
  290.                                         fen=0;        
  291.                                 }
  292.                                 if(set==7)                           //如果设置菜单为7(设置秒)
  293.                                 {
  294.                                         miao++;
  295.                                         if(miao==60)
  296.                                         miao=0;                           
  297.                                 }
  298.                                 if(set==8)                           //如果设置菜单为8(设置闹钟时)
  299.                                 {
  300.                                         nz_shi++;
  301.                                         if(nz_shi==24)
  302.                                         nz_shi=0;
  303.                                         write_eeprom();         //保存数据
  304.                                 }
  305.                                 if(set==9)                                //如果设置菜单为9(设置闹钟分)
  306.                                 {
  307.                                         nz_fen++;
  308.                                         if(nz_fen==60)
  309.                                         nz_fen=0;
  310.                              write_eeprom();
  311.                                 }
  312.                                 while(!s2)                                        //等待加按键弹起
  313.                                 {display();}                                //正常显示         
  314.                         }
  315.                 }
  316.                 if(s3==0)                                           //如果减键按下
  317.                 {
  318.                         delayms(5);
  319.                         if(s3==0)                                   
  320.                         {
  321.                                 fmq=0;
  322.                                 delayms(10);
  323.                                 fmq=1;
  324.                                 if(set==1)                                //如果设置菜单为1
  325.                                 {
  326.                                         nian--;                                //年减少
  327.                                         if(nian==(-1))
  328.                                         nian=99;
  329.                                         if((dxy[yue]==2)&&(nian%4==0)&&(ri>28)==1)
  330.                                         ri=28;
  331.                                 }
  332.                                 if(set==2)
  333.                                 {
  334.                                         yue--;
  335.                                         if(yue==0)
  336.                                         yue=12;
  337.                                         if((dxy[yue]==0)&&(ri>30)==1)
  338.                                         ri=30;
  339.                                         if((dxy[yue]==2)&&(nian%4==0)&&(ri>28)==1)
  340.                                         ri=28;
  341.                                         if((dxy[yue]==2)&&(nian%4!=0)&&(ri>29)==1)
  342.                                         ri=29;
  343.                                 }
  344.                                 if(set==3)
  345.                                 {
  346.                                         ri--;
  347.                                          
  348.                                         if((dxy[yue]==0)&&(ri==0)==1)
  349.                                         ri=30;
  350.                                         if((dxy[yue]==1)&&(ri==0)==1)
  351.                                         ri=31;
  352.                                         if((dxy[yue]==2)&&(nian%4==0)&&(ri==0)==1)
  353.                                         ri=28;
  354.                                         if((dxy[yue]==2)&&(nian%4!=0)&&(ri==0)==1)
  355.                                         ri=29;
  356.                                 }
  357.                                 if(set==4)
  358.                                 {
  359.                                 xq--;
  360.                                         if(xq==0)
  361.                                         xq=7;               
  362.                                 }
  363.                                 if(set==5)
  364.                                 {
  365.                                     shi--;
  366.                                         if(shi==(-1))
  367.                                         shi=23;
  368.                                        
  369.                                 }
  370.                                 if(set==6)
  371.                                 {
  372.                                     fen--;
  373.                                         if(fen==(-1))
  374.                                         fen=59;        
  375.                                 }
  376.                                 if(set==7)                                         //如果设置菜单为7
  377.                                 {
  378.                                         miao--;
  379.                                         if(miao==(-1))
  380.                                         miao=59;
  381.                                 }
  382.                                 if(set==8)
  383.                                 {
  384.                                         nz_shi--;
  385.                                         if(nz_shi==(-1))
  386.                                         nz_shi=23;
  387.                                         write_eeprom();                                //保存数据
  388.                                 }
  389.                                 if(set==9)
  390.                                 {
  391.                                         nz_fen--;
  392.                                         if(nz_fen==(-1))
  393.                                         nz_fen=59;
  394.                                         write_eeprom();                                //保存数据
  395.                                 }
  396.                                 while(!s3)
  397.                                 {display();}               
  398.                         }
  399.                 }
  400.         }
  401.         if(set==0)                                                                 //如果设置菜单为0,时日设置完成
  402.         {
  403.                 if(s2==0)      //如果s2按下
  404.                 {
  405.                         delayms(5);
  406.                         if(s2==0)    //如果确认s2按下,语音报时模式选择
  407.                         {
  408.                  fmq=0;                 //蜂鸣器短鸣一声
  409.                                  delayms(10);
  410.                                  fmq=1;
  411.                                  mode++;
  412.                              if(mode>5)
  413.                              mode=1;
  414.                              write_eeprom();                                //保存数据
  415.                         }
  416.                         while(!s2);
  417.                         {display();}
  418.         }
  419.                 if(s3==0)                        //如果s3按下,报警开关
  420.                 {
  421.                          delayms(5);                                          //延时5毫秒
  422.                          if(s3==0)
  423.                          {
  424.                   fmq=0;                 //蜂鸣器短鸣一声
  425.                                   delayms(10);
  426.                                   fmq=1;
  427.                   bjkg=~bjkg;
  428.                           write_eeprom();
  429.              }
  430.                          while(!s4);
  431.                          {display();}
  432.                 }
  433.                 if(s4==0)
  434.                 {
  435.                    bofang(mode,disbuff);
  436.                 }
  437.                 if((s5==0)&&(bj==1))        //按键关闭闹钟
  438.                 {
  439.                    zdbj=1;
  440.                    bj=0;
  441.                    fmq=1;
  442.                 }
  443.         }                     
  444. }

  445. //=====================================================================================
  446. //=====================================================================================

  447. /*****主显示函数*****/
  448. void display()
  449. {        //         年          月         日           时         分              温度                 秒                  
  450.    uc  x1,x2,x3,x4,x5,x6,x7,x8,x9,x10,x11,x12,x13,x14,x15;   
  451.         //农历月农历日 闹钟时闹钟分
  452.    uc  y1,y2,y3,y4,y5,y6,y7,y8;
  453.         
  454.     x1=nian/10;                 //年十位
  455.         x2=nian%10;                 //年个位

  456.         x3=yue/10;
  457.         x4=yue%10;

  458.         x5=ri/10;
  459.         x6=ri%10;

  460.         x7=shi/10;                   //时十位         
  461.         x8=shi%10;

  462.         x9=fen/10;                   //分十位
  463.         x10=fen%10;

  464.         x11=wendu/100;       //温度十位
  465.         x12=(wendu%100)/10;
  466.         x13=(wendu%100)%10;

  467.         x14=miao/10;          //秒十位
  468.         x15=miao%10;

  469.     y5=nz_shi/10;    //闹钟时十位
  470.         y6=nz_shi%10;
  471.         y7=nz_fen/10;    //闹钟分十位
  472.         y8=nz_fen%10;                 

  473.          InitDis_3();

  474.     if(set!=1)                                        // 设置年数据
  475.         {
  476.                 WriteWord_3(0x07,tab[2]);
  477.                 WriteWord_3(0x08,tab[0]);
  478.                 WriteWord_3(0x01,tab[x1]);
  479.                 WriteWord_3(0x02,tab[x2]);
  480.         }                                                         
  481.         else if(set==1)                                 // 写入年数据
  482.         {
  483.                 if(h==0)                                 // 秒灯灭时写入
  484.                 {
  485.                         WriteWord_3(0x07,tab[2]);           //显示2
  486.                         WriteWord_3(0x08,tab[0]);           //显示0
  487.                         WriteWord_3(0x01,tab[x1]);   //显示x1
  488.                         WriteWord_3(0x02,tab[x2]);   //显示x2
  489.                 }
  490.                 else                                         // 秒灯亮时不显示(秒灯闪烁显示数据随着闪烁)
  491.                 {
  492.                         WriteWord_3(0x07,tab[10]);         //不显示  
  493.                         WriteWord_3(0x08,tab[10]);         //
  494.                         WriteWord_3(0x01,tab[10]);         //
  495.                         WriteWord_3(0x02,tab[10]);         //不显示
  496.                 }
  497.         }
  498.         if(set!=2)                                                         // 设置月数据
  499.         {
  500.                 if(x3==0)
  501.                 {                                                 //如果月十位为0
  502.                 WriteWord_3(0x03,tab[10]);                 //不显示
  503.                 WriteWord_3(0x04,tab[x4]);
  504.                 }                  
  505.                 else
  506.                 {                                                         //否则
  507.                 WriteWord_3(0x03,tab[x3]);                 //显示x3
  508.                 WriteWord_3(0x04,tab[x4]);
  509.                 }                 //显示x4
  510.         }
  511.         else if(set==2)                                                 // 写入月数据
  512.         {
  513.                 if(h==0)
  514.                 {
  515.                         if(x3==0)
  516.                         {
  517.                         WriteWord_3(0x03,tab[10]);
  518.                         WriteWord_3(0x04,tab[x4]);
  519.                         }
  520.                         else
  521.                         {
  522.                         WriteWord_3(0x03,tab[x3]);
  523.                         WriteWord_3(0x04,tab[x4]);
  524.                         }
  525.                 }
  526.                 else
  527.                 {
  528.                         WriteWord_3(0x03,tab[10]);
  529.                         WriteWord_3(0x04,tab[10]);
  530.                 }
  531.         }
  532.         if(set!=3)                                                  // 设置日数据
  533.         {
  534.                
  535.                 if(x5==0)
  536.                 {
  537.                 WriteWord_3(0x05,tab[10]);
  538.                 WriteWord_3(0x06,tab[x6]);
  539.                 }
  540.                 else
  541.                 WriteWord_3(0x05,tab[x5]);
  542.                 WriteWord_3(0x06,tab[x6]);
  543.         }
  544.         else if(set==3)                                        // 写入日数据
  545.         {
  546.                 WriteWord_3(0x05,tab[x5]);
  547.                 WriteWord_3(0x06,tab[x6]);
  548.                
  549.                 if(h==0)                                         
  550.                 {
  551.                         if(x5==0)
  552.                         {
  553.                         WriteWord_3(0x05,tab[10]);
  554.                         WriteWord_3(0x06,tab[x6]);
  555.                         }
  556.                         else
  557.                         WriteWord_3(0x05,tab[x5]);
  558.                         WriteWord_3(0x06,tab[x6]);
  559.                 }
  560.                 else
  561.                 {
  562.                         WriteWord_3(0x05,tab[10]);
  563.                         WriteWord_3(0x06,tab[10]);
  564.                 }
  565.         }

  566.         InitDis_2();
  567.    
  568.         if(set!=4)
  569.         {
  570.                 if(xq!=7)
  571.                 WriteWord_2(0x07,tab[xq]);
  572.                 else
  573.                 WriteWord_2(0x07,tab[(xq+1)]);
  574.         }
  575.         else if(set==4)
  576.         {
  577.                 if(h==0)
  578.                 {
  579.                         if(xq!=7)
  580.                         WriteWord_2(0x07,tab[xq]);
  581.                         else
  582.                         WriteWord_2(0x07,tab[(xq+1)]);
  583.                 }
  584.                 else
  585.                 {
  586.                         WriteWord_2(0x07,tab[10]);
  587.                 }
  588.         }

  589.         if(set!=5)                                                 //设置时数据
  590.         {
  591.                 if(x7==0)
  592.                 {                                           //如果时十位是0
  593.                 WriteWord_2(0x01,tab[10]);   //不显示
  594.                 WriteWord_2(0x02,tab[x8]);
  595.                 }
  596.                 else                                           //否则
  597.                 WriteWord_2(0x01,tab[x7]);   //显示时十位
  598.                 WriteWord_2(0x02,tab[x8]);   //显示时个位
  599.         }
  600.         else if(set==5)                                       //写入时数据
  601.         {
  602.                 if(h==0)                                  //秒灯灭写入
  603.                 {
  604.                         if(x7==0)
  605.                         {
  606.                         WriteWord_2(0x01,tab[10]);
  607.                         WriteWord_2(0x02,tab[x8]);
  608.                         }
  609.                         else
  610.                         WriteWord_2(0x01,tab[x7]);
  611.                         WriteWord_2(0x02,tab[x8]);
  612.                 }
  613.                 else                                           //秒灯亮不显示
  614.                 {
  615.                         WriteWord_2(0x01,tab[10]);
  616.                         WriteWord_2(0x02,tab[10]);
  617.                 }
  618.         }
  619.         if(set!=6)                                                   //设置分
  620.         {
  621.                 WriteWord_2(0x03,tab[x9]);
  622.                 WriteWord_2(0x04,tab[x10]);
  623.         }
  624.         else if(set==6)                                           //写入分
  625.         {
  626.                 if(h==0)
  627.                 {
  628.                         WriteWord_2(0x03,tab[x9]);
  629.                         WriteWord_2(0x04,tab[x10]);
  630.                 }
  631.                 else
  632.                 {
  633.                         WriteWord_2(0x03,tab[10]);
  634.                         WriteWord_2(0x04,tab[10]);
  635.                 }
  636.         }
  637.         
  638.     if(set!=7)
  639.         {
  640.           WriteWord_2(0x05,tab[x14]);
  641.           WriteWord_2(0x06,tab[x15]);
  642.         }
  643.         else if(set==7)        
  644.         {
  645.                 if(h==0)
  646.                 {
  647.                         WriteWord_2(0x05,tab[x14]);
  648.                         WriteWord_2(0x06,tab[x15]);
  649.                 }
  650.                 else
  651.                 {
  652.                         WriteWord_2(0x05,tab[10]);
  653.                         WriteWord_2(0x06,tab[10]);
  654.                 }
  655.         
  656.         }
  657.                   
  658.           InitDis_1();

  659.         if(set==8)
  660.         {
  661.           WriteWord_1(0x05,tab[y5]);
  662.           WriteWord_1(0x06,tab[y6]);
  663.         }
  664.         if(set==9)
  665.         {
  666.           WriteWord_1(0x07,tab[y7]);
  667.           WriteWord_1(0x08,tab[y8]);
  668.         }
  669.         if(set==0)                                                          //如果时钟走时时间设置菜单为0 ,时日设置完成
  670.         {
  671.            
  672.            SunToMoon(nian,yue,ri);         //调用农历转换
  673.          
  674.            y1=month_moon/10;                 //农历月十位
  675.            y2=month_moon%10;
  676.        y3=day_moon/10;     //农历日十位
  677.            y4=day_moon%10;
  678.        if(y1==0)
  679.            {
  680.               WriteWord_1(0x01,tab[10]);
  681.                   WriteWord_1(0x02,tab[y2]);
  682.                 }
  683.             else
  684.                 {
  685.                   WriteWord_1(0x01,tab[y1]);                //显示农历月
  686.                   WriteWord_1(0x02,tab[y2]);
  687.                 }                  
  688.                 if(y3==0)
  689.                 {
  690.                         WriteWord_1(0x03,tab[10]);
  691.                         WriteWord_1(0x04,tab[y4]);
  692.                 }
  693.                 else
  694.                 {        
  695.                   WriteWord_1(0x03,tab[y3]);                //显示农历日
  696.                   WriteWord_1(0x04,tab[y4]);
  697.                 }
  698.                 if(x11==0)
  699.                 {
  700.                    WriteWord_1(0x05,tab[10]);                //温度十位为0不显示
  701.                    WriteWord_1(0x06,tab1[x12]);
  702.                    WriteWord_1(0x07,tab[x13]);  
  703.                    WriteWord_1(0x08,tab[11]);        //显示C        
  704.                 }
  705.                 else                                                        //否则
  706.                 {
  707.                    WriteWord_1(0x05,tab[x11]);        //显示温度
  708.                    WriteWord_1(0x06,tab1[x12]);
  709.                    WriteWord_1(0x07,tab[x13]);  
  710.                    WriteWord_1(0x08,tab[11]);        //显示C        
  711.                 }
  712.                  if(bjkg==1)
  713.              LED1=0;     //显示闹钟开
  714.                  else
  715.                  LED1=1;
  716.         

  717.   }
  718.     disbuff[0]=x1;                                   //年十位值  数组0号数据
  719.         disbuff[1]=x2;                                  //年个位值  数组1号数据
  720.         disbuff[2]=x3;                                  //月十位值  数组2号数据   
  721.          disbuff[3]=x4;                                  //月个位值  数组3号数据
  722.          disbuff[4]=x5;
  723.          disbuff[5]=x6;                                  //日个位值
  724.         disbuff[6]=xq;                              //星期  数组6号数据
  725.          disbuff[7]=x7;                                  //时十位值  数组7号数据
  726.          disbuff[8]=x8;                                  //时个位值
  727.          disbuff[9]=x9;                                  //分十位值
  728.          disbuff[10]=x10;                          //分个位值
  729.          disbuff[11]=x14;                          //秒十位值
  730.         disbuff[12]=x15;
  731.         disbuff[13]=x11;                          //温度十位值
  732.         disbuff[14]=x12;                      //温度个位值
  733.         disbuff[15]=x13;                          //温度小数位值        
  734.       
  735.                                           
  736. }


  737. /*****闹钟函数*****/
  738. void clock_dis()
  739. {
  740.         if(zdbj==0&&bjkg==1&&set==0)
  741.         {
  742.                 if(shi==nz_shi&&fen==nz_fen)
  743.                 bj=1;
  744.                 else
  745.                 {
  746.                         fmq=1;
  747.                         bj=0;
  748.                 }
  749.         }
  750.            
  751. }                                                                              


  752. /*****语音报时函数*****/
  753. void bofang(uc broadcast,uc *str)        //两个参数(节目,数组指针)
  754. {  

  755.         uc length,length_finish;          //根据芯片秒数声明播放语句数(大约每句1秒)?
  756. //        length=1;
  757.         if(broadcast==1)                          //播放模式1  只报时间
  758.         {
  759.                 length=15;                                  //从第15句开始
  760.                 length_finish=26;                  //到第26句结束
  761.         }
  762.         else if(broadcast==2)                  //播放模式2  报时间和日期
  763.         {
  764.                 length=0;
  765.                 length_finish=26;
  766.         }
  767.         else if(broadcast==3)                  //播放模式3  报时间和温度
  768.         {
  769.                 length=15;
  770.                 length_finish=33;
  771.         }
  772.         else if(broadcast==4)                   //播放模式4 报时间和日期        温度
  773.         {                                                                                       
  774.                 length=0;                                  //从第0句开始
  775.                 length_finish=33;                  //到第33句结束
  776.         }
  777.         else                  //否则不播放 模式0
  778.         {
  779.                 length=1;          //从第1句开始
  780.                 length_finish=1;   //到第1句结束
  781.         }
  782.         
  783.         if(length<length_finish)
  784.         {
  785.                 TR0=0;                                   //关闭定时器
  786.                 //speak(25);                   //车站大厅音乐-------开机音乐  */
  787.              while(length<length_finish/*&&flag_bofang*/)        //最大32         
  788.                  {
  789.                         if(yyxp_busy==1)                                                        //
  790.                         {
  791.                                 if(length==15||length==26)                                //如果播报从15句或26句开始
  792.                                 delayms(200);                                                                //延时0.2秒
  793.                                 switch (length)
  794.                                 {                                                                                //x?
  795.                                           
  796.                         case 0:speak(25);length++;break;                         //报时音乐
  797.                                         case 1:speak(27); length++;break;                         //今天是
  798.                                         case 2:if(*str!=0) speak(*str+1); else speak(1);length++;break;                         //年十位   
  799.                                         case 3:if(*(str+1)!=0) speak(*(str+1)+1); else speak(1);length++;break;                         //年个位
  800.                                         case 4:speak(16);length++;break;                         //年           
  801.                         case 5:if(*(str+2)!=0) {speak(11);length++;} else length++; break;//月十位   为1时播报十,为0时不播报                                                                                                                                                                                                                                                                     
  802.                                     case 6:if(*(str+3)!=0) {speak(*(str+3)+1);length++;} else length++;break;                //月个位
  803.                                         case 7:speak(17);length++;break;                         //月
  804.                                         case 8:if(*(str+4)==1) length++; else if(*(str+4)>1) {speak(*(str+4)+1);length++;}else length+=2;break;//日十位  为1时跳到case 10播报十,大于1时播报数字并跳到case 10播报十,为0十时不播报跳到case 11                          
  805.                                           case 9:speak(11);length++;break;                         //十
  806.                                         case 10:if(*(str+5)!=0) {speak(*(str+5)+1);length++;} else length++;break;                         //日个位
  807.                                         case 11:speak(18);length++;break;                         //日
  808.                                         case 12:speak(19);length++;break;                         //星期
  809.                                         case 13:if(*(str+6)==7) length++; else  {speak(*(str+6)+1);length=16;}  break;        //
  810.                                         case 14:speak(18);length+=2;break;                         //日

  811.                                         case 15:speak(25);length++;break;                         //音乐1,3模式报
  812.                                         case 16:speak(22);length++;break;                         //现在时刻北京时间
  813.                     case 17:if(*(str+7)==1) length++; else if(*(str+7)>1) {speak(*(str+7)+1);length++;}else length+=2;break;  //
  814.                                         //时十位  为1时跳到case 17播报十,大于1时播报数字并跳到case 17播报十,为0十时不播报跳到case 15
  815.                                         case 18:speak(11);length++;break;                         //十
  816.                                         case 19:if(*(str+8)!=0) speak(*(str+8)+1);if(*(str+7)==0&&*(str+8)==0)speak(1);length++;break;                         //时个位
  817.                                         case 20:speak(13);length++;break;                         //点                ---此处修改speak(22为speak(13)
  818.         
  819.                                         case 21:
  820.                                                 if(*(str+9)==1)
  821.                                                 length++;
  822.                                                 else if(*(str+9)>1)
  823.                                                 {
  824.                                                         speak(*(str+9)+1);
  825.                                                         length++;
  826.                                                 }
  827.                                                 else if((*(str+9))==0&&(*(str+10))==0)
  828.                                                 {
  829.                                                         if((*(str+11))==0&&(*(str+12))==0)
  830.                                                         length=25;
  831.                                                         else
  832.                                                         length+=2;
  833.                                                 }
  834.                                                 else if((*(str+9))==0&&(*(str+10))!=0)
  835.                                                 {
  836.                                                         speak(1);length+=2;
  837.                                                 }

  838.                                                 break;
  839.                                         //分十位  为1时跳到case 10播报十,大于1时播报数字并跳到case 10播报十,为0十时不播报跳到case 19
  840.                                         case 22:speak(11);length++;break;                         //十
  841.                                         case 23:if(*(str+10)!=0)speak(*(str+10)+1); if(*(str+9)==0&&*(str+10)==0)speak(1);length++;break;                         //分个位
  842.                                         case 24:speak(14);length+=2;break;                         //分
  843.         
  844.                                         /*case 21:if(*(str+11)==1) length++;                                                         //不播报秒
  845.                                                   else if(*(str+11)>1) {speak(*(str+11)+1);length++;}
  846.                                                           else if(*(str+11)==0&&*(str+12)!=0){speak(1);length+=2;}
  847.                                                           else if(*(str+11)==0&&*(str+12)==0){length+=2;}break;
  848.                                         //秒十位  为1时跳到case 22播报十,大于1时播报数字并跳到case 22播报十,秒十位为0秒个位不为0时播报0跳到case 23,
  849.                                         //秒数据为0时不播报跳到case 23
  850.                                         //case 22:speak(11);length++;break;                         //十         
  851.                                         //case 23:if(*(str+12)!=0) speak(*(str+12)+1);if(*(str+11)==0&&*(str+12)==0)speak(1);length++;break;        //秒个位
  852.                                         //case 24:speak(15);length=26;break;                         //秒 ---此处修改speak(24)为speak(15)                                   */

  853.                                         case 25:speak(26);length++;break;                         //整 ---此处修改speak(21)为speak(26)
  854.         


  855.                                         case 26:speak(23);length++;break;                         //当前温度        ---- 此处修改speak(15)为speak(23)
  856.         
  857.                                         case 27:if(*(str+13)==1) length++; else if(*(str+13)>1) {speak(*(str+13)+1);length++;}else length+=2;break;//温度十位  为1时跳到case 10播报十,大于1时播报数字并跳到case 10播报十,为0十时不播报跳到case 11
  858.                                         case 28:speak(11);length++;break;                         //十
  859.                                         case 29:if(*(str+14)!=0) speak(*(str+14)+1);length++;break;                         //温度个位
  860.                                         case 30:speak(13);length++;break;                         //点        ----此处修改speak(22)为speak(13)
  861.                                         case 31:if(*(str+15)!=0) speak(*(str+15)+1);else speak(1);length++;break;                         //温度小数位
  862.                                         case 32:speak(20);length++;break;                         // 度----此处修改speak(16)为speak(20)
  863.                                          
  864.                                 }
  865.                                 yydelay(2);
  866.                         }
  867.                 }
  868.                 TR0=1;
  869.                 while(!yyxp_busy);        //等待播完
  870.                
  871.                 bs=0;
  872.                 delayms(100);
  873.         }
  874. }                                                
  875. /*****秒灯控制函数*****/
  876. void sec_led(void)
  877. {
  878.         if(set==0)
  879.         deng=h;                                //秒灯闪烁
  880.         if(set==1)
  881.         deng=1;                                //按下set键关秒灯

  882. }
  883.                                                                                     
  884. /*****定时器T0*****/
  885. void init()
  886. {
  887.         EA=1;
  888.         ET0=1;
  889.         TMOD=0x01;
  890.         TH0=0x3c;        //12M 50ms
  891.         TL0=0xb0;
  892.         TR0=1;



  893. }
  894.                                  
  895. /*****主函数*****/
  896. void main()
  897. {        
  898.         uc aa;
  899.         init();          //定时器初始化,启动定时器0

  900.   //  DS12C887_init()   //        初始化ds12c887,仅限初次使用,以后不必写入
  901. //        InitDis ();         //初始化7219
  902.          
  903.   

  904.         for(aa=0;aa<30;aa++)  //10毫秒读取一次温度,读取30次
  905.         {
  906.                 ds18b20();
  907.                 delayms(10);
  908.         }
  909.         fmq=0;                                   //蜂鸣器长鸣
  910.         delayms(200);
  911.         fmq=1;
  912.         delayms(100);
  913.          init_eeprom();                   //eeprom初始化
  914.         while(1)                           //循环执行
  915.         {
  916.             key();                           //按键扫描
  917.                  ds12c887();            //获取时间
  918.         ds18b20();                                  //获取温度
  919.             sec_led();
  920.                  display();                                 //显示
  921.              clock_dis();         //闹钟输出
  922.                 if((fen==0)&&(miao==0)&&set==0)                  // hour,min,sec
  923.                 {
  924.                         if(shi>=7&&shi<=21)         //7点到21点播报
  925.                         bs=1;
  926.                         if(bs==1)
  927.                         bofang(mode,disbuff);
  928.                 }
  929.                
  930.         /*        if(shi>=7&&shi<=21)         //白天亮度
  931.                 {
  932.                    WriteWord_1 (Intensity,11);
  933.                    WriteWord_2 (Intensity,10);
  934.                    WriteWord_3 (Intensity,11);
  935.                 }        
  936.                 else if(shi<7||shi>21)          //夜间节能模式  
  937.                 {
  938.                    WriteWord_1 (Intensity,0);
  939.                    WriteWord_2 (Intensity,0);
  940.                    WriteWord_3 (Intensity,0);
  941.                 }        */                                                        
  942.   }
  943. }
  944. void time() interrupt 1         //中断函数
  945. {
  946.    
  947.         TH0=0x3c;        //12M 50ms
  948.         TL0=0xb0;  //定时50毫秒(晶振12M)
  949.         ee++;                //记录溢出次数
  950.         if(ee==10)        //溢出达到10次
  951.         {
  952.                 h=~h;        //秒点每秒闪烁一次
  953.                 ee=0;
  954.                 if(bj==1)
  955.                 fmq=!fmq;           //蜂鸣器每秒短叫一次
  956.                
  957.         }
  958.          
  959. }
复制代码

Keil代码下载:
LED万年历.zip (257.94 KB, 下载次数: 43)

评分

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

查看全部评分

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

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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