標(biāo)題: 12864-ds1302-ds18b20-單片機(jī)萬年歷程序 [打印本頁]

作者: 51hei人人    時(shí)間: 2016-3-12 21:21
標(biāo)題: 12864-ds1302-ds18b20-單片機(jī)萬年歷程序




  1. #include<reg52.h>
  2. #include<intrins.h>
  3. #define SoundSpace 3/4   
  4. unsigned char sec,min,hour,day,month,year,year1,cen,week;  //秒,分,小時(shí),公歷日期,月份,年份,世紀(jì),星期
  5. unsigned char LunarMonth,LunarDay,LunarYear;         //陰歷日期,月份,年份
  6. bit c_moon;                                          //大小月標(biāo)志位                                          
  7. bit cenbit=0;                                          //世紀(jì)標(biāo)志,為1,則表示20世紀(jì),為0,則表示21世紀(jì)
  8. bit w;                                               //調(diào)時(shí)狀態(tài)標(biāo)志位
  9. unsigned char next;
  10. /**********定義LCD12864的數(shù)據(jù)線和相關(guān)函數(shù)*************/
  11. sbit LCD_RS=P2^6;        //模式位,低電平輸入指令,高電平輸入數(shù)據(jù)
  12. sbit LCD_RW=P2^5;        //讀寫位,低電平讀,高電平寫
  13. sbit LCD_E=P2^7;         //LCD12864使能位,低電平無效,高電平使能
  14. sbit PSB=P3^2;
  15. #define Busy 0x80
  16. #define LCD_Data P0     //LCD12864的8位數(shù)據(jù)總線,單片機(jī)的P0端口
  17. void WriteDataLCD(unsigned char WDLCD);          //給LCD12864寫數(shù)據(jù)
  18. void WriteCommandLCD(unsigned char WCLCD);       //給LCD12864寫指令
  19. void LCDInit(void);                              //LCD12864初始化
  20. void LCDClear(void);                             //LCD12864清屏
  21. void CheckBusy(void);                            //忙檢測(cè)
  22. void LCDSendWord(unsigned char *p);              //向LCD發(fā)送一個(gè)字符串
  23. void LCDTestWord(bit i,unsigned char word);
  24. void DisplaySec(void);                           //在LCD上顯示秒鐘
  25. void DisplayMin(void);                           //在LCD上顯示分鐘
  26. void DisplayHour(void);                          //在LCD上顯示小時(shí)
  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上顯示節(jié)日
  32. /*********定義時(shí)間芯片DS1302的數(shù)據(jù)線及相關(guān)函數(shù)***********/
  33. sbit DS1302_CLK=P3^6;         //DS1302的時(shí)鐘信號(hào)線   
  34. sbit DS1302_IO=P3^0;          //DS1302的數(shù)據(jù)端口線
  35. sbit DS1302_RST=P3^5;         //DS1302的片選信號(hào)線
  36. void WriteDs1302byte(unsigned char temp);                    //給DS1302寫一個(gè)字節(jié)
  37. void WriteDs1302(unsigned char address,unsigned char dat);  //給DS1302寫入時(shí)間,先確定地址,再確定要寫入的數(shù)據(jù)
  38. unsigned char ReadDs1302(unsigned char address);           //讀取DS1302的數(shù)據(jù)
  39. void InitDS1302();
  40. /**********定義溫度傳感器DS18B20的數(shù)據(jù)線和相關(guān)函數(shù)*************/
  41. sbit DS18B20=P3^7;                        //DS18B20的數(shù)據(jù)線
  42. int temp;
  43. void DS18B20Init(void);                   //DS18B20初始化函數(shù)
  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. /**********定義開關(guān)按鍵,及蜂鳴器的數(shù)據(jù)線************/
  56. sbit SetKey=P1^0;       //按鍵功能:設(shè)置
  57. sbit SureKey=P1^1;      //按鍵功能:確認(rèn)
  58. sbit PlusKey=P1^2;      //按鍵功能:加
  59. sbit ReduceKey=P1^3;    //按鍵功能:減
  60. void Key(void);

  61. #define Fosc 12000000      //定義晶振頻率12000000HZ
  62. #define jiepai 3/4         //定義普通音符演奏的長(zhǎng)度分率,//每4分音符間隔
  63. sbit Speaker=P1^5;         //定義輸出管腳
  64. unsigned int code FreTab[12]={262,277,294,311,330,349,369,392,415,440,466,494};  //C調(diào)歌曲12個(gè)半音的頻率
  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;    //音符定時(shí)器初值暫存
  68. unsigned char SoundTempTH1,SoundTempTL1;    //音長(zhǎng)定時(shí)器初值暫存
  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(100);
  77.   Speaker=1;
  78.   DelayMs(100);
  79. }
  80. DelayMs(500);
  81. for(i=0;i<3;i++)
  82. {
  83.   Speaker=0;
  84.   DelayMs(100);
  85.   Speaker=1;
  86.   DelayMs(100);
  87. }
  88. DelayMs(500);
  89. for(i=0;i<2;i++)
  90. {
  91.   Speaker=0;
  92.   DelayMs(500);
  93.   Speaker=1;
  94.   DelayMs(100);
  95. }
  96. }
  97. void InitialSound(void)
  98. {
  99.     Speaker=1;
  100.     SoundTempTH1=(65535-(1/1200)*Fosc)/256;    //計(jì)算TL1應(yīng)裝入的初值     (10ms的初裝值)
  101.     SoundTempTL1=(65535-(1/1200)*Fosc)%256;    //計(jì)算TH1應(yīng)裝入的初值
  102.     TH1=SoundTempTH1;                          //裝入初值
  103.     TL1=SoundTempTL1;
  104.     TMOD|=0x11;                                //定時(shí)器1、2都工作在定時(shí)器模式,工作方式1
  105.     ET0=1;                                     //定時(shí)器0開中斷
  106.     ET1=0;                                     //定時(shí)器1關(guān)中斷
  107.     TR0=0;                                     //不啟動(dòng)定時(shí)器
  108.     TR1=0;                                     //不啟動(dòng)定時(shí)器
  109.     EA=1;                                      //開啟CPU中斷
  110. }

  111. void Speakertimer(void) interrupt 1            //音符發(fā)生中斷
  112. {
  113.     Speaker=!Speaker;                          //取反  
  114.     TH0=SoundTempTH0;                          //定時(shí)器0重新裝初值
  115.     TL0=SoundTempTL0;
  116. }
  117. void PlayMusic(unsigned char *SoundName,unsigned char diaohao,unsigned shengjiang,unsigned int Speed)
  118.                                    //SoundName為演奏歌曲歌名 diaohao是指樂曲升多少個(gè)半音演奏
  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 指針?biāo)饕?nbsp; LDiv  音符演奏的長(zhǎng)度(多少個(gè)10ms)   yipai 1分音符的長(zhǎng)度(幾個(gè)10ms)即一個(gè)節(jié)拍   
  125.              //sifenyifu 4分音符的長(zhǎng)度   CurrentFre 查出對(duì)應(yīng)音符的頻率   SoundLength歌曲長(zhǎng)度   TempCounter計(jì)算計(jì)數(shù)器初值
  126.     unsigned char yindiao,length,yinfu,shengban,gaodi,SLen,leixing,fudian;
  127.              //yindiao音調(diào)  length音長(zhǎng)  yinfu音符  gaodi高低音  shengban是否升半   leixing音符類型(0普通1連音2頓音)
  128.     for(i=0;i<12;i++)                   // 根據(jù)調(diào)號(hào)及升降八度來生成新的頻率表
  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;      //如果是降調(diào)  則頻率除以2
  139.         else if(shengjiang==3) NewFreTab[i]<<=2; //如果是升調(diào) 則頻率翻倍速
  140.     }                                   
  141.     SoundLength=0;
  142.     while(SoundName[SoundLength]!=0x00)          //計(jì)算歌曲長(zhǎng)度 以0X00結(jié)尾
  143.     {
  144.         SoundLength+=2;
  145.     }
  146.     Point=0;
  147.     yindiao=SoundName[Point];                    //第一個(gè)字節(jié)為音符音調(diào)
  148.     length=SoundName[Point+1];                   //第二個(gè)字節(jié)為音符時(shí)值
  149.     yipai=12000/Speed;                           //算出一個(gè)節(jié)拍的長(zhǎng)度(單位是10ms)   
  150.     sifenyifu=yipai/4;                           //算出4分音符的長(zhǎng)度
  151.     sifenyifu=sifenyifu-sifenyifu*jiepai;        //普通音最長(zhǎng)間隔標(biāo)準(zhǔn)
  152.     TR0=0;
  153.     TR1=1;                                       //啟動(dòng)定時(shí)器1
  154.     while(Point<SoundLength)
  155.     {
  156.         yinfu=yindiao%10;                        //個(gè)位,1--7七個(gè)音符                                 
  157.         gaodi=yindiao/10%10;                     //十位,高低音
  158.         shengban=yindiao/100;                    //百位,是否升半
  159.         CurrentFre=NewFreTab[PositTab[yinfu-1]+shengban];     //查出對(duì)應(yīng)音符的頻率   
  160.         if(yinfu!=0)
  161.         {
  162.             if (gaodi==1) CurrentFre>>=2;         //低音,頻率除以2
  163.             if (gaodi==3) CurrentFre<<=2;         //高音, 頻率翻倍速
  164.             TempCounter=65536-(50000/CurrentFre)*10/(12000000/Fosc);//計(jì)算計(jì)數(shù)器初值
  165.             SoundTempTH0=TempCounter/256;
  166.             SoundTempTL0=TempCounter%256;
  167.             TH0=SoundTempTH0;
  168.             TL0=SoundTempTL0+12;                 //加12是對(duì)中斷延時(shí)的補(bǔ)償
  169.         }
  170.         SLen=LengthTab[length%10];               //算出是幾分音符
  171.         leixing=length/10%10;                    //算出音符類型(0普通1連音2頓音)
  172.         fudian=length/100;
  173.         yinfuchang=yipai/SLen;                   //算出連音音符演奏的長(zhǎng)度(多少個(gè)10ms)
  174.         if (fudian==1)
  175.             yinfuchang=yinfuchang+yinfuchang/2;
  176.         if(leixing!=1)   
  177.             if(leixing==0)                       //算出普通音符的演奏長(zhǎng)度
  178.                 if (SLen<=4)   
  179.                     LDiv1=yinfuchang-sifenyifu;
  180.                 else
  181.                     LDiv1=yinfuchang*jiepai;
  182.             else
  183.                 LDiv1=yinfuchang/2;              //算出頓音的演奏長(zhǎng)度
  184.         else
  185.             LDiv1=yinfuchang;
  186.         if(yinfu==0) LDiv1=0;
  187.             LDiv2=yinfuchang-LDiv1;              //算出不發(fā)音的長(zhǎng)度
  188.          if (yinfu!=0)
  189.         {
  190.             TR0=1;
  191.             for(i=LDiv1;i>0;i--)                 //發(fā)規(guī)定長(zhǎng)度的音
  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. /*音樂歌譜每個(gè)音符由兩個(gè)字節(jié)表示,第一個(gè)字節(jié)表示音高,第二個(gè)字節(jié)表示音長(zhǎng)
  263. 音高由三位數(shù)字組成:個(gè)位是表示 1~7 這七個(gè)音符
  264. 十位是表示音符所在的音區(qū):1-低音,2-中音,3-高音;百位表示這個(gè)音符是否要升半音: 0-不升,1-升半音。
  265. 音長(zhǎng)最多由三位數(shù)字組成:
  266. 個(gè)位表示音符的時(shí)值,其對(duì)應(yīng)關(guān)系是:
  267. 數(shù)值(n): |0 |1 |2 |3 | 4 | 5 | 6 |
  268. 幾分音符: |1 |2 |4 |8 |16 |32 |64   
  269. 十位表示音符的演奏效果 (0-2): 0-普通,1-連音,2-頓音 百位是符點(diǎn)位: 0-無符點(diǎn),1-有符點(diǎn)


  270. 陽歷對(duì)應(yīng)的陰歷數(shù)據(jù),每年三字節(jié),
  271. 格式第一字節(jié)BIT7-4位表示閏月月份,為0,則無閏月,BIT3-0對(duì)應(yīng)陰歷第1-4月的大小,
  272. 第二字節(jié)BIT7-0對(duì)應(yīng)陰歷第5-12月大小,第三字節(jié)BIT7表示陰歷第13月大小
  273. 月分對(duì)應(yīng)的位為1,表示農(nóng)歷月大(30天)為0表示。29天)
  274. 第三字節(jié)BIT6-5表示春節(jié)的公歷月份,BIT4-0表示春節(jié)公歷日期
  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. /******************忙檢測(cè)函數(shù)***************/
  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寫入數(shù)據(jù)*****************/
  489. void WriteDataLCD(unsigned char WDLCD)
  490. {
  491.   CheckBusy();               //檢測(cè)忙
  492.   LCD_RS = 1;                //RS為高電平,DB7----DB0為數(shù)據(jù)      
  493.   LCD_RW = 0;                //RW為低電平,E從高電平到低電平,則是把DB7----DB0的數(shù)據(jù)寫到DR或者IR
  494.   LCD_E = 1;
  495.   LCD_Data = WDLCD;          //傳送數(shù)據(jù)WDLCD
  496.   Delay(5);
  497.   LCD_E = 0;                 //E從 高電平 到 低電平
  498.   Delay(5);
  499. }

  500. /******************給LCD寫入指令**********************/
  501. void WriteCommandLCD(unsigned char WCLCD) //BuysC為0時(shí)忽略忙檢測(cè)
  502. {
  503.   CheckBusy();                //檢測(cè)忙
  504.   LCD_RS = 0;                 //RS為低,DB7----DB0為指令
  505.   LCD_RW = 0;                 //RW為低,E從高電平到低電平,則是把DB7----DB0的數(shù)據(jù)寫到DR或者IR
  506.   LCD_E = 1;
  507.   LCD_Data = WCLCD;           //傳送數(shù)據(jù)
  508.   Delay(5);
  509.   LCD_E = 0;                  //E從 高電平到低電平
  510.      Delay(5);
  511. }

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

  513. void LCDInit(void)
  514. {
  515.   WriteCommandLCD(0x30);     //顯示模式設(shè)置,開始要求每次檢測(cè)忙信號(hào)
  516.   WriteCommandLCD(0x01);     //顯示清屏
  517.   WriteCommandLCD(0x06);     // 顯示光標(biāo)移動(dòng)設(shè)置
  518.   WriteCommandLCD(0x0C);     // 顯示開,無游標(biāo),不反白
  519. }

  520. /********************清屏***************************/
  521. void LCDClear(void)
  522. {
  523.   WriteCommandLCD(0x01);     //顯示清屏
  524.   WriteCommandLCD(0x34);     // 顯示光標(biāo)移動(dòng)設(shè)置
  525.   WriteCommandLCD(0x30);     // 顯示開及光標(biāo)設(shè)置
  526. }

  527. /*****************************************/
  528. void LCDSendWord(unsigned char *p)         //向LCD發(fā)送一個(gè)字符串,
  529. {
  530. while(*p>0)                            //比如void LCDSendWord('你好');就是讓LCD顯示"你好"
  531. {
  532.   WriteDataLCD(*p);
  533.   p++;
  534. }
  535. }
  536.   
  537. /************寫數(shù)據(jù)或者指令***************/
  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;則寫入數(shù)據(jù)  
  547. }
  548. }

  549. void DisplayYear(void)                 //往LCD上填寫 年 數(shù)據(jù)
  550. {
  551. year=ReadDs1302(0x8d);            //從1302的0X8D處讀出年數(shù)據(jù)
  552. LCDTestWord(0,0x81);               //寫指令 0X81  在第一行第二個(gè)字符位置顯示 年 數(shù)據(jù)
  553. LCDTestWord(1,(year/16)+0x30);     //寫數(shù)據(jù)
  554. LCDTestWord(1,year%16+0x30);      //寫數(shù)據(jù)
  555. LCDTestWord(0,0x82);                //寫指令  第一行第三個(gè)字符位置
  556. LCDSendWord("年");                  //顯示 年  LCD DDRAM第一行地址為80-87,第二行為90-97,第三行為88-8F,第四行為98-9F
  557. DisplayShengXiao();
  558. }

  559. void DisplayMonth(void)                //往LCD上填寫  月 數(shù)據(jù)
  560. {
  561. month=ReadDs1302(0x89);           //從1302中讀取月份數(shù)據(jù)
  562. LCDTestWord(0,0x83);               //寫命令
  563. if(month/16!=0)
  564. {
  565.   LCDTestWord(1,(month/16)+0x30);//寫數(shù)據(jù)
  566. }
  567. else
  568. {
  569.   LCDTestWord(1,0x20);            //寫數(shù)據(jù)
  570. }
  571. LCDTestWord(1,month%16+0x30);       //寫數(shù)據(jù)  
  572. LCDTestWord(0,0x84);                //寫指令
  573. LCDSendWord("月");                  //顯示 月
  574. DisplayShengXiao();
  575. }
  576.                            
  577. void DisplayWeek(void)                  //往LCD上填寫  星期  數(shù)據(jù)
  578. {
  579. week=(ReadDs1302(0x8b))%16;             //從1302中讀取星期數(shù)據(jù)  
  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上填寫   日期  數(shù)據(jù)     
  592. {
  593. day=ReadDs1302(0x87);              //從1302中讀取日期數(shù)據(jù)
  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上填寫  小時(shí)數(shù)據(jù)
  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上填寫分鐘 數(shù)據(jù)   
  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上填寫  秒鐘   和溫度  數(shù)據(jù)
  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++)               //循環(huán)8次 寫入數(shù)據(jù)
  651.     {
  652.         DS1302_CLK=0;
  653.         DS1302_IO=temp&0x01;      //每次傳輸?shù)妥止?jié)
  654.         temp>>=1;                //右移一位
  655.         DS1302_CLK=1;
  656.    }
  657. }  

  658. /***********************************寫入數(shù)據(jù)*****************************/
  659. void WriteDs1302( unsigned char address,unsigned char dat )     //先寫地址,再寫數(shù)據(jù)
  660. {
  661.   DS1302_RST=0;
  662. _nop_();
  663.   DS1302_CLK=0;
  664. _nop_();
  665.   DS1302_RST=1;
  666.     _nop_();                    //啟動(dòng)
  667.   WriteDs1302Byte(address); //發(fā)送地址
  668.   WriteDs1302Byte(dat);  //發(fā)送數(shù)據(jù)
  669.   DS1302_RST=0;            //恢復(fù)
  670. }

  671. /****************************************************************************/
  672. unsigned char ReadDs1302(unsigned char address)        //先送地址,再讀數(shù)據(jù)
  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);         //送地址函數(shù)
  682.   for (i=0;i<8;i++)               //循環(huán)8次 讀取數(shù)據(jù)
  683.   {
  684.   DS1302_CLK=1;
  685.   _nop_();
  686.    if(DS1302_IO)
  687.    temp|=0x80;               //每次傳輸?shù)妥止?jié)
  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中秒,分,時(shí),日期,月份,星期,年的地址分別是0x80,0x82,0x84,0x86,0x88,0x8a,0x8c
  699. {                                        //初始化寫入的時(shí)間是2010年4月1日15點(diǎn)整,星期六
  700. WriteDs1302(0x8e,0x00);             //控制命令,WP位為0,允許寫操作  控制位地址是0x8e
  701. DelayMs(5);
  702. WriteDs1302(0x8c,0x10);             //寫入年份10年
  703. DelayMs(5);
  704. WriteDs1302(0x8a,0x04);             //寫入星期6
  705.     DelayMs(5);
  706. WriteDs1302(0x88,0x05);             //定入月分 5月
  707. DelayMs(5);
  708. WriteDs1302(0x86,0x01);             //寫入日期 1日
  709. DelayMs(5);
  710. WriteDs1302(0x84,0x09);             //寫入小時(shí) 9點(diǎn)
  711. DelayMs(5);
  712. WriteDs1302(0x82,0x59);             //寫入分鐘 59分
  713. DelayMs(5);
  714. WriteDs1302(0x80,0x30);              //寫入秒  30秒
  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;
  735. while(i>0)i--;
  736. DS18B20=1;
  737. i=4;
  738. while(i>0)i--;
  739. }

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

  750. unsigned char TempRead(void)   //讀一個(gè)字節(jié)
  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); //讀出的數(shù)據(jù)最低位在最前面,這樣剛好一個(gè)字節(jié)在DAT里
  758.     }
  759.     return(dat);             //將一個(gè)字節(jié)數(shù)據(jù)返回
  760. }

  761. void TempWriteByte(unsigned char dat)  
  762. {                           //寫一個(gè)字節(jié)到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=8;while(i>0)i--;
  776.         }
  777.      else
  778.      {
  779.          DS18B20=0;       //寫0部分
  780.          i=8;while(i>0)i--;
  781.          DS18B20=1;
  782.          i++;i++;
  783.         }
  784.     }
  785. }

  786. void TempChange(void)  //發(fā)送溫度轉(zhuǎn)換命令
  787. {
  788. DS18B20Init();             //初始化DS18B20
  789.     delayb(1);             //延時(shí)
  790.     TempWriteByte(0xcc);  // 跳過序列號(hào)命令
  791.     TempWriteByte(0x44);  //發(fā)送溫度轉(zhuǎn)換命令
  792. }

  793. int GetTemp()               //獲得溫度
  794. {
  795. float tt;
  796.     unsigned char a,b;
  797.     DS18B20Init();
  798.     delayb(1);
  799.     TempWriteByte(0xcc);  
  800.     TempWriteByte(0xbe);    //發(fā)送讀取數(shù)據(jù)命令
  801.     a=TempRead();           //連續(xù)讀兩個(gè)字節(jié)數(shù)據(jù)
  802.     b=TempRead();
  803.     temp=b;
  804.     temp<<=8;            
  805.     temp=temp|a;            //兩字節(jié)合成一個(gè)整型變量。
  806.     tt=temp*0.0625;         //得到真實(shí)十進(jìn)制溫度值,因?yàn)镈S18B20 可以精確到0.0625度,所以讀回?cái)?shù)據(jù)的最低位代表的是0.0625度。                     
  807.     temp=tt*10+0.5;         //放大十倍,這樣做的目的將小數(shù)點(diǎn)后第一位 也轉(zhuǎn)換為可顯示數(shù)字,同時(shí)進(jìn)行一個(gè)四舍五入操作。                          
  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. //計(jì)算公歷日離當(dāng)年元旦的天數(shù),為了減少運(yùn)算,用了兩個(gè)表   DayCode1[9],DayCode2[3]
  813. //如果公歷月在九月或前,天數(shù)會(huì)少于0xff,用表DayCode1[9],在九月后,天數(shù)大于0xff,用表DayCode2[3]
  814. //如輸入公歷日為8月10日,則公歷日離元旦天數(shù)為DayCode1[8-1]+10-1,如輸入公歷日為11月10日,則公歷日離元旦天數(shù)為DayCode2[11-10]+10-1
  815. /*讀取數(shù)據(jù)表中農(nóng)歷月的大月或小月,如果該月為大返回1,為小返回0*/
  816. bit GetMoonDay(unsigned char LunarMonth,unsigned int TableAddr)
  817. {
  818. unsigned char temp;
  819.     switch (LunarMonth)                       //LunarMonth指向農(nóng)歷月份
  820. {
  821.         case 1:
  822.   {
  823.    temp=YearCode[TableAddr]&0x08;    //1月,對(duì)應(yīng)年份表里第一字節(jié)的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月,對(duì)應(yīng)年份表里第一字節(jié)的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月,對(duì)應(yīng)第一字節(jié)的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月,對(duì)應(yīng)第一字節(jié)的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月,對(duì)應(yīng)第二字節(jié)的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月,對(duì)應(yīng)第二字節(jié)的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月,對(duì)應(yīng)第二字節(jié)的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月,對(duì)應(yīng)第二字節(jié)的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月,對(duì)應(yīng)第二字節(jié)的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月,對(duì)應(yīng)第二字節(jié)的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月,對(duì)應(yīng)第二字節(jié)的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月,對(duì)應(yīng)第二字節(jié)的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月,對(duì)應(yīng)第三字節(jié)的BIT7位,如果是1,則月大,如果是0,則月小
  896.             if (temp==0) return(0);
  897.    else  return(1);
  898.   }
  899.     }
  900. }

  901. void Conversion(bit cenbit,unsigned char year,unsigned char month,unsigned char day)
  902.                              //cenbit=0為21世紀(jì),cenbit=1為20世紀(jì),輸入輸出數(shù)據(jù)均為BCD數(shù)據(jù)
  903. {                        
  904.     unsigned char temp1,temp2,temp3,MonthP;//temp3,temp4分別表示春節(jié)距元旦的天數(shù),公歷日離元旦的天數(shù)
  905.     unsigned int temp4,TableAddr;
  906.     bit flag2,flag_y;
  907.     temp1=year/16;           //BCD->hex 先把數(shù)據(jù)轉(zhuǎn)換為十六進(jìn)制  高位
  908.     temp2=year%16;           //低位
  909.     year=temp1*10+temp2;     //把 年 數(shù)據(jù) 轉(zhuǎn)換成16進(jìn)制
  910.     temp1=month/16;          //月份 高位
  911.     temp2=month%16;          //月份 低位
  912.     month=temp1*10+temp2;    //把 月 數(shù)據(jù) 轉(zhuǎn)換成16進(jìn)制
  913.     temp1=day/16;            //日期 高位
  914.     temp2=day%16;            //日期 低位
  915.     day=temp1*10+temp2;      //把 日 數(shù)據(jù) 轉(zhuǎn)換成16進(jìn)制
  916.     if(cenbit==0)                           //如果是21世紀(jì)
  917. {                  
  918.         TableAddr=(year+0x64-1)*0x03;       //定位數(shù)據(jù)表地址  year對(duì)應(yīng)的年份表中的地址是(year+99)*3 如2010年 其地址是327
  919.   LCDTestWord(0,0x80);
  920.   LCDSendWord("20");
  921.     }
  922.     else                                    //如果是20世紀(jì)
  923. {
  924.         TableAddr=(year-1)*0x03;            //定位數(shù)據(jù)表地址  year對(duì)應(yīng)的年份表中的地址是(year-1)*3  如1901年 其地址是3
  925.   LCDTestWord(0,0x80);
  926.   LCDSendWord("19");
  927.     }
  928.     temp1=YearCode[TableAddr+2]&0x60;       //取當(dāng)年春節(jié)所在的公歷月份   年份表中第三字節(jié)BIT6-5表示春節(jié)的公歷月份
  929.     temp1=_cror_(temp1,5);                  //循環(huán)右移5位,得到 春節(jié)所在的公歷月份
  930.     temp2=YearCode[TableAddr+2]&0x1f;       //取當(dāng)年春節(jié)所在的公歷日    年份表中第三字節(jié)BIT4-0表示當(dāng)年春節(jié)所在的公歷日
  931.     if(temp1==0x01)                         // 計(jì)算當(dāng)年春年離當(dāng)年元旦的天數(shù),春節(jié)只會(huì)在公歷1月或2月   
  932.         temp3=temp2-1;                      //假如春節(jié)在公歷1月,則元旦離春節(jié)的天數(shù)為  temp2-1 天
  933.     else
  934.         temp3=temp2+0x1f-1;                 //假如春節(jié)在公歷2月,則無理離春節(jié)的天數(shù)為  temp2+0x1f-1 天
  935.     if (month<10)
  936.         temp4=DayCode1[month-1]+day-1;      //0到8月某日距元旦的天數(shù)
  937.     else
  938.         temp4=DayCode2[month-10]+day-1;     //9月開始的某一天距元旦的天數(shù)
  939.     if ((month>0x02)&&(year%0x04==0))       //如果公歷月大于2月并且該年的2月為閏月,天數(shù)加1
  940.         temp4+=1;
  941.                                          //計(jì)算機(jī)出公歷日距元旦的天數(shù)和春節(jié)距元旦的天數(shù),則是為了比較公歷日是在春節(jié)前還是春節(jié)后
  942.                                          //如果temp3>temp4  則 公歷日在春節(jié)之前
  943.     if (temp4>=temp3)                       //公歷日在春節(jié)后或就是春節(jié)當(dāng)日使用下面代碼進(jìn)行運(yùn)算
  944. {   
  945.         temp4-=temp3;                       //公歷日離春節(jié)的天數(shù)  因?yàn)楣珰v日在春節(jié)后  所以為temp4-temp3
  946.         month=0x01;
  947.         MonthP=0x01;                        //LunarMonth為月份指向,公歷日在春節(jié)前或就是春節(jié)當(dāng)日LunarMonth指向首月
  948.         flag2=GetMoonDay(MonthP,TableAddr); //檢查該農(nóng)歷月為大小還是小月,大月返回1,小月返回0
  949.         flag_y=0;
  950.         if(flag2==0)                            //GetMoonDay()函數(shù)返回的是0
  951.    {temp1=0x1d;}                       //小月29天
  952.         else                                    //GetMoonDay()函數(shù)返回的是1
  953.    {temp1=0x1e;}                       //大月30天
  954.         temp2=YearCode[TableAddr]&0xf0;         //年份數(shù)據(jù)表中第1字節(jié)BIT7-4為閏月,為0則這年無閏月,如為1,表示有閏月
  955.         temp2=_cror_(temp2,4);                  //從數(shù)據(jù)表中取該年的閏月月份,如為0,則該年無閏月  BIT3-0表示陰歷1到4月的大小 1為大 0 為小
  956.         while(temp4>=temp1)
  957.   {
  958.             temp4-=temp1;
  959.             MonthP+=1;
  960.             if(month==temp2)
  961.    {
  962.              flag_y=~flag_y;
  963.              if(flag_y==0)  {month+=1;}
  964.             }
  965.             else
  966.       {
  967.     month+=1;
  968.    }
  969.             flag2=GetMoonDay(MonthP,TableAddr);
  970.             if(flag2==0)
  971.    {
  972.     temp1=0x1d;
  973.    }
  974.             else
  975.    {
  976.     temp1=0x1e;
  977.    }
  978.         }
  979.         day=temp4+1;
  980.     }
  981.     else
  982. {  //公歷日在春節(jié)前使用下面代碼進(jìn)行運(yùn)算
  983.         temp3-=temp4;                          //公歷日離春節(jié)的天數(shù)  因?yàn)楣珰v日在春節(jié)前  所以為temp3-temp4
  984.         if (year==0x00){year=0x63;cenbit=1;}
  985.         else year-=1;
  986.         TableAddr-=0x03;
  987.         month=0x0c;
  988.         temp2=YearCode[TableAddr]&0xf0;    //格式第一字節(jié)BIT7-4位表示閏月月份,為0,則無閏月,BIT3-0對(duì)應(yīng)陰歷第1-4月的大小,
  989.         temp2=_cror_(temp2,4);
  990.         if (temp2==0)MonthP=0x0c;
  991.         else MonthP=0x0d; //
  992.         /* MonthP為月份指向,如果當(dāng)年有閏月,一年有十三個(gè)月,月指向13,無閏月指向12*/
  993.         flag_y=0;
  994.         flag2=GetMoonDay(MonthP,TableAddr);
  995.         if(flag2==0)temp1=0x1d;
  996.         else temp1=0x1e;
  997.         while(temp3>temp1)
  998.   {
  999.             temp3-=temp1;
  1000.             MonthP-=1;
  1001.             if(flag_y==0)month-=1;
  1002.             if(month==temp2)flag_y=~flag_y;
  1003.             flag2=GetMoonDay(MonthP,TableAddr);
  1004.             if(flag2==0)temp1=0x1d;
  1005.             else temp1=0x1e;
  1006.          }
  1007.         day=temp1-temp3+1;
  1008.     }
  1009.     c_moon=cenbit;               
  1010.     temp1=year/10;
  1011.     temp1=_crol_(temp1,4);
  1012.     temp2=year%10;
  1013.     LunarYear=temp1|temp2;

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

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

  1023. void DisplayShengXiao(void)
  1024. {
  1025. unsigned char LunarYearD,ReYear;        //農(nóng)歷年份的十進(jìn)制數(shù)  和取模后的余數(shù)
  1026. if(cen==0x19)  {cenbit=1;}
  1027. if(cen==0x20)  {cenbit=0;}
  1028.   Conversion(cenbit,year,month,day);       //將公歷日期轉(zhuǎn)換成農(nóng)歷
  1029. LCDTestWord(0,0x94);                     //顯示在LCD的0X94位置上
  1030. LCDTestWord(1,LunarYear/16+0x30);        //農(nóng)歷年十位
  1031.   LCDTestWord(1,LunarYear%16+0x30);        //農(nóng)歷年個(gè)位
  1032.   LCDTestWord(1,'-');                      //用-隔開
  1033.   LCDTestWord(1,LunarMonth/16+0x30);       //農(nóng)歷月十位
  1034.   LCDTestWord(1,LunarMonth%16+0x30);       //農(nóng)歷月個(gè)位  
  1035.   LCDTestWord(1,'-');
  1036.   LCDTestWord(1,LunarDay/16+0x30);         //農(nóng)歷日十位
  1037.   LCDTestWord(1,LunarDay%16+0x30);         //農(nóng)歷日個(gè)位
  1038.   LunarYearD=(LunarYear/16)*10+LunarYear%16;        //農(nóng)歷年轉(zhuǎn)換成10進(jìn)制數(shù)
  1039.   ReYear=LunarYearD%12;                             //農(nóng)歷年模12,取余運(yùn)算
  1040.   switch(ReYear)
  1041.   {
  1042.   case 0: LCDTestWord(0,0x93);LCDSendWord("龍");break;   //余0即整除 農(nóng)歷 龍年
  1043.   case 1: LCDTestWord(0,0x93);LCDSendWord("蛇");break;   //蛇年
  1044.      case 2: LCDTestWord(0,0x93);LCDSendWord("馬");break;
  1045.   case 3: LCDTestWord(0,0x93);LCDSendWord("羊");break;
  1046.   case 4: LCDTestWord(0,0x93);LCDSendWord("猴");break;
  1047.   case 5: LCDTestWord(0,0x93);LCDSendWord("雞");break;
  1048.   case 6: LCDTestWord(0,0x93);LCDSendWord("狗");break;
  1049.   case 7: LCDTestWord(0,0x93);LCDSendWord("豬");break;
  1050.   case 8: LCDTestWord(0,0x93);LCDSendWord("鼠");break;
  1051.      case 9: LCDTestWord(0,0x93);LCDSendWord("牛");break;
  1052.   case 10:LCDTestWord(0,0x93);LCDSendWord("虎");break;
  1053.   case 11:LCDTestWord(0,0x93);LCDSendWord("兔");break;
  1054. }
  1055. }
  1056. /***************節(jié)假日提示********************/

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

  1060. if(LunarMonth==0x01 && LunarDay==0x01)       {LCDSendWord("春節(jié)快樂        ");}
  1061. if(LunarMonth==0x01 && LunarDay==0x05)       {LCDSendWord("姐姐的生日      ");}
  1062. if(LunarMonth==0x01 && LunarDay==0x15)       {LCDSendWord("元宵節(jié)快樂      ");}
  1063. if(LunarMonth==0x05 && LunarDay==0x05)       {LCDSendWord("端午節(jié)快樂      ");}
  1064. if(LunarMonth==0x06 && LunarDay==0x26)       {LCDSendWord("佳燕的生日      ");}
  1065. if(LunarMonth==0x07 && LunarDay==0x07)       {LCDSendWord("中國(guó)情人節(jié)      ");}
  1066. if(LunarMonth==0x08 && LunarDay==0x15)       {LCDSendWord("中秋節(jié)快樂      ");}
  1067. if(LunarMonth==0x09 && LunarDay==0x01)       {LCDSendWord("嘿嘿,又長(zhǎng)大了  ");}
  1068. if(LunarMonth==0x09 && LunarDay==0x03)       {LCDSendWord("侄子的生日      ");}
  1069. if(LunarMonth==0x09 && LunarDay==0x09)       {LCDSendWord("重陽節(jié)          ");}
  1070. if(LunarMonth==0x09 && LunarDay==0x30)       {LCDSendWord("媽媽的生日      ");}
  1071. if(LunarMonth==0x12 && LunarDay==0x08)       {LCDSendWord("臘八節(jié)          ");}
  1072. if(LunarMonth==0x12 && LunarDay==0x15)       {LCDSendWord("過小年啦        ");}
  1073. if(LunarMonth==0x12 && LunarDay==0x27)       {LCDSendWord("爸爸的生日      ");}
  1074. if(LunarMonth==0x12 && LunarDay==0x29)       {LCDSendWord("臘月二十九      ");}
  1075. if(LunarMonth==0x12 && LunarDay==0x30)       {LCDSendWord("除夕夜到了      ");}     //以上是農(nóng)歷節(jié)日,以下是公歷節(jié)日
  1076. if(month==0x01 && day==0x01)     {LCDSendWord("元旦節(jié)快樂      ");}   
  1077. if(month==0x02 && day==0x02)  {LCDSendWord("世界濕地日      ");}
  1078. if(month==0x02 && day==0x10)  {LCDSendWord("世界氣象日      ");}
  1079. if(month==0x03 && day==0x08)  {LCDSendWord("國(guó)際婦女節(jié)      ");}
  1080. if(month==0x03 && day==0x12)  {LCDSendWord("中國(guó)植樹節(jié)      ");}
  1081. if(month==0x03 && day==0x15)  {LCDSendWord("消費(fèi)者權(quán)益日    ");}
  1082. if(month==0x03 && day==0x22)  {LCDSendWord("世界水日        ");}     
  1083. if(month==0x04 && day==0x01)  {LCDSendWord("愚人節(jié)快樂      ");}
  1084. if(month==0x04 && day==0x05)  {LCDSendWord("中國(guó)清明節(jié)      ");}
  1085. if(month==0x04 && day==0x22)  {LCDSendWord("世界地球日      ");}
  1086. if(month==0x05 && day==0x01)  {LCDSendWord("國(guó)際勞動(dòng)節(jié)      ");}
  1087. if(month==0x05 && day==0x04)  {LCDSendWord("中國(guó)青年節(jié)      ");}
  1088. if(month==0x05 && day==0x12)  {LCDSendWord("世界護(hù)士節(jié)      ");}
  1089. if(month==0x06 && day==0x01)  {LCDSendWord("國(guó)際兒童節(jié)      ");}
  1090. if(month==0x06 && day==0x05)  {LCDSendWord("世界環(huán)境日      ");}
  1091. if(month==0x06 && day==0x06)  {LCDSendWord("國(guó)際愛眼日      ");}
  1092. if(month==0x06 && day==0x25)  {LCDSendWord("世界土地日      ");}
  1093. if(month==0x06 && day==0x26)  {LCDSendWord("國(guó)際禁毒日      ");}   
  1094. if(month==0x07 && day==0x01)  {LCDSendWord("香港回歸日      ");}   
  1095. if(month==0x08 && day==0x01)  {LCDSendWord("中國(guó)建軍節(jié)      ");}
  1096. if(month==0x09 && day==0x10)  {LCDSendWord("中國(guó)老師節(jié)      ");}
  1097. if(month==0x09 && day==0x18)  {LCDSendWord("九一八事件紀(jì)念日");}
  1098. if(month==0x10 && day==0x01)  {LCDSendWord("中國(guó)國(guó)慶節(jié)      ");}
  1099. if(month==0x10 && day==0x04)  {LCDSendWord("世界動(dòng)物日      ");}
  1100. if(month==0x10 && day==0x09)  {LCDSendWord("世界郵政日      ");}
  1101. if(month==0x10 && day==0x10)  {LCDSendWord("辛亥革命紀(jì)念日  ");}  
  1102. if(month==0x12 && day==0x20)  {LCDSendWord("澳門回歸紀(jì)念日  ");}
  1103. if(month==0x12 && day==0x24)  {LCDSendWord("平安夜          ");}
  1104. if(month==0x12 && day==0x25)  {LCDSendWord("圣誕節(jié)          ");}
  1105.     else    LCDSendWord("入云龍小白");
  1106. }
  1107. void UpDate(void)
  1108. {
  1109. DisplayYear();     //顯示年
  1110. DisplayMonth();    //顯示月
  1111. DisplayDay();    //顯示日
  1112. DisplayWeek();    //顯示星期
  1113. DisplayHour();    //顯示時(shí)
  1114. DisplayMin();    //顯示分
  1115. DisplaySec();    //顯示秒
  1116. DisplayShengXiao();
  1117. }
  1118. void SetTime(unsigned char count)
  1119. {
  1120. unsigned char address,item;
  1121. unsigned char max,mini;
  1122. LCDTestWord(0,0x98);
  1123. LCDSendWord("調(diào)整");
  1124. if(count==6)  {LCDSendWord("秒鐘      ");address=0x81; max=59;mini=0;}
  1125. if(count==5)  {LCDSendWord("分鐘      ");address=0x83; max=59;mini=0;}
  1126. if(count==4)  {LCDSendWord("小時(shí)      ");address=0x85; max=23;mini=0;}
  1127. if(count==3)  {LCDSendWord("星期      ");address=0x8b; max=7;mini=1;}
  1128. if(count==2)  {LCDSendWord("日期      ");address=0x87; max=31; mini=1;}
  1129. if(count==1)  {LCDSendWord("月份      ");address=0x89; max=12;mini=1;}
  1130. if(count==0)  {LCDSendWord("年份      ");address=0x8d; max=99;mini=0;}
  1131. item=ReadDs1302(address);//讀取DS1302某地址上的數(shù)值賦給item  
  1132. item=(item/16)*10+item%16;
  1133. if(PlusKey==0)       //PlusKey-加
  1134.   item++;          //數(shù)加 1
  1135. if(ReduceKey==0)     //ReduceKey-減
  1136.   item--;          //數(shù)減 1
  1137. if(item>max)
  1138.   item=mini;       //查看數(shù)值有效范圍  
  1139. if(item<mini)
  1140.   item=max;
  1141. WriteDs1302(0x8e,0x00);
  1142. item=(item/10)*16+item%10;
  1143. WriteDs1302(address-1,item); //將調(diào)整好的item值寫入DS1302
  1144.     UpDate();
  1145. }

  1146. void Key(void)
  1147. {

  1148. if (SetKey==0)           // 設(shè)置時(shí)間
  1149. {
  1150.     DelayMs(10);         //按鍵消抖   
  1151.   if(SetKey==0&&w==0)  //當(dāng)是正常狀態(tài)時(shí)就進(jìn)入調(diào)時(shí)狀態(tài)
  1152.   {
  1153.    w=1;          //進(jìn)入調(diào)時(shí)   
  1154.    SetTime(next);   //調(diào)整   
  1155.   }
  1156.   if(SetKey==0&&w==1)  //當(dāng)是調(diào)時(shí)狀態(tài) 本鍵用于調(diào)整下一項(xiàng)
  1157.   {
  1158.    next++;
  1159.    if(next>=7)   {next= 0;}
  1160.    SetTime(next);   //調(diào)整   
  1161.   }
  1162.      while(SetKey==0);    //等待鍵松開
  1163. }
  1164. if(SureKey==0)           // 當(dāng)在調(diào)時(shí)狀態(tài)時(shí)就退出調(diào)時(shí)
  1165.     {
  1166.   DelayMs(10);         //按鍵消抖
  1167.   if(SureKey==0&&w==1)
  1168.   {
  1169.    w=0;next=0;
  1170.    Holidays();
  1171.   }
  1172.   while(SureKey==0);   //等待鍵松開
  1173. }
  1174. if (PlusKey==0)          //加調(diào)整
  1175. {
  1176.      DelayMs(10);         //按鍵消抖
  1177.      if(PlusKey==0&&w==1)
  1178.   {   
  1179.    SetTime(next);   //調(diào)整
  1180.   }
  1181.   while(PlusKey==0);       //等待鍵松開
  1182. }

  1183. if (ReduceKey==0)        //減調(diào)整
  1184. {        
  1185.      DelayMs(10);         //按鍵消抖
  1186.      if(ReduceKey==0&&w==1)
  1187.   {   
  1188.    SetTime(next);   //調(diào)整
  1189.   }  
  1190.   while(ReduceKey==0);     //等待鍵松開
  1191. }  
  1192. }

  1193. void DelayMs(unsigned int a)        //延時(shí) 1MS/次
  1194. {
  1195. unsigned char i;
  1196. while(--a!=0)
  1197. {
  1198.   for(i=0;i<125;i++)
  1199.   ;
  1200. }
  1201. }

  1202. void Delay(unsigned char num)               
  1203. {
  1204. while(num--)
  1205. ;
  1206. }

  1207. void main()
  1208. {
  1209. SetKey=1;
  1210. SureKey=1;
  1211. PlusKey=1;
  1212. ReduceKey=1;
  1213. PSB=1;
  1214. next=0;
  1215. LCDInit();
  1216. LCDClear();
  1217. //InitDS1302();
  1218. InitialSound();
  1219. while(1)                        
  1220. {
  1221. if(w==0)
  1222. {
  1223.   DisplayYear();     //顯示年
  1224.   DisplayMonth();    //顯示月
  1225.   DisplayDay();    //顯示日
  1226.   DisplayWeek();    //顯示星期
  1227.   DisplayHour();    //顯示時(shí)
  1228.   DisplayMin();    //顯示分
  1229.   DisplaySec();    //顯示秒
  1230.   Holidays();        //顯示節(jié)日
  1231.   DisplayTemp();     //顯示溫度
  1232.   }
  1233.   Key();
  1234.   if(min==0&&sec==0)
  1235.   {
  1236.    
  1237.    if(LunarMonth==9&&LunarDay==1)
  1238.    {
  1239.     PlayMusic(HappyBirthday,0,3,300);
  1240.    }
  1241.    else
  1242.    {
  1243.     SpeakerDiDi();
  1244.    }
  1245.   }
  1246. }
  1247. }
復(fù)制代碼





作者: 1433633039    時(shí)間: 2016-3-19 17:42
可有仿真圖?
作者: whengfu    時(shí)間: 2016-3-31 14:38
謝謝樓主開源,這么完整的萬年歷代碼,我等學(xué)習(xí)了
作者: D_anJF00    時(shí)間: 2016-12-22 20:23
可有仿真圖




歡迎光臨 (http://www.torrancerestoration.com/bbs/) Powered by Discuz! X3.1