久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 7578|回復: 10
打印 上一主題 下一主題
收起左側

帶GPS授時語音報時的大數字萬年歷制作 附單片機程序 DS12C887 DS3231芯片

  [復制鏈接]
跳轉到指定樓層
樓主
制作出來的萬年歷實物圖如下,走時非常精準:

提醒:
1、所有標 C1、C2、C3、R1的元件先不用安裝,主要為抗干擾預留,若在使用中不正常才可安裝。
2、所有電阻阻值前標“*”表示該電阻可根據LED元件性能或個人使用習慣浮動調節。
3、如果使用mini_USB,需要一定的焊接功夫。可先將焊錫加在5個引腳焊盤上。
4、不能使用劣等供電電源,板子上很多芯片都怕高頻干擾!

注意:
1、在有GPS連接的情況下,+、-、EXIT 無效,短按MOD可強制GPS校時。
2、冒號閃爍開關、整點報時開關變量保存入24C02,斷電不丟失。
3、調時中,秒不可調整。調到分鐘時秒自動回零。
4、調時中可隨時按EXIT不保存退出,也可以一直按MOD保存退出。







P0 :DS12C887-AD

//max7219
sbit DIN  = P1^0;
sbit LOAD = P1^1;
sbit CLK  = P1^2;

//控制冒號是否閃爍
sbit BLK  = P1^3;     

//按鍵 MOD + - EXIT
sbit K1  = P1^4; //K1-調時設置,長按進入時間設置;短按作為日期時間下一項。當gps有效時,短按以gps時間校時
sbit K2  = P1^5; //K2-調時中作+,    運行中作為報時
sbit K3  = P1^6; //K3-調時中作-,    (運行中可留作12/24模式切換)
sbit K4  = P1^7; //K4-調時中作確認、返回;運行中作是否報時選擇鍵

//DS3231,24C02
sbit SCL= P2^0;   
sbit SDA= P2^1;   

P2^2 : DHT11

//語音報時指示燈
sbit SND  = P2^3;

//DS12C887 控制IO
sbit DS  = P2^4;   //兼做電波鐘BPC的P0控制
sbit RW  = P2^5;
sbit AS  = P2^6;
sbit CS  = P2^7;

P3^0 :串口RXD
P3^1 :串口TXD

//DS3231 SQW
sbit INT0= P3^2;

//PWM語音芯片
sbit BUSY = P3^3;
sbit DATA = P3^4;
sbit RST  = P3^5;

P3^6 : 紅外;
P3^7 : DS18B20;

供電電路:
一、電源預留寬電壓輸入降壓:
1、1117-5
2、7805
若有5V電源,可以將降壓芯片輸入輸出短接。

二、電源輸入濾波部分可根據使用的電源質量酌情考慮

三、1.5KE68CA為雙向過壓保險設計,可無視!

四、部分器件使用3.3V電壓,因此使用1117-3.3。輸出必須22uF和0.1uF濾波。



24C02是存儲冒號是否閃爍及整點報時開關

萬年歷語音報時芯片與τ 寶原版芯片不一樣,地址向后錯一位。

原版芯片開機送電產生脈沖即會播報第一個地址“零”,新版定制芯片把第一個地址留空。而且在地址最后額外增加了3個語音:貓叫、老鼠叫、貓叫老鼠叫混合。

語音芯片有3個接口:
SPK1_1、SPK1_2并聯,哪個使用方便就接哪個。喇叭建議8Ω/0.25--0.5W
SPK2_1 為放大語音,一般不建議使用。


單片機源程序如下:
  1. //89C52RC + 11.0592M
  2. //語音報時,手動調時,gps授時,電腦校時
  3. //GPS有效信號(VA)穩定達10分鐘后自動校時
  4. //電腦可串口發送數據強制校時 GPRMC,024813.640,,,,,,,,150706,X
  5. //                                                         標志頭         時分秒                          日月年 標志尾
  6. //DS3231 SQW已引入中斷P3.2,但本程序未使用外部中斷
  7. //2016.5.10
  8. #include<reg52.h>
  9. #include <intrins.h>
  10. #include <string.h>
  11. #include "DS3231.h"
  12. #include "nongli.h"
  13. #include "iic.h"
  14. /********************************************************************************************************************
  15.                 以下為GPS部分定義
  16. 因時間關系,gps數據應該加校驗處理,防止出現亂碼情況,雖然gps被干擾的情況很罕見。待其他有精力的玩家來解決
  17. ********************************************************************************************************************/
  18. //GPS數據存儲數組
  19. u8 time[6];        //時間
  20. u8 date[6];        //日期
  21. bit va;                           //有效
  22. bit QJ;                           //電腦發送強制校時信號
  23. bit tswc;                   //調時完成標志

  24. //串口中斷需要的變量
  25. u8 seg_count;        //逗號計數器
  26. u8 dot_count;        //小數點計數器
  27. u8 byte_count;        //位數計數器

  28. u8 mode;                //0:結束模式,1:命令模式,2:數據模式
  29. u8 buf_full;            //1:整句接收完成,相應數據有效。0:緩存數據無效。
  30. u8 cmd[5];            //命令類型存儲數組

  31. typedef  struct        _TIMER          /** 作時區轉換時需要用到年、月、日進一 **/
  32. {
  33.     u8 Hour;
  34.     u8 Min;
  35.     u8 Sec;
  36.     u8 Day;
  37.     u8 Mon;
  38.     u8 Year;
  39. } TIMER;
  40. TIMER BjTime;

  41. void InitBps();                           /**  串口初始化 **/
  42. void UTCToLocal(TIMER *GPS_DataTmp);  //時區轉換
  43. void Set_DStime(u8 sel);
  44. void GetGpsTime(void);
  45. void FormatString(char *p);
  46. void updatetime();

  47. int gpscount=0;  //gps有效計時

  48. /////////////////////////////////////
  49. sbit DIN  = P1^0;
  50. sbit LOAD = P1^1;
  51. sbit CLK  = P1^2;

  52. sbit BUSY = P3^3;
  53. sbit DATA = P3^4;
  54. sbit RST  = P3^5;

  55. /********按鍵部分 按鍵采用定時器配合狀態機        **/
  56. bit  TS_Mode;//調時標志
  57. u8   Tcount;  //10ms計數

  58. xdata        uint        F_50ms_Loop                =        0;
  59. xdata        uint        F_500ms_Loop        =        0;

  60. bit        F_50ms        =        1;
  61. bit        F_500ms        =        1;
  62.          
  63. u8   KeyValue;

  64. sbit K1  = P1 ^ 4; //K1-調時設置,長按進入時間設置;短按作為日期時間下一項。當gps有效時,短按以gps時間校時
  65. sbit K2  = P1 ^ 5; //K2-調時中作+,        運行中作為手動報時
  66. sbit K3  = P1 ^ 6; //K3-調時中作-,        運行中作冒號閃爍開關
  67. sbit K4  = P1 ^ 7; //K4-調時中作確認、返回;運行中作整點報時開關

  68. sbit BLK  = P1 ^ 3;         //冒號是否閃爍
  69. sbit SND  = P2 ^ 3;         //語音報時指示燈
  70. bit bs;
  71. bit ss,sb;  //冒號閃爍標志

  72. void key_scan(void);
  73. void Led_Flash(u8 n,bit f);


  74. u8   DStime[8]={0,0,0,0,0,0,0,0};//秒,分,時,周,日,月,年,溫度
  75. u8   S[7]={0,0,0,0,0,0,0};//調時時的中間變量

  76. bit sound;//報時指示燈標志 是否允許報時
  77. u8 spkcount;//報時段參數

  78. u8 e;//對應調時的位置
  79. u8  item, max, mini;

  80. void FormatDT();

  81. void Delay_50us(uint t)        //50us延遲函數
  82. {
  83.      u8 j;
  84.          for(;t>0;t--)
  85.           for(j=19;j>0;j--);
  86. }


  87. void speak(uint z)      //賦值變量 Z  Z等于幾就播放第幾段
  88. {
  89.     RST = 1;                          //語音芯片的復位腳為高電平//
  90.     Delay_50us(4);      //持續 200us//
  91.     RST = 0;                          //然后復位腳置零//
  92.     Delay_50us(4);
  93.         z++;                                /*自己定制語音芯片后移一位,如果使用原版報時芯片,此句應刪除*/
  94.     while(z > 0)            //若 Z等于 0 則不工作,若大于 0則繼續自減//
  95.     {
  96.         DATA = 1;                  //data 腳位為高電平//
  97.         Delay_50us(3);    //持續 100us//
  98.         DATA = 0;                  //然后置零//
  99.         Delay_50us(3);    //持續 100us這三句的意思就是發從一個 100us的脈沖(高低各 100us)//
  100.         z--;             //z 自減完成后開始播放對應的語音(因為z 是幾就播放第幾段)//
  101.     }
  102. }

  103. //          八點整
  104. //    八點  零一分
  105. //    八點  十  分
  106. //    八點  十一分
  107. //    八點二十  分
  108. //          八點二十一分
  109. //  十一點
  110. //二十  點
  111. //二十一點
  112. void baoshi()//7--21點報時
  113. {
  114.           if(spkcount<1 || spkcount>9) return;

  115.          

  116. //第二級MAX7219寫入字(16位)

  117. void WriteWord_2 (u8 addr, u8 num) //發現與第二及第三塊相連的數碼管閃爍,增加了空操作后就不閃爍了!!
  118. {
  119.     LOAD = 0;
  120.     _nop_();
  121.     SendChar (NoOp);
  122.     _nop_();
  123.     SendChar (0);

  124.     _nop_();
  125.     SendChar (addr);
  126.     _nop_();
  127.     SendChar (num);
  128.     _nop_();
  129.     SendChar (NoOp);
  130.     _nop_();
  131.     SendChar (0);
  132.     _nop_();

  133.     LOAD = 1;
  134. }

  135. //            向第三級MAX7219寫入字(16位)
  136. void WriteWord_1 (u8 addr, u8 num) //發現與第二及第三塊相連的數碼管閃爍,增加了空操作后就不閃爍了!!
  137. {
  138.     LOAD = 0;
  139.     _nop_();
  140.     SendChar (NoOp);
  141.     _nop_();
  142.     SendChar (0);
  143.     _nop_();
  144.     SendChar (NoOp);
  145.     _nop_();
  146.     SendChar (0);
  147.     _nop_();
  148.     SendChar (addr);
  149.     _nop_();
  150.     SendChar (num);
  151.     _nop_();
  152.     LOAD = 1;
  153. }
  154. void init()
  155. {
  156.     K1 = 1;
  157.     K2 = 1;
  158.     K3 = 1;
  159.     K4 = 1;

  160.         QJ=0;
  161.         SND=1;//關
  162.         sound=0;
  163.         RST=0;
  164.         DATA=0;
  165.         Tcount=0;


  166.         TS_Mode=0;
  167.         KeyValue=0;
  168.         tswc=0;

  169.         ss=Read_02_Data(0);
  170.         Delay_50us(40);

  171.         SND=Read_02_Data(2);
  172.         Delay_50us(40);

  173.         clrwdt;
  174.         bs=0;

  175. }
  176. void InitDis (void)
  177. {
  178.     WriteWord_1 (ScanLimit,ScanDigit-1);        /*設置掃描界限*/
  179.     WriteWord_1 (DecodeMode,DecodeDigit);      /*設置譯碼模式*/
  180.     WriteWord_1 (Intensity,IntensityGrade);    /*設置亮度*/
  181.     WriteWord_1 (ShutDown,NormalOperation);    /*設置電源工作模式*/
  182.    
  183.     WriteWord_2 (ScanLimit,ScanDigit-2);        /*設置掃描界限*/
  184.     WriteWord_2 (DecodeMode,DecodeDigit);      /*設置譯碼模式*/
  185.     WriteWord_2 (Intensity,IntensityGrade);   /*設置亮度*/
  186.     WriteWord_2 (ShutDown,NormalOperation);    /*設置電源工作模式*/

  187.     WriteWord_3 (ScanLimit,ScanDigit);         /*設置掃描界限*/
  188.     WriteWord_3 (DecodeMode,DecodeDigit);      /*設置譯碼模式*/
  189.     WriteWord_3 (Intensity,IntensityGrade);    /*設置亮度*/
  190.     WriteWord_3 (ShutDown,NormalOperation);    /*設置電源工作模式*/
  191. }
  192. /*日期、時間設置函數---------------------------------------------------------*/

  193. void        GetDateTime()        //獲取DS3231當前日期和時間
  194. {
  195.                 u8        Tmp,i;
  196.                 for(i=0;i<7;i++)
  197.                 {
  198.                     if(i==3)         //星期不理睬
  199.                            continue;
  200.                         Tmp=read_random(i);        
  201.                         if(i==2)
  202.                                 Tmp&=0x3f;        //時的格式單獨處理
  203.                         DStime[i]        =        BCD2HEX(Tmp);               
  204.                 }
  205. }
  206. void        ShowTime(bit b)        //更新信息
  207. {
  208.         WriteWord_2 (Digit4, DStime[0]/10);
  209.         WriteWord_2 (Digit5, DStime[0]%10);
  210.                 if(gpscount)
  211.                 {
  212.                     WriteWord_3 (Digit4, BjTime.Sec/10);   //測試gps走時
  213.                     WriteWord_3 (Digit5, BjTime.Sec%10);
  214.                 }
  215.            if(b) //更新全部信息
  216.            {
  217.                 if(DStime[3]==0 ||DStime[3]==7)         //星期日=8
  218.                         DStime[3]=8;
  219.                 DStime[7]=read_temp() ;

  220.                 WriteWord_2 (Digit0, DStime[2]<10 ? 0x0F:DStime[2]/10);
  221.                 WriteWord_2 (Digit1, DStime[2]%10);
  222.                 WriteWord_2 (Digit2, DStime[1]/10);
  223.                 WriteWord_2 (Digit3, DStime[1]%10);

  224.                         WriteWord_1 (Digit0, DStime[6]/10);
  225.                 WriteWord_1 (Digit1, DStime[6]%10);
  226.                 WriteWord_1 (Digit2, DStime[5]<10?0x0F:1);
  227.                 WriteWord_1 (Digit3, DStime[5]%10);
  228.                 WriteWord_1 (Digit4, DStime[4]<10?0x0F:DStime[4]/10);
  229.                 WriteWord_1 (Digit5, DStime[4]%10);
  230.                 WriteWord_1 (Digit6, DStime[3]);        
  231.         
  232.                 WriteWord_3 (Digit0, month_moon<10? 0x0F:1);
  233.                 WriteWord_3 (Digit1, month_moon%10);
  234.                 WriteWord_3 (Digit2, day_moon<10? 0x0F:day_moon/10);
  235.                 WriteWord_3 (Digit3, day_moon%10);

  236.                         if(!gpscount)
  237.                         {
  238.                         WriteWord_3 (Digit4, 0x0F);   //無濕度計
  239.                         WriteWord_3 (Digit5, 0x0F);
  240.                         }
  241.                 if(DStime[7]<128)//正數時直接顯示
  242.                 {
  243.                                 WriteWord_3 (Digit6, DStime[7] / 10);
  244.                                 WriteWord_3 (Digit7, DStime[7] % 10);
  245.                 }
  246.                 else
  247.                 {
  248.                                 WriteWord_3 (Digit6, 0x0A);//負數顯示 -
  249.                                 WriteWord_3 (Digit7, DStime[7] % 10);        //零下只顯示一位        
  250.                 }        

  251.                 }
  252. }
  253. void        Led_Flash(u8 n,bit f)        //調試時閃爍提示效果
  254. {
  255.     if(n < 3)
  256.     {
  257.         if(f)
  258.         {
  259.             WriteWord_1 (n*2 + 1, 0x0F);
  260.             WriteWord_1 (n*2 + 2, 0x0F);
  261.         }
  262.         else
  263.         {
  264.             WriteWord_1 (n*2 + 1, S[n] / 10);
  265.             WriteWord_1 (n*2 + 2, S[n] % 10);
  266.         }                                                                                                                                                                                                                                                                                                                        
  267.     }
  268.     else
  269.     {
  270.                 if(f)
  271.         {
  272.             WriteWord_2 ((n-4)*2 + 1, 0x0F);
  273.             WriteWord_2 ((n-4)*2 + 2, 0x0F);

  274.         }
  275.         else
  276.         {
  277.             WriteWord_2 ((n-4)*2 + 1, S[n] / 10);
  278.             WriteWord_2 ((n-4)*2 + 2, S[n] % 10);
  279.         }

  280.     }
  281. }
  282. void updatetime()
  283. {
  284.         u8 i;
  285.                 S[3]= Conver_WEEK( S[0], S[1], S[2]);
  286.                 if(S[3]== 0)
  287.                    S[3]=7;
  288.         for(i = 0; i < 7; i++)
  289.         {
  290.             if(S[i] != DStime[6-i])
  291.                 ModifyTime(6-i, S[i]);
  292.         }
  293. }
  294. //按鍵掃描,定時10ms執行一次
  295. static u8 KeyScan(void)
  296. {
  297.     if(K1 == 0)return KEY_VALUE_1 ;
  298.     if(K2 == 0)return KEY_VALUE_2 ;
  299.     if(K3 == 0)return KEY_VALUE_3 ;
  300.     if(K4 == 0)return KEY_VALUE_4 ;
  301.     return KEY_NULL ;
  302. }
  303. u8  GetKey(void)
  304. {
  305.     static u8 s_u8KeyState = KEY_STATE_INIT ;
  306.     static u8 s_u8KeyTimeCount = 0 ;
  307.     static u8 s_u8LastKey = KEY_NULL ;  //保存按鍵釋放時候的鍵值
  308.     u8 KeyTemp = KEY_NULL ;
  309.     KeyTemp = KeyScan() ;        //獲取鍵值
  310.     switch(s_u8KeyState)
  311.     {
  312.             case KEY_STATE_INIT :
  313.             {
  314.                 if(KEY_NULL != (KeyTemp))
  315.                 {
  316.                     s_u8KeyState = KEY_STATE_WOBBLE ;
  317.                 }
  318.             }
  319.             break ;
  320.             case KEY_STATE_WOBBLE :      //消抖
  321.             {
  322.                 s_u8KeyState = KEY_STATE_PRESS ;
  323.             }
  324.             break ;
  325.             case KEY_STATE_PRESS :
  326.             {
  327.                 if(KEY_NULL != (KeyTemp))
  328.                 {
  329.                     s_u8LastKey = KeyTemp ; //保存鍵值,以便在釋放按鍵狀態返回鍵值
  330.                     KeyTemp |= KEY_DOWN ;  //按鍵按下
  331.                     s_u8KeyState = KEY_STATE_LONG ;
  332.                 }
  333.                 else
  334.                 {
  335.                     s_u8KeyState = KEY_STATE_INIT ;
  336.                 }
  337.             }
  338.             break ;
  339.             case KEY_STATE_LONG :
  340.             {
  341.                 if(KEY_NULL != (KeyTemp))
  342.                 {
  343.                     if(++s_u8KeyTimeCount > KEY_LONG_PERIOD)
  344.                     {
  345.                         s_u8KeyTimeCount = 0 ;
  346.                         KeyTemp |= KEY_LONG ;  //長按鍵事件發生
  347.                         s_u8KeyState = KEY_STATE_CONTINUE ;
  348.                     }
  349.                 }
  350.                 else
  351.                 {
  352.                     s_u8KeyState = KEY_STATE_RELEASE ;
  353.                 }
  354.             }
  355.             break ;
  356.             case KEY_STATE_CONTINUE :
  357.             {
  358.                 if(KEY_NULL != (KeyTemp))
  359.                 {
  360.                     if(++s_u8KeyTimeCount > KEY_CONTINUE_PERIOD)
  361.                     {
  362.                         s_u8KeyTimeCount = 0 ;
  363.                         KeyTemp |= KEY_CONTINUE ;
  364.                     }
  365.                 }
  366.                 else
  367.                 {
  368.                     s_u8KeyState = KEY_STATE_RELEASE ;
  369.                 }
  370.             }
  371.             break ;
  372.             case KEY_STATE_RELEASE :
  373.             {
  374.                 s_u8LastKey |= KEY_UP ;
  375.                 KeyTemp = s_u8LastKey ;
  376.                 s_u8KeyState = KEY_STATE_INIT ;
  377.             }
  378.             break ;
  379.             default :
  380.                 break ;
  381.     }
  382.     return KeyTemp ; //返回鍵值
  383. }
  384. void  KeyProc(void)
  385. {
  386.                 u8 i;
  387.         if(!va && !TS_Mode && KeyValue == (KEY_VALUE_1 | KEY_LONG))   //無gps+長按K1進入調時
  388.         {
  389.             TS_Mode = 1;                //進入調時模式
  390.             for(i = 0; i < 7; i++)         
  391.             {
  392.                 S[i] = DStime[6 - i];
  393.             }
  394.         }

  395.         if(KeyValue == (KEY_VALUE_1 | KEY_DOWN))
  396.         {
  397.             if(TS_Mode)                //在調時狀態下進入下一項設置
  398.             {
  399.                 if(S[e] != DStime[6 - e] || e>4)
  400.                 {
  401.                     ModifyTime(6 - e, S[e]);
  402.                     DStime[6 - e] = S[e];
  403.                 }
  404.                                 
  405.                 e++;
  406.                 if(e == 3) //跳過調整星期
  407.                     e++;

  408.                 if (e == 5)        //調到分鐘時,秒置零
  409.                 {
  410.                                         S[6]=0;
  411.                             WriteWord_2 (5, 0);
  412.                             WriteWord_2 (6, 0);
  413.                                 }
  414.                 if (e > 5)
  415.                 {
  416.                     ModifyTime(0, 0);
  417.                                         e = 0;
  418.                     TS_Mode = 0;                                //修改退出
  419.                                         tswc=1;                                       
  420.                 }
  421.             }

  422.             if(va)                   //有gps按下即強制校時
  423.             {
  424.                 GetGpsTime();
  425.                 updatetime();
  426.             }
  427.         }

  428.         if(KeyValue == (KEY_VALUE_2 | KEY_DOWN))        //+
  429.         {
  430.             if(TS_Mode)
  431.             {
  432.                 item = S[e];
  433.                 item++;//數加 1
  434.                 Set_DStime(e);
  435.             }
  436.             else //運行中做報時鍵
  437.             {
  438.                 sound = 1;
  439.                 spkcount = 9;
  440.             }
  441.         }
  442.         if(KeyValue == (KEY_VALUE_3 | KEY_DOWN))        //-
  443.         {
  444.             if(TS_Mode)
  445.             {
  446.                 item = S[e];
  447.                                 if(item == 0)
  448.                                 {
  449.                                         if(e==4)
  450.                                                 item=23;
  451.                                          else
  452.                                                 item=59;
  453.                                 }
  454.                                 else
  455.                 item--;//數減 1
  456.                 Set_DStime(e);
  457.             }
  458.                         else
  459.                         {
  460.                                 ss=~ss;         //閃爍
  461.                                 sb=1;
  462.                         }
  463.         }

  464.         if(KeyValue == (KEY_VALUE_4 | KEY_DOWN))        //EXIT
  465.         {
  466.             if(TS_Mode)
  467.             {
  468.                 TS_Mode = 0;                       //退出調時
  469.                 e = 0;                                   //"下一項"計數器清0
  470.                 //updatetime();
  471.                                 tswc=1;
  472.             }
  473.             else
  474.             {
  475.                 SND = ~SND;                          /**  運行模式中 K4 作語音報時切換鍵  **/
  476.                                 bs=1;                                
  477.             }
  478.         }
  479. }

  480. void main()//主函數
  481. {
  482.     u8 Temp, TempT;
  483.     u8 i = 0;
  484.     u8 ee = 0;
  485.     bit d = 0;
  486.     e = 0;
  487.     TempT = Temp = 0;

  488.     init();
  489.     InitDis ();
  490.     InitBps();
  491.     Delayms(100);

  492.     GetDateTime();

  493.     Conversion( DStime[6], DStime[5], DStime[4]);
  494.     DStime[3] = Conver_WEEK( DStime[6], DStime[5], DStime[4]);
  495.     ShowTime(1);

  496.     BLK = 0;
  497.     clrwdt;
  498.         

  499.     while(1)//進入無限循環
  500.     {
  501.         if(TS_Mode  == 0)         //運行模式
  502.         {
  503.             if(F_50ms)        //50ms標志
  504.             {
  505.                 GetDateTime();
  506.                 F_50ms        =        0;
  507.             }

  508.             if(QJ)        //電腦發送的校時信息
  509.             {
  510.                 GetGpsTime();
  511.                 updatetime();
  512.                                 tswc=1;
  513.                 QJ = 0;
  514.             }

  515.             if(Temp != DStime[0]) //不用頻繁更新,有變化才更新一次
  516.             {
  517.                 if(va && TempT != BjTime.Sec) //如果接收到GPRMC有效數據
  518.                 {
  519.                     TempT = BjTime.Sec;
  520.                     if(gpscount++ == 600) //持續有效達10分鐘即自動校時,可根據GPS性能調整
  521.                     {
  522.                         GetGpsTime();
  523.                         updatetime();
  524.                     }
  525.                     if(gpscount > 86400) //若gps掛機超過1天則回零
  526.                         gpscount = 0;
  527.                 }
  528.                 else
  529.                 {
  530.                     gpscount = 0;
  531.                     va = 0;
  532.                 }

  533.                 if(DStime[0] == 0 ||  tswc)  //每分鐘或調時完成全部刷新
  534.                 {
  535.                     if(DStime[1] == 0)        //每小時
  536.                     {
  537.                         //Conversion( DStime[6], DStime[5], DStime[4]);
  538.                         //DStime[3]        = Conver_WEEK( DStime[6], DStime[5], DStime[4]);
  539.                         
  540.                         if(DStime[2] > 6 && DStime[2] < 22 )        //7--21點報時
  541.                         {
  542.                             InitDis ();//每小時初始化一次
  543.                                                         if(!SND )
  544.                                                         {
  545.                                                                 sound = 1;         //整點報時
  546.                                     spkcount = 9;
  547.                                                         }
  548.                         }
  549.                                                 else  //夜間節能模式
  550.                                                 {
  551.                                                         WriteWord_1 (Intensity,0);
  552.                                                         WriteWord_2 (Intensity,0);
  553.                                                         WriteWord_3 (Intensity,0);
  554.                                                 }

  555.                     }
  556.                     Conversion( DStime[6], DStime[5], DStime[4]);
  557.                     DStime[3]        = Conver_WEEK( DStime[6], DStime[5], DStime[4]);
  558.                     ShowTime(1); //每分鐘全部更新一次 ,調整完時間退出后全部更新一次
  559.                     if(tswc)
  560.                     {
  561.                                                 tswc = 0;
  562.                     }
  563.                     
  564.                 }
  565.                 else
  566.                     ShowTime(0);  //只更新秒

  567.                 Temp = DStime[0];

  568.                                 if(sb)
  569.                                 {
  570.                                   Write_02_Data(0,ss);
  571.                                   Delay_50us(40);
  572.                                   sb=0;                                                                  
  573.                                 }
  574.                                 if(ss)
  575.                         BLK=~BLK;          //開啟冒號閃爍
  576.             }
  577.             if(sound && BUSY)
  578.             {
  579.                 baoshi();
  580.                 if(spkcount < 1 || spkcount > 20 )
  581.                     sound = 0; //退出報時
  582.             }
  583.                         if(bs) //報時存儲
  584.                         {
  585.                                   Write_02_Data(2,SND);
  586.                                   Delay_50us(40);
  587.                                   bs=0;
  588.                         }

  589.         }
  590.         else
  591.         {
  592.             //調試狀態,led應閃爍指示調整位
  593.             if(F_500ms)        //500ms標志
  594.             {
  595.                 d = ~d;
  596.                 if(e != ee )   //調整下一項時防止上一項不亮
  597.                 {
  598.                     Led_Flash(ee, 0);
  599.                     ee = e;
  600.                 }
  601.                 Led_Flash(e, d);

  602.                 F_500ms        =        0;
  603.             }
  604.             //if()        //進入調時超過5分鐘后自動退出 (該功能略)
  605.         }
  606.         clrwdt;        //設置看門狗
  607.     }
  608. }

  609. /*-----------------------------日期、時間設置函數-----------------------------*/
  610. //被調數據加一或減一,并檢查數據范圍,寫入3231指定地址保存
  611. void ds_w(u8 sel)
  612. {
  613.     if(item > max) item = mini;         //查看數值是否在有效范圍之內
  614.     if(item < mini) item = max;         //如果數值小于最小值,則自動等于最大值
  615.         S[sel]=item;
  616. }
  617. void Set_DStime(u8 sel)  //根據選擇調整的相應項目加1并寫入DS3231,函數參數是按動設置鍵的次數
  618. {
  619.     if(sel == 3 || sel == 6)  return; //星期不用設置
  620.         /*        秒不用設置,調到分鐘時,秒置零
  621.         if(sel == 6)
  622.     {
  623.         max = 59;
  624.         mini = 0;
  625.         ds_w(sel);                  //被調數據加一或減一函數
  626.     }        
  627.         //秒7,按動7次顯示 調整秒鐘
  628.     //秒鐘數據的最大值是59,最小值是0
  629.         */

  630.     if(sel == 5)
  631.     {
  632.         max = 59;
  633.         mini = 0;
  634.         ds_w(sel);

  635.     }        
  636.         //分鐘6,按動6次顯示 調整分鐘
  637.     //分鐘數據的最大值是59,最小值是0

  638.     if(sel == 4)
  639.     {
  640.         max = 23;
  641.         mini = 0;
  642.         ds_w(sel);

  643.     }        //小時5,按動5次顯示 調整小時
  644.     //小時數據最大值23,最小值是0        

  645.     if(sel == 2)
  646.     {
  647.         if(S[1] == 2 && S[0] % 4 != 0)
  648.         {
  649.             max = 28;    //平年2月28天
  650.             mini = 1;
  651.         }
  652.         if(S[1] == 2 && S[0] % 4 == 0)
  653.         {
  654.             max = 29;    //閏年2月29天
  655.             mini = 1;
  656.         }
  657.         if(S[1] == 1 || S[1] == 3 || S[1] == 5 || S[1] == 7 || S[1] == 8 || S[1] == 10 || S[1] == 12)
  658.         {
  659.             max = 31;    //31天的月份
  660.             mini = 1;
  661.         }
  662.         if(S[1] == 4 || S[1] == 6 || S[1] == 9 || S[1] == 11)
  663.         {
  664.             max = 30;    //30天的月份
  665.             mini = 1;
  666.         }
  667. ……………………

  668. …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼

所有資料51hei提供下載:
萬年歷.7z (3.73 MB, 下載次數: 185)

評分

參與人數 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏17 分享淘帖 頂5 踩
回復

使用道具 舉報

沙發
ID:489631 發表于 2020-10-31 10:42 | 只看該作者
感謝分享,最好能附上原理圖和打板文件
回復

使用道具 舉報

板凳
ID:207943 發表于 2020-10-31 21:49 | 只看該作者
感謝分享,這個有點大
回復

使用道具 舉報

地板
ID:64053 發表于 2021-3-2 01:02 | 只看該作者
一樂原創
回復

使用道具 舉報

5#
ID:884042 發表于 2021-8-19 14:50 | 只看該作者
語音芯片建議用NVC080C系列的,可以改音量,內存也很大,資料上網找
回復

使用道具 舉報

6#
ID:1011444 發表于 2022-5-23 13:20 | 只看該作者
描述的很詳細,樓主辛苦!實際制作大部分都是貼片器件,焊接任務太大了,不易成功,不過還是要謝謝分享
回復

使用道具 舉報

7#
ID:1011444 發表于 2022-6-7 17:52 | 只看該作者
資料豐富齊全,表述清晰明了,多謝分享!
回復

使用道具 舉報

8#
ID:1011444 發表于 2022-7-14 12:13 | 只看該作者
今天仔細看了一遍,感覺大數碼管電源5v電壓似乎驅動不了,四個led串聯至少要有7v以上的電壓才可點亮,如何設計電源?應有詳細描述。
回復

使用道具 舉報

9#
ID:1039479 發表于 2022-7-14 14:16 | 只看該作者
jdf 發表于 2020-10-31 10:42
感謝分享,最好能附上原理圖和打板文件

非常好用
回復

使用道具 舉報

10#
ID:149642 發表于 2022-7-22 09:17 | 只看該作者
kz0018 發表于 2022-5-23 13:20
描述的很詳細,樓主辛苦!實際制作大部分都是貼片器件,焊接任務太大了,不易成功,不過還是要謝謝分享

貼片的最好焊了,膠水粘上熱風槍隨便吹吹就好
回復

使用道具 舉報

11#
ID:1064915 發表于 2023-10-28 17:45 | 只看該作者
請教GPS模塊是哪個?
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 一级免费看片 | a级网站| 国产传媒视频在线观看 | 青青草这里只有精品 | 国产福利在线免费观看 | 精品影院 | 黄色片免费在线观看 | 久久精品一区二区 | 中文字幕乱码亚洲精品一区 | 久久黄色 | 亚洲国产中文字幕 | 免费在线黄 | 无码日韩精品一区二区免费 | 欧美日韩免费 | 少妇精品亚洲一区二区成人 | 欧美自拍视频 | 国产一区二区影院 | 精品视频久久久久久 | 国产午夜在线观看 | 欧美成ee人免费视频 | 国产精品国产a | 国产成人叼嘿视频在线观看 | 国产高清视频一区 | 操人网站 | 亚州成人| 午夜精品 | 久久精品小视频 | 综合中文字幕 | 人人九九精 | 亚洲精品播放 | www.五月天婷婷.com | 久久国产成人精品国产成人亚洲 | 国产高清在线 | 国产一级在线 | 亚洲一区国产 | 91在线播| av天天澡天天爽天天av | 成人在线免费 | 久久精品国产a三级三级三级 | 日韩一区不卡 | 色欧美片视频在线观看 |