找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4331|回复: 10
收起左侧

哪位大神帮我看一下这个单片机程序,按键不起作用

[复制链接]
ID:61140 发表于 2018-6-10 16:06 | 显示全部楼层 |阅读模式
这个程序是我从网上下载的,因为它是用普通51单片机的,但我用的STC12C5A60S2,所以改了延时能用了,但是现在按键调整时间不管用,有没有大神帮我看一下问题出在哪。
  1. #include<stc12c5a60s2.h>
  2. #include<intrins.h>
  3. #define SoundSpace 3/4   
  4. unsigned char sec,min,hour,day,month,year,cen,week;  //秒,分,小时,公历日期,月份,年份,世纪,星期
  5. unsigned char LunarMonth,LunarDay,LunarYear;         //阴历日期,月份,年份
  6. bit c_moon;                                          //大小月标志位                                          
  7. bit cenbit=0;                                          //世纪标志,为1,则表示20世纪,为0,则表示21世纪
  8. bit w;                                               //调时状态标志位
  9. unsigned char next;
  10. /**********定义LCD12864的数据线和相关函数*************/
  11. sbit LCD_RS=P1^1;        //模式位,低电平输入指令,高电平输入数据
  12. sbit LCD_RW=P1^0;        //读写位,低电平读,高电平写
  13. sbit LCD_E=P4^2;         //LCD12864使能位,低电平无效,高电平使能
  14. //sbit PSB=P1^4;
  15. #define Busy 0x80
  16. #define LCD_Data P0     //LCD12864的8位数据总线,单片机的P0端口
  17. void WriteDataLCD(unsigned char WDLCD);          //给LCD12864写数据
  18. void WriteCommandLCD(unsigned char WCLCD);       //给LCD12864写指令
  19. void LCDInit(void);                              //LCD12864初始化
  20. void LCDClear(void);                             //LCD12864清屏
  21. void CheckBusy(void);                            //忙检测
  22. void LCDSendWord(unsigned char *p);              //向LCD发送一个字符串
  23. void LCDTestWord(bit i,unsigned char word);
  24. void DisplaySec(void);                           //在LCD上显示秒钟
  25. void DisplayMin(void);                           //在LCD上显示分钟
  26. void DisplayHour(void);                          //在LCD上显示小时
  27. void DisplayDay(void);                           //在LCD上显示日期
  28. void DisplayYear(void);                          //在LCD上显示年份
  29. void DisplayMonth(void);                         //在LCD上显示月份
  30. void DisplayWeek(void);                          //在LCD上显示星期
  31. void Holidays(void);                             //在LCD上显示节日
  32. /*********定义时间芯片DS1302的数据线及相关函数***********/
  33. sbit DS1302_CLK=P2^5;         //DS1302的时钟信号线   
  34. sbit DS1302_IO=P2^6;          //DS1302的数据端口线
  35. sbit DS1302_RST=P2^7;         //DS1302的片选信号线
  36. void WriteDs1302byte(unsigned char temp);                    //给DS1302写一个字节
  37. void WriteDs1302(unsigned char address,unsigned char dat);  //给DS1302写入时间,先确定地址,再确定要写入的数据
  38. unsigned char ReadDs1302(unsigned char address);           //读取DS1302的数据
  39. void InitDS1302();
  40. /**********定义温度传感器DS18B20的数据线和相关函数*************/
  41. sbit DS18B20=P4^4;                        //DS18B20的数据线
  42. int temp;
  43. void DS18B20Init(void);                   //DS18B20初始化函数
  44. int GetTemp(void);
  45. void TempWriteByte(unsigned char dat);
  46. unsigned char TempRead(void);
  47. bit TempReadBit(void);   
  48. void delayb(unsigned int count);
  49. void TempChange(void);
  50. void Conversion(bit cen_m,unsigned char year,unsigned char month,unsigned char day);
  51. bit GetMoonDay(unsigned char month_p,unsigned int TableAddr);
  52. void DisplayShengXiao(void);
  53. void DelayMs(unsigned int a);
  54. void Delay(unsigned char num);
  55. /**********定义开关按键,及蜂鸣器的数据线************/
  56. sbit SetKey=P1^4;       //按键功能:设置
  57. sbit SureKey=P1^5;      //按键功能:确认
  58. sbit PlusKey=P1^6;      //按键功能:加
  59. sbit ReduceKey=P1^7;    //按键功能:减
  60. void Key(void);

  61. #define Fosc 24000000      //定义晶振频率24000000HZ
  62. #define jiepai 3/4         //定义普通音符演奏的长度分率,每4分音符间隔
  63. sbit Speaker=P3^0;         //定义输出管脚

  64. unsigned int code FreTab[12]={262,277,294,311,330,349,369,392,415,440,466,494};  //C调歌曲12个半音的频率
  65. unsigned char code PositTab[7]={0,2,4,5,7,9,11};                                   //1~7在频率表中的位置
  66. unsigned char code LengthTab[7]={1,2,4,8,16,32,64};                       
  67. unsigned char SoundTempTH0,SoundTempTL0;    //音符定时器初值暂存
  68. unsigned char SoundTempTH1,SoundTempTL1;    //音长定时器初值暂存
  69. void SpeakerDiDi(void);
  70. void SpeakerDiDi(void)
  71. {
  72. unsigned char i;  //整点报时延时
  73. for(i=0;i<3;i++)
  74. {
  75.   Speaker=0;
  76.   DelayMs(800);
  77.   Speaker=1;
  78.   DelayMs(800);
  79. }
  80. DelayMs(4000);
  81. for(i=0;i<3;i++)
  82. {
  83.   Speaker=0;
  84.   DelayMs(800);
  85.   Speaker=1;
  86.   DelayMs(800);
  87. }
  88. DelayMs(4000);
  89. for(i=0;i<2;i++)
  90. {
  91.   Speaker=0;
  92.   DelayMs(4000);
  93.   Speaker=1;
  94.   DelayMs(1000);
  95. }
  96. }
  97. void InitialSound(void)
  98. {
  99.     Speaker=1;
  100.     SoundTempTH1=(65535-(1/1200)*Fosc)/256;    //计算TL1应装入的初值     (10ms的初装值)
  101.     SoundTempTL1=(65535-(1/1200)*Fosc)%256;    //计算TH1应装入的初值
  102.     TH1=SoundTempTH1;                          //装入初值
  103.     TL1=SoundTempTL1;
  104.     TMOD|=0x11;                                //定时器1、2都工作在定时器模式,工作方式1
  105.     ET0=1;                                     //定时器0开中断
  106.     ET1=0;                                     //定时器1关中断
  107.     TR0=0;                                     //不启动定时器
  108.     TR1=0;                                     //不启动定时器
  109.     EA=1;                                      //开启CPU中断
  110. }  

  111. void Speakertimer(void) interrupt 1            //音符发生中断
  112. {
  113.     Speaker=!Speaker;                          //取反  
  114.     TH0=SoundTempTH0;                          //定时器0重新装初值
  115.     TL0=SoundTempTL0;
  116. }
  117. void PlayMusic(unsigned char *SoundName,unsigned char diaohao,unsigned shengjiang,unsigned int Speed)
  118.                                    //SoundName为演奏歌曲歌名 diaohao是指乐曲升多少个半音演奏
  119.            //shengjiang 1:降八度, 2:不升不降, 3:升八度; Speed歌曲演奏速度
  120. {
  121.     unsigned int NewFreTab[12];         //新的频率表
  122.     unsigned char i,j;
  123.     unsigned int Point,yinfuchang,yipai,LDiv1,LDiv2,sifenyifu,CurrentFre,TempCounter,SoundLength;
  124.              //Point 指针索引值  LDiv  音符演奏的长度(多少个10ms)   yipai 1分音符的长度(几个10ms)即一个节拍   
  125.              //sifenyifu 4分音符的长度   CurrentFre 查出对应音符的频率   SoundLength歌曲长度   TempCounter计算计数器初值
  126.     unsigned char yindiao,length,yinfu,shengban,gaodi,SLen,leixing,fudian;
  127.              //yindiao音调  length音长  yinfu音符  gaodi高低音  shengban是否升半   leixing音符类型(0普通1连音2顿音)
  128.     for(i=0;i<12;i++)                   // 根据调号及升降八度来生成新的频率表
  129.     {
  130.         j=i+diaohao;
  131.         if(j>11)
  132.         {
  133.             j=j-12;
  134.             NewFreTab[i]=FreTab[j]*2;            //频率翻倍速
  135.         }
  136.         else
  137.             NewFreTab[i]=FreTab[j];
  138.         if(shengjiang==1) NewFreTab[i]>>=2;      //如果是降调  则频率除以2
  139.         else if(shengjiang==3) NewFreTab[i]<<=2; //如果是升调 则频率翻倍速
  140.     }                                   
  141.     SoundLength=0;
  142.     while(SoundName[SoundLength]!=0x00)          //计算歌曲长度 以0X00结尾
  143.     {
  144.         SoundLength+=2;
  145.     }
  146.     Point=0;
  147.     yindiao=SoundName[Point];                    //第一个字节为音符音调
  148.     length=SoundName[Point+1];                   //第二个字节为音符时值
  149.     yipai=12000/Speed;                           //算出一个节拍的长度(单位是10ms)   
  150.     sifenyifu=yipai/4;                           //算出4分音符的长度
  151.     sifenyifu=sifenyifu-sifenyifu*jiepai;        //普通音最长间隔标准
  152.     TR0=0;
  153.     TR1=1;                                       //启动定时器1
  154.     while(Point<SoundLength)
  155.     {
  156.         yinfu=yindiao%10;                        //个位,1--7七个音符                                 
  157.         gaodi=yindiao/10%10;                     //十位,高低音
  158.         shengban=yindiao/100;                    //百位,是否升半
  159.         CurrentFre=NewFreTab[PositTab[yinfu-1]+shengban];     //查出对应音符的频率   
  160.         if(yinfu!=0)
  161.         {
  162.             if (gaodi==1) CurrentFre>>=2;         //低音,频率除以2
  163.             if (gaodi==3) CurrentFre<<=2;         //高音, 频率翻倍速
  164.             TempCounter=65536-(50000/CurrentFre)*10/(24000000/Fosc);//计算计数器初值
  165.             SoundTempTH0=TempCounter/256;
  166.             SoundTempTL0=TempCounter%256;
  167.             TH0=SoundTempTH0;
  168.             TL0=SoundTempTL0+12;                 //加12是对中断延时的补偿
  169.         }
  170.         SLen=LengthTab[length%10];               //算出是几分音符
  171.         leixing=length/10%10;                    //算出音符类型(0普通1连音2顿音)
  172.         fudian=length/100;
  173.         yinfuchang=yipai/SLen;                   //算出连音音符演奏的长度(多少个10ms)
  174.         if (fudian==1)
  175.             yinfuchang=yinfuchang+yinfuchang/2;
  176.         if(leixing!=1)   
  177.             if(leixing==0)                       //算出普通音符的演奏长度
  178.                 if (SLen<=4)   
  179.                     LDiv1=yinfuchang-sifenyifu;
  180.                 else
  181.                     LDiv1=yinfuchang*jiepai;
  182.             else
  183.                 LDiv1=yinfuchang/2;              //算出顿音的演奏长度
  184.         else
  185.             LDiv1=yinfuchang;
  186.         if(yinfu==0) LDiv1=0;
  187.             LDiv2=yinfuchang-LDiv1;              //算出不发音的长度
  188.          if (yinfu!=0)
  189.         {
  190.             TR0=1;
  191.             for(i=LDiv1;i>0;i--)                 //发规定长度的音
  192.             {
  193.                 while(TF1==0);
  194.                 TH1=SoundTempTH1;
  195.                 TL1=SoundTempTL1;
  196.                 TF1=0;
  197.             }
  198.         }
  199.         if(LDiv2!=0)
  200.         {
  201.             TR0=0; Speaker=0;
  202.             for(i=LDiv2;i>0;i--)                //音符间的间隔
  203.             {
  204.                 while(TF1==0);
  205.                 TH1=SoundTempTH1;
  206.                 TL1=SoundTempTL1;
  207.                 TF1=0;
  208.             }
  209.         }
  210.         Point+=2;
  211.         yindiao=SoundName[Point];
  212.         length=SoundName[Point+1];
  213.     }
  214.     Speaker=1;               
  215. }
  216. //**************************************************************************
  217. unsigned char code HappyBirthday[]=
  218. {//生日歌
  219.     0x19,0x03, 0x19,0x03, 0x1A,0x02, 0x19,0x02, 0x1F,0x02,
  220.     0x1B,0x01, 0x19,0x03, 0x19,0x03, 0x1A,0x02, 0x19,0x02,
  221.     0x20,0x02, 0x1F,0x01, 0x19,0x03, 0x19,0x03, 0x23,0x02,
  222.     0x21,0x02, 0x1F,0x02, 0x1B,0x0C, 0x1A,0x15, 0x22,0x03,
  223.     0x22,0x03, 0x21,0x02, 0x1F,0x02, 0x20,0x02, 0x1F,0x15,
  224.     0x00,0x00
  225. };
  226. unsigned char code Butterfly[]=
  227. {
  228. 0x17,0x03, 0x16,0x03, 0x17,0x01, 0x16,0x03, 0x17,0x03,                                
  229. 0x16,0x03, 0x15,0x01, 0x10,0x03, 0x15,0x03, 0x16,0x02,
  230.   0x16,0x0D, 0x17,0x03, 0x16,0x03, 0x15,0x03, 0x10,0x03,  
  231.    0x10,0x0E, 0x15,0x04, 0x0F,0x01, 0x17,0x03, 0x16,0x03,
  232.     0x17,0x01, 0x16,0x03, 0x17,0x03, 0x16,0x03, 0x15,0x01,
  233.     0x10,0x03, 0x15,0x03, 0x16,0x02, 0x16,0x0D, 0x17,0x03,
  234.     0x16,0x03, 0x15,0x03, 0x10,0x03, 0x15,0x03, 0x16,0x01,  
  235.     0x17,0x03, 0x16,0x03, 0x17,0x01, 0x16,0x03, 0x17,0x03,
  236.     0x16,0x03, 0x15,0x01, 0x10,0x03, 0x15,0x03, 0x16,0x02,
  237.     0x16,0x0D, 0x17,0x03, 0x16,0x03, 0x15,0x03, 0x10,0x03,  
  238.     0x10,0x0E, 0x15,0x04, 0x0F,0x01, 0x17,0x03, 0x19,0x03,  
  239.     0x19,0x01, 0x19,0x03, 0x1A,0x03, 0x19,0x03, 0x17,0x01,  
  240.     0x16,0x03, 0x16,0x03, 0x16,0x02, 0x16,0x0D, 0x17,0x03,
  241.     0x16,0x03, 0x15,0x03, 0x10,0x03, 0x10,0x0D, 0x15,0x00,
  242.     0x19,0x03, 0x19,0x03, 0x1A,0x03, 0x1F,0x03, 0x1B,0x03,  
  243.     0x1B,0x03, 0x1A,0x03, 0x17,0x0D, 0x16,0x03, 0x16,0x03,  
  244.     0x16,0x0D, 0x17,0x01, 0x17,0x03, 0x17,0x03, 0x19,0x03,  
  245.     0x1A,0x02, 0x1A,0x02, 0x10,0x03, 0x17,0x0D, 0x16,0x03,
  246.     0x16,0x01, 0x17,0x03, 0x19,0x03, 0x19,0x03, 0x17,0x03,
  247.     0x19,0x02, 0x1F,0x02, 0x1B,0x03, 0x1A,0x03, 0x1A,0x0E,
  248.     0x1B,0x04, 0x17,0x02, 0x1A,0x03, 0x1A,0x03, 0x1A,0x0E,   
  249.     0x1B,0x04, 0x1A,0x03, 0x19,0x03, 0x17,0x03, 0x16,0x03,
  250.     0x17,0x0D, 0x16,0x03, 0x17,0x03, 0x19,0x01, 0x19,0x03,
  251.     0x19,0x03, 0x1A,0x03, 0x1F,0x03, 0x1B,0x03, 0x1B,0x03,
  252.     0x1A,0x03, 0x17,0x0D, 0x16,0x03, 0x16,0x03, 0x16,0x03,
  253.     0x17,0x01, 0x17,0x03, 0x17,0x03, 0x19,0x03, 0x1A,0x02,
  254.     0x1A,0x02, 0x10,0x03, 0x17,0x0D, 0x16,0x03, 0x16,0x01,
  255.     0x17,0x03, 0x19,0x03, 0x19,0x03, 0x17,0x03, 0x19,0x03,
  256.     0x1F,0x02, 0x1B,0x03, 0x1A,0x03, 0x1A,0x0E, 0x1B,0x04,
  257.     0x17,0x02, 0x1A,0x03, 0x1A,0x03, 0x1A,0x0E, 0x1B,0x04,
  258.     0x17,0x16, 0x1A,0x03, 0x1A,0x03, 0x1A,0x0E, 0x1B,0x04,
  259.     0x1A,0x03, 0x19,0x03, 0x17,0x03, 0x16,0x03, 0x0F,0x02,
  260.     0x10,0x03, 0x15,0x00, 0x00,0x00
  261. };
  262. /*音乐歌谱每个音符由两个字节表示,第一个字节表示音高,第二个字节表示音长
  263. 音高由三位数字组成:个位是表示 1~7 这七个音符
  264. 十位是表示音符所在的音区:1-低音,2-中音,3-高音;百位表示这个音符是否要升半音: 0-不升,1-升半音。
  265. 音长最多由三位数字组成:
  266. 个位表示音符的时值,其对应关系是:
  267. 数值(n): |0 |1 |2 |3 | 4 | 5 | 6 |
  268. 几分音符: |1 |2 |4 |8 |16 |32 |64   
  269. 十位表示音符的演奏效果 (0-2): 0-普通,1-连音,2-顿音 百位是符点位: 0-无符点,1-有符点


  270. 阳历对应的阴历数据,每年三字节,
  271. 格式第一字节BIT7-4位表示闰月月份,为0,则无闰月,BIT3-0对应阴历第1-4月的大小,
  272. 第二字节BIT7-0对应阴历第5-12月大小,第三字节BIT7表示阴历第13月大小
  273. 月分对应的位为1,表示农历月大(30天)为0表示小(29天)
  274. 第三字节BIT6-5表示春节的公历月份,BIT4-0表示春节公历日期
  275. */
  276. code unsigned char YearCode[597]=
  277. {
  278.     0x04,0xAe,0x53,    //1901 0
  279.     0x0A,0x57,0x48,    //1902 3
  280.     0x55,0x26,0xBd,    //1903 6
  281.     0x0d,0x26,0x50,    //1904 9
  282.     0x0d,0x95,0x44,    //1905 12
  283.     0x46,0xAA,0xB9,    //1906 15
  284.     0x05,0x6A,0x4d,    //1907 18
  285.     0x09,0xAd,0x42,    //1908 21
  286.     0x24,0xAe,0xB6,    //1909
  287.     0x04,0xAe,0x4A,    //1910
  288.     0x6A,0x4d,0xBe,    //1911
  289.     0x0A,0x4d,0x52,    //1912
  290.     0x0d,0x25,0x46,    //1913
  291.     0x5d,0x52,0xBA,    //1914
  292.     0x0B,0x54,0x4e,    //1915
  293.     0x0d,0x6A,0x43,    //1916
  294.     0x29,0x6d,0x37,    //1917
  295.     0x09,0x5B,0x4B,    //1918
  296. 0x74,0x9B,0xC1,    //1919
  297. 0x04,0x97,0x54,    //1920
  298.     0x0A,0x4B,0x48,    //1921
  299.     0x5B,0x25,0xBC,    //1922
  300.     0x06,0xA5,0x50,    //1923
  301.     0x06,0xd4,0x45,    //1924
  302.     0x4A,0xdA,0xB8,    //1925
  303.     0x02,0xB6,0x4d,    //1926
  304.     0x09,0x57,0x42,    //1927
  305.     0x24,0x97,0xB7,    //1928
  306.     0x04,0x97,0x4A,    //1929
  307.     0x66,0x4B,0x3e,    //1930
  308.     0x0d,0x4A,0x51,    //1931
  309.     0x0e,0xA5,0x46,    //1932
  310.     0x56,0xd4,0xBA,    //1933
  311.     0x05,0xAd,0x4e,    //1934
  312.     0x02,0xB6,0x44,    //1935
  313.     0x39,0x37,0x38,    //1936
  314.     0x09,0x2e,0x4B,    //1937
  315.     0x7C,0x96,0xBf,    //1938
  316.     0x0C,0x95,0x53,    //1939
  317.     0x0d,0x4A,0x48,    //1940
  318.     0x6d,0xA5,0x3B,    //1941
  319.     0x0B,0x55,0x4f,    //1942
  320.     0x05,0x6A,0x45,    //1943
  321.     0x4A,0xAd,0xB9,    //1944
  322.     0x02,0x5d,0x4d,    //1945
  323.     0x09,0x2d,0x42,    //1946
  324.     0x2C,0x95,0xB6,    //1947
  325.     0x0A,0x95,0x4A,    //1948
  326.     0x7B,0x4A,0xBd,    //1949
  327.     0x06,0xCA,0x51,    //1950
  328.     0x0B,0x55,0x46,    //1951
  329.     0x55,0x5A,0xBB,    //1952
  330.     0x04,0xdA,0x4e,    //1953
  331.     0x0A,0x5B,0x43,    //1954
  332.     0x35,0x2B,0xB8,    //1955
  333.     0x05,0x2B,0x4C,    //1956
  334.     0x8A,0x95,0x3f,    //1957
  335.     0x0e,0x95,0x52,    //1958
  336.     0x06,0xAA,0x48,    //1959
  337.     0x7A,0xd5,0x3C,    //1960
  338.     0x0A,0xB5,0x4f,    //1961
  339.     0x04,0xB6,0x45,    //1962
  340.     0x4A,0x57,0x39,    //1963
  341.     0x0A,0x57,0x4d,    //1964
  342.     0x05,0x26,0x42,    //1965
  343.     0x3e,0x93,0x35,    //1966
  344.     0x0d,0x95,0x49,    //1967
  345.     0x75,0xAA,0xBe,    //1968
  346.     0x05,0x6A,0x51,    //1969
  347.     0x09,0x6d,0x46,    //1970
  348.     0x54,0xAe,0xBB,    //1971
  349.     0x04,0xAd,0x4f,    //1972
  350.     0x0A,0x4d,0x43,    //1973
  351.     0x4d,0x26,0xB7,    //1974
  352.     0x0d,0x25,0x4B,    //1975
  353.     0x8d,0x52,0xBf,    //1976
  354.     0x0B,0x54,0x52,    //1977
  355.     0x0B,0x6A,0x47,    //1978
  356.     0x69,0x6d,0x3C,    //1979
  357.     0x09,0x5B,0x50,    //1980
  358.     0x04,0x9B,0x45,    //1981
  359.     0x4A,0x4B,0xB9,    //1982
  360.     0x0A,0x4B,0x4d,    //1983
  361.     0xAB,0x25,0xC2,    //1984
  362.     0x06,0xA5,0x54,    //1985
  363.     0x06,0xd4,0x49,    //1986
  364.     0x6A,0xdA,0x3d,    //1987
  365.     0x0A,0xB6,0x51,    //1988
  366.     0x09,0x37,0x46,    //1989
  367.     0x54,0x97,0xBB,    //1990
  368.     0x04,0x97,0x4f,    //1991
  369.     0x06,0x4B,0x44,    //1992
  370.     0x36,0xA5,0x37,    //1993
  371.     0x0e,0xA5,0x4A,    //1994
  372.     0x86,0xB2,0xBf,    //1995
  373.     0x05,0xAC,0x53,    //1996
  374.     0x0A,0xB6,0x47,    //1997
  375.     0x59,0x36,0xBC,    //1998
  376.     0x09,0x2e,0x50,    //1999 294
  377.     0x0C,0x96,0x45,    //2000 297
  378.     0x4d,0x4A,0xB8,    //2001 300
  379.     0x0d,0x4A,0x4C,    //2002 303
  380.     0x0d,0xA5,0x41,    //2003 306
  381.     0x25,0xAA,0xB6,    //2004 309
  382.     0x05,0x6A,0x49,    //2005 312
  383.     0x7A,0xAd,0xBd,    //2006 315
  384.     0x02,0x5d,0x52,    //2007 318
  385.     0x09,0x2d,0x47,    //2008 321
  386.     0x5C,0x95,0xBA,    //2009 324
  387.     0x0A,0x95,0x4e,    //2010 327
  388.     0x0B,0x4A,0x43,    //2011
  389.     0x4B,0x55,0x37,    //2012
  390.     0x0A,0xd5,0x4A,    //2013
  391.     0x95,0x5A,0xBf,    //2014
  392.     0x04,0xBA,0x53,    //2015
  393.     0x0A,0x5B,0x48,    //2016
  394.     0x65,0x2B,0xBC,    //2017
  395.     0x05,0x2B,0x50,    //2018
  396.     0x0A,0x93,0x45,    //2019
  397.     0x47,0x4A,0xB9,    //2020
  398.     0x06,0xAA,0x4C,    //2021
  399.     0x0A,0xd5,0x41,    //2022
  400.     0x24,0xdA,0xB6,    //2023
  401.     0x04,0xB6,0x4A,    //2024
  402.     0x69,0x57,0x3d,    //2025
  403.     0x0A,0x4e,0x51,    //2026
  404.     0x0d,0x26,0x46,    //2027
  405.     0x5e,0x93,0x3A,    //2028
  406.     0x0d,0x53,0x4d,    //2029
  407.     0x05,0xAA,0x43,    //2030
  408.     0x36,0xB5,0x37,    //2031
  409.     0x09,0x6d,0x4B,    //2032
  410.     0xB4,0xAe,0xBf,    //2033
  411.     0x04,0xAd,0x53,    //2034
  412.     0x0A,0x4d,0x48,    //2035
  413.     0x6d,0x25,0xBC,    //2036
  414.     0x0d,0x25,0x4f,    //2037
  415.     0x0d,0x52,0x44,    //2038
  416.     0x5d,0xAA,0x38,    //2039
  417.     0x0B,0x5A,0x4C,    //2040
  418.     0x05,0x6d,0x41,    //2041
  419.     0x24,0xAd,0xB6,    //2042
  420.     0x04,0x9B,0x4A,    //2043
  421.     0x7A,0x4B,0xBe,    //2044
  422.     0x0A,0x4B,0x51,    //2045
  423.     0x0A,0xA5,0x46,    //2046
  424.     0x5B,0x52,0xBA,    //2047
  425.     0x06,0xd2,0x4e,    //2048
  426.     0x0A,0xdA,0x42,    //2049
  427.     0x35,0x5B,0x37,    //2050
  428.     0x09,0x37,0x4B,    //2051
  429.     0x84,0x97,0xC1,    //2052
  430.     0x04,0x97,0x53,    //2053
  431.     0x06,0x4B,0x48,    //2054
  432.     0x66,0xA5,0x3C,    //2055
  433.     0x0e,0xA5,0x4f,    //2056
  434.     0x06,0xB2,0x44,    //2057
  435.     0x4A,0xB6,0x38,    //2058
  436. 0x0A,0xAe,0x4C,    //2059
  437.     0x09,0x2e,0x42,    //2060
  438.     0x3C,0x97,0x35,    //2061
  439.     0x0C,0x96,0x49,    //2062
  440.     0x7d,0x4A,0xBd,    //2063
  441.     0x0d,0x4A,0x51,    //2064
  442. 0x0d,0xA5,0x45,    //2065
  443.     0x55,0xAA,0xBA,    //2066
  444.     0x05,0x6A,0x4e,    //2067
  445.     0x0A,0x6d,0x43,    //2068
  446.     0x45,0x2e,0xB7,    //2069
  447. 0x05,0x2d,0x4B,    //2070
  448.     0x8A,0x95,0xBf,    //2071
  449.     0x0A,0x95,0x53,    //2072
  450.     0x0B,0x4A,0x47,    //2073
  451.     0x6B,0x55,0x3B,    //2074
  452.     0x0A,0xd5,0x4f,    //2075
  453.     0x05,0x5A,0x45,    //2076
  454.     0x4A,0x5d,0x38,    //2077
  455.     0x0A,0x5B,0x4C,    //2078
  456.     0x05,0x2B,0x42,    //2079
  457.     0x3A,0x93,0xB6,    //2080
  458.     0x06,0x93,0x49,    //2081
  459.     0x77,0x29,0xBd,    //2082
  460.     0x06,0xAA,0x51,    //2083
  461.     0x0A,0xd5,0x46,    //2084
  462.     0x54,0xdA,0xBA,    //2085
  463.     0x04,0xB6,0x4e,    //2086
  464.     0x0A,0x57,0x43,    //2087
  465.     0x45,0x27,0x38,    //2088
  466.     0x0d,0x26,0x4A,    //2089
  467.     0x8e,0x93,0x3e,    //2090
  468.     0x0d,0x52,0x52,    //2091
  469.     0x0d,0xAA,0x47,    //2092
  470.     0x66,0xB5,0x3B,    //2093
  471.     0x05,0x6d,0x4f,    //2094
  472.     0x04,0xAe,0x45,    //2095
  473.     0x4A,0x4e,0xB9,    //2096
  474.     0x0A,0x4d,0x4C,    //2097
  475.     0x0d,0x15,0x41,    //2098
  476.     0x2d,0x92,0xB5,    //2099
  477. };

  478. /******************忙检测函数***************/
  479. void CheckBusy(void)
  480. {
  481. LCD_RS=0;
  482. LCD_RW=1;
  483. LCD_E=1;
  484. LCD_Data=0xff;
  485. while((LCD_Data&0x80)==0x80);
  486. LCD_E=0;
  487. }

  488. /**********************给LCD写入数据*****************/
  489. void WriteDataLCD(unsigned char WDLCD)
  490. {
  491.   CheckBusy();               //检测忙
  492.   LCD_RS = 1;                //RS为高电平,DB7----DB0为数据      
  493.   LCD_RW = 0;                //RW为低电平,E从高电平到低电平,则是把DB7----DB0的数据写到DR或者IR
  494.   LCD_E = 1;
  495.   LCD_Data = WDLCD;          //传送数据WDLCD
  496.   Delay(40);
  497.   LCD_E = 0;                 //E从 高电平 到 低电平
  498.   Delay(40);
  499. }

  500. /******************给LCD写入指令**********************/
  501. void WriteCommandLCD(unsigned char WCLCD) //BuysC为0时忽略忙检测
  502. {
  503.   CheckBusy();                //检测忙
  504.   LCD_RS = 0;                 //RS为低,DB7----DB0为指令
  505.   LCD_RW = 0;                 //RW为低,E从高电平到低电平,则是把DB7----DB0的数据写到DR或者IR
  506.   LCD_E = 1;
  507.   LCD_Data = WCLCD;           //传送数据
  508.   Delay(40);
  509.   LCD_E = 0;                  //E从 高电平到低电平
  510.      Delay(40);
  511. }

  512. /***************LCD初始化******************/

  513. void LCDInit(void)
  514. {
  515.   WriteCommandLCD(0x30);     //显示模式设置,开始要求每次检测忙信号
  516.   WriteCommandLCD(0x01);     //显示清屏
  517.   WriteCommandLCD(0x06);     // 显示光标移动设置
  518.   WriteCommandLCD(0x0C);     // 显示开,无游标,不反白
  519. }

  520. /********************清屏***************************/
  521. void LCDClear(void)
  522. {
  523.   WriteCommandLCD(0x01);     //显示清屏
  524.   WriteCommandLCD(0x34);     // 显示光标移动设置
  525.   WriteCommandLCD(0x30);     // 显示开及光标设置
  526. }

  527. /*****************************************/
  528. void LCDSendWord(unsigned char *p)         //向LCD发送一个字符串,
  529. {
  530. while(*p>0)                            //比如void LCDSendWord('你好');就是让LCD显示"你好"
  531. {
  532.   WriteDataLCD(*p);
  533.   p++;
  534. }
  535. }
  536.   
  537. /************写数据或者指令***************/
  538. void LCDTestWord(bit i,unsigned char word)
  539. {
  540. if(i==0)
  541. {
  542.   WriteCommandLCD(word);             //i=0;则写入指令
  543. }
  544. else
  545. {
  546.   WriteDataLCD(word);                //i=1;则写入数据  
  547. }
  548. }

  549. void DisplayYear(void)                 //往LCD上填写 年 数据
  550. {
  551. year=ReadDs1302(0x8d);            //从1302的0X8D处读出年数据
  552. LCDTestWord(0,0x81);               //写指令 0X81  在第一行第二个字符位置显示 年 数据
  553. LCDTestWord(1,(year/16)+0x30);     //写数据
  554. LCDTestWord(1,year%16+0x30);       //写数据
  555. LCDTestWord(0,0x82);                //写指令  第一行第三个字符位置
  556. LCDSendWord("年");                  //显示 年  LCD DDRAM第一行地址为80-87,第二行为90-97,第三行为88-8F,第四行为98-9F
  557. DisplayShengXiao();
  558. }

  559. void DisplayMonth(void)                //往LCD上填写  月 数据
  560. {
  561. month=ReadDs1302(0x89);           //从1302中读取月份数据
  562. LCDTestWord(0,0x83);               //写命令
  563. if(month/16!=0)
  564. {
  565.   LCDTestWord(1,(month/16)+0x30);//写数据
  566. }
  567. else
  568. {
  569.   LCDTestWord(1,0x20);            //写数据
  570. }
  571. LCDTestWord(1,month%16+0x30);       //写数据  
  572. LCDTestWord(0,0x84);                //写指令
  573. LCDSendWord("月");                  //显示 月
  574. DisplayShengXiao();
  575. }
  576.                            
  577. void DisplayWeek(void)                  //往LCD上填写  星期  数据
  578. {
  579. week=(ReadDs1302(0x8b))%16;             //从1302中读取星期数据  
  580. LCDTestWord(0,0x90);
  581. LCDSendWord("星期");
  582. LCDTestWord(0,0x92);
  583. if(week==7)    {LCDSendWord("日");}
  584. if(week==6)    {LCDSendWord("六");}
  585. if(week==5)    {LCDSendWord("五");}
  586. if(week==4)    {LCDSendWord("四");}
  587. if(week==3)    {LCDSendWord("三");}
  588. if(week==2)    {LCDSendWord("二");}
  589. if(week==1)    {LCDSendWord("一");} //显示星期一到星期日
  590. }   

  591. void DisplayDay(void)                   //往LCD上填写   日期  数据     
  592. {
  593. day=ReadDs1302(0x87);              //从1302中读取日期数据
  594. LCDTestWord(0,0x85);
  595. if(day/16!=0)   
  596.   { LCDTestWord(1,(day/16)+0x30); }         
  597. else
  598.      { LCDTestWord(1,0x20);}
  599. LCDTestWord(1,day%16+0x30);
  600. LCDTestWord(0,0x86);
  601. LCDSendWord("日☆");
  602. DisplayShengXiao();
  603. }

  604. void DisplayHour(void)                 //往LCD上填写  小时数据
  605. {
  606. hour=ReadDs1302(0x85);
  607. LCDTestWord(0,0x88);
  608. LCDTestWord(1,(hour/16)+0x30);
  609. LCDTestWord(1,hour%16+0x30);
  610. }

  611. void DisplayMin(void)                  //往LCD上填写分钟 数据   
  612. {
  613. min=ReadDs1302(0x83);
  614. LCDTestWord(0,0x89);
  615. LCDTestWord(1,0x3a);
  616. LCDTestWord(1,(min/16)+0x30);
  617. LCDTestWord(1,min%16+0x30);
  618. LCDTestWord(1,0x3a);
  619. }

  620. void DisplaySec(void)                 //住LCD上填写  秒钟   和温度  数据
  621. {
  622. unsigned char i=0;
  623. unsigned int a=0,b=0,c=0;
  624. sec=ReadDs1302(0x81);
  625. LCDTestWord(0,0x8b);
  626. LCDTestWord(1,(sec/16)+0x30);
  627. LCDTestWord(1,sec%16+0x30);
  628. }
  629. void DisplayTemp(void)
  630. {
  631. unsigned int i;
  632. unsigned char a,b,c;
  633. WriteCommandLCD(0x8c);
  634. LCDTestWord(0,0x8d);
  635. TempChange();
  636. i=GetTemp();
  637. a=i/100;
  638. LCDTestWord(1,a+0x30);
  639. b=i/10-a*10;
  640. LCDTestWord(1,b+0x30);
  641. LCDTestWord(1,0x2e);
  642. c=i-a*100-b*10;
  643. LCDTestWord(1,c+0x30);
  644. LCDSendWord("℃");
  645. }

  646. /***************************写入操作*********************/
  647. void WriteDs1302Byte(unsigned  char temp)        
  648. {
  649.     unsigned char i;
  650.     for (i=0;i<8;i++)               //循环8次 写入数据
  651.     {
  652.         DS1302_CLK=0;
  653.         DS1302_IO=temp&0x01;      //每次传输低字节
  654.         temp>>=1;                //右移一位
  655.         DS1302_CLK=1;
  656.    }
  657. }  

  658. /***********************************写入数据*****************************/
  659. void WriteDs1302( unsigned char address,unsigned char dat )     //先写地址,再写数据
  660. {
  661.   DS1302_RST=0;
  662. _nop_();
  663.   DS1302_CLK=0;
  664. _nop_();
  665.   DS1302_RST=1;
  666.     _nop_();                    //启动
  667.   WriteDs1302Byte(address); //发送地址
  668.   WriteDs1302Byte(dat);  //发送数据
  669.   DS1302_RST=0;            //恢复
  670. }

  671. /****************************************************************************/
  672. unsigned char ReadDs1302(unsigned char address)        //先送地址,再读数据
  673. {
  674.   unsigned char i,temp=0x00;
  675.   DS1302_RST=0;
  676. _nop_();
  677.   DS1302_CLK=0;
  678. _nop_();
  679.   DS1302_RST=1;
  680. _nop_();
  681.   WriteDs1302Byte(address);         //送地址函数
  682.   for (i=0;i<8;i++)               //循环8次 读取数据
  683.   {
  684.   DS1302_CLK=1;
  685.   _nop_();
  686.    if(DS1302_IO)
  687.    temp|=0x80;               //每次传输低字节
  688.   DS1302_CLK=0;
  689.   temp>>=1;               //右移一位
  690. }
  691.   DS1302_RST=0;
  692. _nop_();  
  693. DS1302_CLK=1;
  694. DS1302_IO=0;
  695. return (temp);              //返回
  696. }
  697. /*****************DS1302初始化********************/
  698. void InitDS1302()                        //DS1302中秒,分,时,日期,月份,星期,年的地址分别是0x80,0x82,0x84,0x86,0x88,0x8a,0x8c
  699. {                       /*                 //初始化写入的时间是2010年4月1日15点整,星期六
  700. WriteDs1302(0x8e,0x00);             //控制命令,WP位为0,允许写操作  控制位地址是0x8e
  701. DelayMs(5);                           
  702. WriteDs1302(0x8c,0x18);             //写入年份15年
  703. DelayMs(5);
  704. WriteDs1302(0x8a,0x04);             //写入星期7
  705. DelayMs(5);
  706. WriteDs1302(0x88,0x05);             //定入月分 8月
  707. DelayMs(5);
  708. WriteDs1302(0x86,0x31);             //写入日期 10日
  709. DelayMs(5);
  710. WriteDs1302(0x84,0x05);             //写入小时 0点
  711. DelayMs(5);
  712. WriteDs1302(0x82,0x09);             //写入分钟 38分
  713. DelayMs(5);
  714. WriteDs1302(0x80,0x12);              //写入秒  40秒
  715. DelayMs(5);                         */         
  716. WriteDs1302(0x8e,0x80);              //控制命令,WP为1,禁止写操作
  717. }

  718. /*************************************************************************/

  719. void delayb(unsigned int count)   //delay
  720. {
  721.     unsigned char i;
  722.     while(count)
  723.     {
  724.        i=200;
  725.        while(i>0)
  726.        i--;
  727.        count--;
  728.     }
  729. }

  730. void DS18B20Init(void)          //DS18B20初始化
  731. {
  732. unsigned int i;               
  733. DS18B20=0;
  734. i=103*8;
  735. while(i>0)i--;
  736. DS18B20=1;
  737. i=103;
  738. while(i>0)i--;
  739. }

  740. bit TempReadBit(void)          // 读一位
  741. {
  742. unsigned int i;
  743.     bit dat;
  744.     DS18B20=0;i++;             //小延时一下
  745.     DS18B20=1;i++;i++;
  746.     dat=DS18B20;
  747.     i=32;while(i>0)i--;
  748.     return (dat);
  749. }

  750. unsigned char TempRead(void)   //读一个字节
  751. {
  752. unsigned char i,j,dat;
  753.     dat=0;
  754.     for(i=1;i<=8;i++)
  755.     {
  756.      j=TempReadBit();
  757.      dat=(j<<7)|(dat>>1); //读出的数据最低位在最前面,这样刚好一个字节在DAT里
  758.     }
  759.     return(dat);             //将一个字节数据返回
  760. }

  761. void TempWriteByte(unsigned char dat)  
  762. {                           //写一个字节到DS18B20里
  763. unsigned int i;
  764.     unsigned char j;
  765.     bit testb;
  766.     for(j=1;j<=8;j++)
  767.     {
  768.      testb=dat&0x01;
  769.      dat=dat>>1;
  770.      if(testb)          // 写1部分
  771.      {
  772.          DS18B20=0;
  773.          i++;i++;
  774.          DS18B20=1;
  775.          i=32;while(i>0)i--;
  776.         }
  777.      else
  778.      {
  779.          DS18B20=0;       //写0部分
  780.          i=32;while(i>0)i--;
  781.          DS18B20=1;
  782.          i++;i++;
  783.         }
  784.     }
  785. }

  786. void TempChange(void)  //发送温度转换命令
  787. {
  788. DS18B20Init();             //初始化DS18B20
  789.     delayb(8);             //延时
  790.     TempWriteByte(0xcc);  // 跳过序列号命令
  791.     TempWriteByte(0x44);  //发送温度转换命令
  792. }

  793. int GetTemp()               //获得温度
  794. {
  795. float tt;
  796.     unsigned char a,b;
  797.     DS18B20Init();
  798.     delayb(1);
  799.     TempWriteByte(0xcc);  
  800.     TempWriteByte(0xbe);    //发送读取数据命令
  801.     a=TempRead();           //连续读两个字节数据
  802.     b=TempRead();
  803.     temp=b;
  804.     temp<<=8;            
  805.     temp=temp|a;            //两字节合成一个整型变量。
  806.     tt=temp*0.0625;         //得到真实十进制温度值,因为DS18B20 可以精确到0.0625度,所以读回数据的最低位代表的是0.0625度。                     
  807.     temp=tt*10+0.5;         //放大十倍,这样做的目的将小数点后第一位 也转换为可显示数字,同时进行一个四舍五入操作。                          
  808.     return temp;            //返回温度值
  809. }

  810. code unsigned char DayCode1[9]={0x00,0x1f,0x3b,0x5a,0x78,0x97,0xb5,0xd4,0xf3};
  811. code unsigned int DayCode2[3]={0x111,0x130,0x14e};                           
  812. //计算公历日离当年元旦的天数,为了减少运算,用了两个表   DayCode1[9],DayCode2[3]
  813. //如果公历月在九月或前,天数会少于0xff,用表DayCode1[9],在九月后,天数大于0xff,用表DayCode2[3]
  814. //如输入公历日为8月10日,则公历日离元旦天数为DayCode1[8-1]+10-1,如输入公历日为11月10日,则公历日离元旦天数为DayCode2[11-10]+10-1
  815. /*读取数据表中农历月的大月或小月,如果该月为大返回1,为小返回0*/
  816. bit GetMoonDay(unsigned char LunarMonth,unsigned int TableAddr)
  817. {
  818. unsigned char temp;
  819.     switch (LunarMonth)                       //LunarMonth指向农历月份
  820. {
  821.         case 1:
  822.   {
  823.    temp=YearCode[TableAddr]&0x08;    //1月,对应年份表里第一字节的BIT3位,如果是1,则月大,如果是0,则月小
  824.             if (temp==0) return(0);        //为0,月小  
  825.    else  return(1);                //为1,月大
  826.   }
  827.         case 2:
  828.   {
  829.    temp=YearCode[TableAddr]&0x04;    //2月,对应年份表里第一字节的BIT2位,如果是1,则月大,如果是0,则月小
  830.             if (temp==0) return(0);        //为0,月小
  831.    else  return(1);                //为1,月大
  832.   }
  833.         case 3:
  834.   {
  835.    temp=YearCode[TableAddr]&0x02;    //3月,对应第一字节的BIT1位,如果是1,则月大,如果是0,则月小
  836.             if (temp==0) return(0);        //为0,月小
  837.    else  return(1);                //为1,月大
  838.   }
  839.         case 4:
  840.   {
  841.    temp=YearCode[TableAddr]&0x01;    //1月,对应第一字节的BIT0位,如果是1,则月大,如果是0,则月小
  842.             if (temp==0) return(0);
  843.    else return(1);
  844.   }
  845.         case 5:
  846.   {
  847.    temp=YearCode[TableAddr+1]&0x80;  //5月,对应第二字节的BIT7位,如果是1,则月大,如果是0,则月小
  848.             if (temp==0)  return(0);
  849.    else  return(1);
  850.   }
  851.         case 6:
  852.   {
  853.    temp=YearCode[TableAddr+1]&0x40;  //6月,对应第二字节的BIT6位,如果是1,则月大,如果是0,则月小
  854.             if (temp==0) return(0);
  855.    else  return(1);
  856.   }
  857.         case 7:
  858.   {
  859.    temp=YearCode[TableAddr+1]&0x20;  //7月,对应第二字节的BIT5位,如果是1,则月大,如果是0,则月小
  860.             if (temp==0) return(0);
  861.    else  return(1);
  862.   }
  863.         case 8:
  864.   {
  865.    temp=YearCode[TableAddr+1]&0x10;  //8月,对应第二字节的BIT4位,如果是1,则月大,如果是0,则月小
  866.             if (temp==0) return(0);
  867.    else  return(1);
  868.   }
  869.         case 9:
  870.   {
  871.    temp=YearCode[TableAddr+1]&0x08;  //9月,对应第二字节的BIT3位,如果是1,则月大,如果是0,则月小
  872.             if (temp==0) return(0);
  873.    else  return(1);
  874.   }
  875.         case 10:
  876.   {
  877.    temp=YearCode[TableAddr+1]&0x04;  //10月,对应第二字节的BIT2位,如果是1,则月大,如果是0,则月小
  878.             if (temp==0) return(0);
  879.    else  return(1);
  880.   }
  881.         case 11:
  882.   {
  883.    temp=YearCode[TableAddr+1]&0x02;  //11月,对应第二字节的BIT1位,如果是1,则月大,如果是0,则月小
  884.             if (temp==0) return(0);
  885.    else  return(1);
  886.   }
  887.         case 12:
  888.   {
  889.    temp=YearCode[TableAddr+1]&0x01;  //12月,对应第二字节的BIT0位,如果是1,则月大,如果是0,则月小
  890.             if (temp==0) return(0);
  891.    else  return(1);
  892.   }
  893.         case 13:
  894.   {
  895.    temp=YearCode[TableAddr+2]&0x80;  //13月,对应第三字节的BIT7位,如果是1,则月大,如果是0,则月小
  896.             if (temp==0) return(0);
  897.    else  return(1);
  898.   }
  899.     }
  900.         return        0xff;
  901. }

  902. void Conversion(bit cenbit,unsigned char year,unsigned char month,unsigned char day)
  903.                              //cenbit=0为21世纪,cenbit=1为20世纪,输入输出数据均为BCD数据
  904. {                        
  905.     unsigned char temp1,temp2,temp3,MonthP;//temp3,temp4分别表示春节距元旦的天数,公历日离元旦的天数
  906.     unsigned int temp4,TableAddr;
  907.     bit flag2,flag_y;
  908.     temp1=year/16;           //BCD->hex 先把数据转换为十六进制  高位
  909.     temp2=year%16;           //低位
  910.     year=temp1*10+temp2;     //把 年 数据 转换成16进制
  911.     temp1=month/16;          //月份 高位
  912.     temp2=month%16;          //月份 低位
  913.     month=temp1*10+temp2;    //把 月 数据 转换成16进制
  914.     temp1=day/16;            //日期 高位
  915.     temp2=day%16;            //日期 低位
  916.     day=temp1*10+temp2;      //把 日 数据 转换成16进制
  917.     if(cenbit==0)                           //如果是21世纪
  918. {                  
  919.         TableAddr=(year+0x64-1)*0x03;       //定位数据表地址  year对应的年份表中的地址是(year+99)*3 如2010年 其地址是327
  920.   LCDTestWord(0,0x80);
  921.   LCDSendWord("20");
  922.     }
  923.     else                                    //如果是20世纪
  924. {
  925.         TableAddr=(year-1)*0x03;            //定位数据表地址  year对应的年份表中的地址是(year-1)*3  如1901年 其地址是3
  926.   LCDTestWord(0,0x80);
  927.   LCDSendWord("19");
  928.     }
  929.     temp1=YearCode[TableAddr+2]&0x60;       //取当年春节所在的公历月份   年份表中第三字节BIT6-5表示春节的公历月份
  930.     temp1=_cror_(temp1,5);                  //循环右移5位,得到 春节所在的公历月份
  931.     temp2=YearCode[TableAddr+2]&0x1f;       //取当年春节所在的公历日    年份表中第三字节BIT4-0表示当年春节所在的公历日
  932.     if(temp1==0x01)                         // 计算当年春年离当年元旦的天数,春节只会在公历1月或2月   
  933.         temp3=temp2-1;                      //假如春节在公历1月,则元旦离春节的天数为  temp2-1 天
  934.     else
  935.         temp3=temp2+0x1f-1;                 //假如春节在公历2月,则无理离春节的天数为  temp2+0x1f-1 天
  936.     if (month<10)
  937.         temp4=DayCode1[month-1]+day-1;      //0到8月某日距元旦的天数
  938.     else
  939.         temp4=DayCode2[month-10]+day-1;     //9月开始的某一天距元旦的天数
  940.     if ((month>0x02)&&(year%0x04==0))       //如果公历月大于2月并且该年的2月为闰月,天数加1
  941.         temp4+=1;
  942.                                          //计算机出公历日距元旦的天数和春节距元旦的天数,则是为了比较公历日是在春节前还是春节后
  943.                                          //如果temp3>temp4  则 公历日在春节之前
  944.     if (temp4>=temp3)                       //公历日在春节后或就是春节当日使用下面代码进行运算
  945. {   
  946.         temp4-=temp3;                       //公历日离春节的天数  因为公历日在春节后  所以为temp4-temp3
  947.         month=0x01;
  948.         MonthP=0x01;                        //LunarMonth为月份指向,公历日在春节前或就是春节当日LunarMonth指向首月
  949.         flag2=GetMoonDay(MonthP,TableAddr); //检查该农历月为大小还是小月,大月返回1,小月返回0
  950.         flag_y=0;
  951.         if(flag2==0)                            //GetMoonDay()函数返回的是0
  952.    {temp1=0x1d;}                       //小月29天
  953.         else                                    //GetMoonDay()函数返回的是1
  954.    {temp1=0x1e;}                       //大月30天
  955.         temp2=YearCode[TableAddr]&0xf0;         //年份数据表中第1字节BIT7-4为闰月,为0则这年无闰月,如为1,表示有闰月
  956.         temp2=_cror_(temp2,4);                  //从数据表中取该年的闰月月份,如为0,则该年无闰月  BIT3-0表示阴历1到4月的大小 1为大 0 为小
  957.         while(temp4>=temp1)
  958.   {
  959.             temp4-=temp1;
  960.             MonthP+=1;
  961.             if(month==temp2)
  962.    {
  963.              flag_y=~flag_y;
  964.              if(flag_y==0)  {month+=1;}
  965.             }
  966.             else
  967.       {
  968.     month+=1;
  969.    }
  970.             flag2=GetMoonDay(MonthP,TableAddr);
  971.             if(flag2==0)
  972.    {
  973.     temp1=0x1d;
  974.    }
  975.             else
  976.    {
  977.     temp1=0x1e;
  978.    }
  979.         }
  980.         day=temp4+1;
  981.     }
  982.     else
  983. {  //公历日在春节前使用下面代码进行运算
  984.         temp3-=temp4;                          //公历日离春节的天数  因为公历日在春节前  所以为temp3-temp4
  985.         if (year==0x00){year=0x63;cenbit=1;}
  986.         else year-=1;
  987.         TableAddr-=0x03;
  988.         month=0x0c;
  989.         temp2=YearCode[TableAddr]&0xf0;    //格式第一字节BIT7-4位表示闰月月份,为0,则无闰月,BIT3-0对应阴历第1-4月的大小,
  990.         temp2=_cror_(temp2,4);
  991.         if (temp2==0)MonthP=0x0c;
  992.         else MonthP=0x0d; //
  993.         /* MonthP为月份指向,如果当年有闰月,一年有十三个月,月指向13,无闰月指向12*/
  994.         flag_y=0;
  995.         flag2=GetMoonDay(MonthP,TableAddr);
  996.         if(flag2==0)temp1=0x1d;
  997.         else temp1=0x1e;
  998.         while(temp3>temp1)
  999.   {
  1000.             temp3-=temp1;
  1001.             MonthP-=1;
  1002.             if(flag_y==0)month-=1;
  1003.             if(month==temp2)flag_y=~flag_y;
  1004.             flag2=GetMoonDay(MonthP,TableAddr);
  1005.             if(flag2==0)temp1=0x1d;
  1006.             else temp1=0x1e;
  1007.          }
  1008.         day=temp1-temp3+1;
  1009.     }
  1010.     c_moon=cenbit;               
  1011.     temp1=year/10;
  1012.     temp1=_crol_(temp1,4);
  1013.     temp2=year%10;
  1014.     LunarYear=temp1|temp2;

  1015.     temp1=month/10;
  1016.     temp1=_crol_(temp1,4);
  1017.     temp2=month%10;
  1018.     LunarMonth=temp1|temp2;

  1019.     temp1=day/10;
  1020.     temp1=_crol_(temp1,4);
  1021.     temp2=day%10;
  1022.     LunarDay=temp1|temp2;
  1023. }

  1024. void DisplayShengXiao(void)
  1025. {
  1026. unsigned char LunarYearD,ReYear;        //农历年份的十进制数  和取模后的余数
  1027. if(cen==0x19)  {cenbit=1;}
  1028. if(cen==0x20)  {cenbit=0;}
  1029.   Conversion(cenbit,year,month,day);       //将公历日期转换成农历
  1030. LCDTestWord(0,0x94);                     //显示在LCD的0X94位置上
  1031. LCDTestWord(1,LunarYear/16+0x30);        //农历年十位
  1032.   LCDTestWord(1,LunarYear%16+0x30);        //农历年个位
  1033.   LCDTestWord(1,'-');                      //用-隔开
  1034.   LCDTestWord(1,LunarMonth/16+0x30);       //农历月十位
  1035.   LCDTestWord(1,LunarMonth%16+0x30);       //农历月个位  
  1036.   LCDTestWord(1,'-');
  1037.   LCDTestWord(1,LunarDay/16+0x30);         //农历日十位
  1038.   LCDTestWord(1,LunarDay%16+0x30);         //农历日个位
  1039.   LunarYearD=(LunarYear/16)*10+LunarYear%16;        //农历年转换成10进制数
  1040.   ReYear=LunarYearD%12;                             //农历年模12,取余运算
  1041.   switch(ReYear)
  1042.   {
  1043.   case 0: LCDTestWord(0,0x9D);LCDSendWord("★龙年");break;   //余0即整除 农历 龙年
  1044.   case 1: LCDTestWord(0,0x9D);LCDSendWord("★蛇年");break;   //蛇年
  1045.   case 2: LCDTestWord(0,0x9D);LCDSendWord("★马年");break;
  1046.   case 3: LCDTestWord(0,0x9D);LCDSendWord("★羊年");break;
  1047.   case 4: LCDTestWord(0,0x9D);LCDSendWord("★猴年");break;
  1048.   case 5: LCDTestWord(0,0x9D);LCDSendWord("★鸡年");break;
  1049.   case 6: LCDTestWord(0,0x9D);LCDSendWord("★狗年");break;
  1050.   case 7: LCDTestWord(0,0x9D);LCDSendWord("★猪年");break;
  1051.   case 8: LCDTestWord(0,0x9D);LCDSendWord("★鼠年");break;
  1052.   case 9: LCDTestWord(0,0x9D);LCDSendWord("★牛年");break;
  1053.   case 10:LCDTestWord(0,0x9D);LCDSendWord("★虎年");break;
  1054.   case 11:LCDTestWord(0,0x9D);LCDSendWord("★兔年");break;
  1055. }
  1056. }
  1057. /***************节假日提示********************/

  1058. void Holidays(void)
  1059. {
  1060. LCDTestWord(0,0x98);

  1061.      if(LunarMonth==0x01 && LunarDay==0x01)       {LCDSendWord("春节快乐!");}
  1062. else if(LunarMonth==0x01 && LunarDay==0x15)       {LCDSendWord("元宵节快乐");}
  1063. else if(LunarMonth==0x02 && LunarDay==0x26)       {LCDSendWord("俺村过会了");}
  1064. else if(LunarMonth==0x04 && LunarDay==0x01)       {LCDSendWord("小蛋蛋生日");}
  1065. else if(LunarMonth==0x05 && LunarDay==0x05)       {LCDSendWord("端午节快乐");}
  1066. else if(LunarMonth==0x05 && LunarDay==0x12)       {LCDSendWord("张宇鹏生日");}
  1067. else if(LunarMonth==0x07 && LunarDay==0x07)       {LCDSendWord("中国情人节");}
  1068. else if(LunarMonth==0x08 && LunarDay==0x15)       {LCDSendWord("中秋节快乐");}
  1069. else if(LunarMonth==0x09 && LunarDay==0x01)       {LCDSendWord("自信就成功");}
  1070. else if(LunarMonth==0x09 && LunarDay==0x09)       {LCDSendWord("今天重阳节");}
  1071. else if(LunarMonth==0x10 && LunarDay==0x01)       {LCDSendWord("今天要祭祖");}
  1072. else if(LunarMonth==0x12 && LunarDay==0x08)       {LCDSendWord("今天腊八节");}
  1073. else if(LunarMonth==0x12 && LunarDay==0x15)       {LCDSendWord("过小年啦!");}
  1074. else if(LunarMonth==0x12 && LunarDay==0x29)       {LCDSendWord("腊月二十九");}
  1075. else if(LunarMonth==0x12 && LunarDay==0x30)       {LCDSendWord("除夕夜到了");}   
  1076. //以上是农历节日,以下是公历节日
  1077. else if(month==0x01 && day==0x01)  {LCDSendWord("元旦节快乐");}   
  1078. else if(month==0x02 && day==0x02)  {LCDSendWord("世界湿地日");}
  1079. else if(month==0x02 && day==0x10)  {LCDSendWord("世界气象日");}
  1080. else if(month==0x03 && day==0x08)  {LCDSendWord("国际妇女节");}
  1081. else if(month==0x03 && day==0x12)  {LCDSendWord("中国植树节");}
  1082. else if(month==0x03 && day==0x15)  {LCDSendWord("消费者权益");}
  1083. else if(month==0x03 && day==0x22)  {LCDSendWord("世界水日了");}     
  1084. else if(month==0x04 && day==0x01)  {LCDSendWord("愚人节快乐");}
  1085. else if(month==0x04 && day==0x05)  {LCDSendWord("中国清明节");}
  1086. else if(month==0x04 && day==0x22)  {LCDSendWord("世界地球日");}
  1087. else if(month==0x05 && day==0x01)  {LCDSendWord("国际劳动节");}
  1088. else if(month==0x05 && day==0x04)  {LCDSendWord("中国青年节");}
  1089. else if(month==0x05 && day==0x12)  {LCDSendWord("世界护士节");}
  1090. else if(month==0x06 && day==0x01)  {LCDSendWord("国际儿童节");}
  1091. else if(month==0x06 && day==0x05)  {LCDSendWord("世界环境日");}
  1092. else if(month==0x06 && day==0x06)  {LCDSendWord("国际爱眼日");}
  1093. else if(month==0x06 && day==0x25)  {LCDSendWord("世界土地日");}
  1094. else if(month==0x06 && day==0x26)  {LCDSendWord("国际禁毒日");}   
  1095. else if(month==0x07 && day==0x01)  {LCDSendWord("香港回归日");}   
  1096. else if(month==0x08 && day==0x01)  {LCDSendWord("中国建军节");}
  1097. else if(month==0x09 && day==0x10)  {LCDSendWord("中国教师节");}
  1098. else if(month==0x09 && day==0x18)  {LCDSendWord("九一八事变");}
  1099. else if(month==0x10 && day==0x01)  {LCDSendWord("今日国庆节");}
  1100. else if(month==0x10 && day==0x04)  {LCDSendWord("世界动物日");}
  1101. else if(month==0x10 && day==0x09)  {LCDSendWord("世界邮政日");}
  1102. else if(month==0x10 && day==0x10)  {LCDSendWord("辛亥革命日");}  
  1103. else if(month==0x12 && day==0x20)  {LCDSendWord("澳门回归日");}
  1104. else if(month==0x12 && day==0x24)  {LCDSendWord("美好的回忆");}
  1105. else if(month==0x12 && day==0x25)  {LCDSendWord("++圣诞节++");}
  1106.    else    LCDSendWord("努力赚钱");  


  1107. /*                else    if (hour==0x04 && min==0x25)    {LCDSendWord("现在是凌晨"); }
  1108.                 else        if (hour>= 0x06 && min<  0x08 ){LCDSendWord("现在是早晨"); }
  1109.                 else        if (hour>= 0x08 && min<  0x12 ){LCDSendWord("现在是上午"); }
  1110.                 else        if (hour== 0x12 )              {LCDSendWord("现在是中午"); }
  1111.                 else        if (hour>= 0x13 && min<  0x18 ){LCDSendWord("现在是下午"); }
  1112.                 else        if (hour>= 0x18 && min<  0x22 ){LCDSendWord("现在是晚上"); }
  1113.                 else        if (hour>= 0x22 && min<= 0x23 ){LCDSendWord("☆现在是夜里"); }
  1114.                 else        if (hour>= 0x00 && min<  0x04 ){LCDSendWord("现在已深夜"); }        */
  1115.                         }        

  1116.   
  1117. void UpDate(void)
  1118. {
  1119. DisplayYear();     //显示年
  1120. DisplayMonth();    //显示月
  1121. DisplayDay();    //显示日
  1122. DisplayWeek();    //显示星期
  1123. DisplayHour();    //显示时
  1124. DisplayMin();    //显示分
  1125. DisplaySec();    //显示秒
  1126. DisplayShengXiao();
  1127. }

  1128. void SetTime(unsigned char count)
  1129. {
  1130. unsigned char address,item;
  1131. unsigned char max,mini;
  1132. LCDTestWord(0,0x98);
  1133. LCDSendWord("调整");
  1134. if(count==6)  {LCDSendWord("秒钟      ");address=0x81; max=59;mini=0;}
  1135. if(count==5)  {LCDSendWord("分钟      ");address=0x83; max=59;mini=0;}
  1136. if(count==4)  {LCDSendWord("小时      ");address=0x85; max=23;mini=0;}
  1137. if(count==3)  {LCDSendWord("星期      ");address=0x8b; max=7;mini=1;}
  1138. if(count==2)  {LCDSendWord("日期      ");address=0x87; max=31; mini=1;}
  1139. if(count==1)  {LCDSendWord("月份      ");address=0x89; max=12;mini=1;}
  1140. if(count==0)  {LCDSendWord("年份      ");address=0x8d; max=99;mini=0;}
  1141. item=ReadDs1302(address);//读取DS1302某地址上的数值赋给item  
  1142. item=(item/16)*10+item%16;
  1143. if(PlusKey==0)       //PlusKey-加
  1144.   item++;          //数加 1
  1145. if(ReduceKey==0)     //ReduceKey-减
  1146.   item--;          //数减 1
  1147. if(item>max)
  1148.   item=mini;       //查看数值有效范围  
  1149. if(item<mini)
  1150.   item=max;
  1151. WriteDs1302(0x8e,0x00);
  1152. item=(item/10)*16+item%10;
  1153. WriteDs1302(address-1,item); //将调整好的item值写入DS1302
  1154.     UpDate();
  1155. }

  1156. void Key(void)
  1157. {

  1158. if (SetKey==0)           // 设置时间
  1159. {
  1160.     DelayMs(80);         //按键消抖   
  1161.   if(SetKey==0&&w==1)  //当是正常状态时就进入调时状态
  1162.   {
  1163.    w=1;          //进入调时   
  1164.    SetTime(next);   //调整   
  1165.   }
  1166.   if(SetKey==0&&w==1)  //当是调时状态 本键用于调整下一项
  1167.   {
  1168.    next++;
  1169.    if(next>=7)   {next= 0;}
  1170.    SetTime(next);   //调整   
  1171.   }
  1172.      while(SetKey==0);    //等待键松开
  1173. }
  1174. if(SureKey==0)           // 当在调时状态时就退出调时
  1175.     {
  1176.   DelayMs(80);         //按键消抖
  1177.   if(SureKey==0&&w==1)
  1178.   {
  1179.    w=0;next=0;
  1180.    Holidays();
  1181.   }
  1182.   while(SureKey==0);   //等待键松开
  1183. }
  1184. if (PlusKey==0)          //加调整
  1185. {
  1186.      DelayMs(80);         //按键消抖
  1187.      if(PlusKey==0&&w==1)
  1188.   {   
  1189.    SetTime(next);   //调整
  1190.   }
  1191.   while(PlusKey==0);       //等待键松开
  1192. }

  1193. if (ReduceKey==0)        //减调整
  1194. {        
  1195.      DelayMs(80);         //按键消抖
  1196.      if(ReduceKey==0&&w==1)
  1197.   {   
  1198.    SetTime(next);   //调整
  1199.   }  
  1200.   while(ReduceKey==0);     //等待键松开
  1201. }  
  1202. }

  1203. void DelayMs(unsigned int a)        //延时 1MS/次
  1204. {
  1205. unsigned char i;
  1206. while(--a!=0)
  1207. {
  1208.   for(i=0;i<125;i++)
  1209.   ;
  1210. }
  1211. }

  1212. void Delay(unsigned char num)               
  1213. {
  1214. while(num--)
  1215. ;
  1216. }

  1217. void main()
  1218. {
  1219.         P4SW = 0xff; //启动P4接口
  1220.         P4M0 = 0xff;   //接口设置为强推
  1221. SureKey=1;
  1222. PlusKey=1;
  1223. ReduceKey=1;
  1224. // PSB=1;
  1225. next=0;
  1226. LCDInit();
  1227. LCDClear();
  1228. InitDS1302();
  1229. InitialSound();
  1230. while(1)                        
  1231. {
  1232.   DisplayYear();     //显示年
  1233.   DisplayMonth();    //显示月
  1234.   DisplayDay();    //显示日
  1235.   DisplayWeek();    //显示星期
  1236.   DisplayHour();    //显示时
  1237.   DisplayMin();    //显示分
  1238.   DisplaySec();    //显示秒
  1239.   Holidays();        //显示节日
  1240.   DisplayTemp();     //显示温度  
  1241.   Key();
  1242.   if(min==0&&sec==0)
  1243.   {
  1244.    if(LunarMonth==9&&LunarDay==1)
  1245.    {
  1246.    PlayMusic(HappyBirthday,0,3,300);
  1247.    }
  1248.    else
  1249.    {
  1250.     SpeakerDiDi();
  1251.    }
  1252.   }
  1253. }
  1254. }
复制代码


回复

使用道具 举报

ID:329253 发表于 2018-6-10 17:02 来自手机 | 显示全部楼层
你这代码太长了,应该把他删减一下,再发出来
回复

使用道具 举报

ID:349102 发表于 2018-6-10 23:17 来自手机 | 显示全部楼层
等我先看完程序先
回复

使用道具 举报

ID:330198 发表于 2018-6-11 12:59 | 显示全部楼层
360截图20180611125241835.jpg
你晶振频率改没改啊
回复

使用道具 举报

ID:61140 发表于 2018-6-12 20:07 | 显示全部楼层
zhanghyg 发表于 2018-6-11 12:59
你晶振频率改没改啊

这个改不改无所谓,反正我也不听歌,走时精确就行了,现在主要是按键不起作用,求教大神了
回复

使用道具 举报

ID:61140 发表于 2018-6-15 12:10 | 显示全部楼层
有没有大神帮我看一下啊,只是按键部分只要能管用就行了,
回复

使用道具 举报

ID:61140 发表于 2019-1-7 18:42 | 显示全部楼层

有没有大神帮我看一下啊,只是按键部分只要能管用就行了,
回复

使用道具 举报

ID:280876 发表于 2019-1-8 10:14 | 显示全部楼层
太长了,没时间看
回复

使用道具 举报

ID:453974 发表于 2019-1-8 12:33 | 显示全部楼层
按键延时检测有点长,你把它减小一点然后再看看
回复

使用道具 举报

ID:386762 发表于 2019-1-8 17:09 | 显示全部楼层
先看看按键检测电路是否有效,在看看按键消抖的时间是否太差导致检测不到(可以试试长按按键试试是否按键有效)
回复

使用道具 举报

ID:61140 发表于 2019-5-26 16:16 | 显示全部楼层
皮条01 发表于 2018-6-10 23:17
等我先看完程序先

大神帮我一下可以么
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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