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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 11991|回復: 30
收起左側

學習單片機,制作了一臺LED電子鐘

  [復制鏈接]
ID:97023 發表于 2020-3-31 00:39 | 顯示全部樓層 |閱讀模式
  學習單片機一段時間了,一直想做一個東西來驗證一下自己的學習效果,“流水燈”之類覺得太簡單;“示波器”、“掃頻儀”、“LCR”、“晶體管特性曲線儀”等儀器又覺得太難,自己覺得還是制作一個電子鐘難度比較適中。
  只所以選擇制作LED顯示的電子鐘,是因為去年在網上30元買得有96只1寸的LED數碼管,總得把它們消化點才是。當然成功后我還會再制作LCD顯示的電子鐘,那是后話。
  原本想用14個LED數碼管來制作這個電子鐘,讓它直接顯示:年、月、日、時、分、秒,其中“年”用4位,免得再出現當年“千年蟲”的問題,其它通通用兩位,當然還可以多加一位用來顯示“星期”。但這樣一來,這個電子鐘就顯得太寬了,做出來有點龐大。
  最后還是決定按照傳統方法,用6位LED數碼管就行了,用一個按鍵來切換日期與時間的顯示。
  根據以上想法設計的電路原理圖:
00 電路原理圖.png


  要讓鐘走起來不難,網上有很多現成的代碼,關鍵的難點是時鐘的設置(調整)。
  我希望在進入設置狀態時,對應的LED應該能夠閃爍,以提醒我當前設置的是年、月、日、時、分、秒的哪一位(其實都是兩位)?
  由于每位LED數碼管都采用動態顯示,在動態顯示時又如何使某兩位閃爍,一下子沒想通怎么做。
  參考了很多網上的資料以及翻了很多書籍,都沒發現哪一款LED數碼管的電子鐘在設置時間或日期時,對應的LED數碼管能夠閃爍,也許是我沒有看懂別人的代碼。
  想了幾天后終于想到了一個辦法:我們知道,LED數碼管的動態顯示,無非就是在某一個時刻只讓一只LED數碼管亮,其余的LED數碼管是不亮的,下一個時刻才讓下一位LED數碼管亮,循環往復,只要時間足夠快,由于人眼的“視覺暫留”作用,我們看到所有的LED數碼管都是亮著的。
  我的辦法就是:需要閃爍的這兩位LED數碼管,當輪到它們亮時暫時不亮,將亮的機會讓給其它的數碼管,這就使得它們“滅”的時間長一點,能讓眼睛感覺到;輪到它們亮時,就讓它們循環多亮一段時間,它們循環結束以后才將亮的機會交給其它的數碼管。這樣的效果,通過眼睛看到,這兩位數碼管一滅一亮地閃爍起來了。實際情況下,其它數碼管也有輕微的閃爍,但沒有這兩位明顯,眼睛不容易觀察到。
  我就通過這個伎倆用來欺騙眼睛。
  由于機器配置有點低,所以這個效果用Proteus仿真不出來,只有用面包板實際搭電路才行。
  我通過測試,閃爍的數碼管“亮”時,循環4次就夠了,次數多了,其它數碼管就會跟著閃爍起來;次數少了閃爍又不明顯。
  說這么多,只是思路,具體實現看源代碼。
  結構上,采用了4個按紐開關進行控制:
  1、【設置/移動/退出】;
  2、【加】;
  3、【減】;
  4、【確定/翻頁】。
  各按紐功能解說:
  【設置/移動/退出】按紐的功能:
  單擊第①次,進入(設置),第一位(其實是兩個數碼管,下同)閃爍;
  單擊第②次,第二位閃爍;
  單擊第③次,第三位閃爍;
  單擊第④次,下一頁第一位閃爍;
  單擊第⑤次,下一頁第二位閃爍;
  單擊第⑥次,下一頁第三位閃爍;
  單擊第⑦次,退出(設置),進入走時狀態。
  【加】、【減】:只在設置狀態有效;
  【確定/翻頁】:在設置狀態下,保存并退出設置;在走時狀態下,切換日期和時間。
  用面包板搭建的功能驗證電路證實了上述想法。
01 面包板驗證電路.jpg


  在面包板上成功以后,開始成品制作。
  電子鐘由三個模塊組成:顯示板、控制板和電源板。
  顯示板由6個LED數碼管組成,用一塊9×15CM的洞洞板裁成兩塊拼接而成,為了使兩塊洞洞板保持在一個平面,在它們的后面又加了一塊裝修吊頂用的“輕鋼龍骨”作為支撐:
IMG_20190618_095136.jpg

IMG_20190618_095153.jpg

  為了避免焊接錯誤,數碼管相同的段用相同顏色的導線連接。
IMG_20190621_230816.jpg


IMG_20190622_004009.jpg


  七個段由這七個插針輸出
IMG_20190622_004128.jpg


  每一位數碼管的控制由一塊單獨的控制板完成,這塊控制板固定在數碼管背面的“輕鋼龍骨”上,它們構成了完整的顯示模塊,通過插針與單片機主控板連接。
IMG_20190622_095018.jpg


IMG_20190622_103105.jpg

  單片機模塊:
IMG_20190623_213313.jpg


IMG_20190623_213417.jpg

  因為電源是12V的,所以用7805將電壓控制在5V:
IMG_20190623_213911.jpg


  電源模塊采用成品12V/1A開關電源,這種電源在網上1.50元一只(輸出線被剪掉的),我買得有幾十只,另外家人多年來丟棄的各種電源,都被我收集了起來,也有幾十只,不管做什么電子裝置,我都能找到合適的電源。
IMG_20200331_001052.jpg


  各個模塊連接起來工作正常了:
IMG_20190624_170212.jpg


  日期顯示:
IMG_20190626_001444.jpg


  時間顯示:
IMG_20190626_001501.jpg


  用撿來的層板制作外殼:
IMG_20190702_113343.jpg


IMG_20190704_082007.jpg

  外殼全部用白乳膠粘接,沒用一顆釘子。
IMG_20190705_084345.jpg


IMG_20190706_162320.jpg

IMG_20190707_133204.jpg


IMG_20190708_233139.jpg

  貼上黑胡桃木的貼皮美化一下:
IMG_20190720_142536.jpg

  內部布局:
IMG_20190720_142543.jpg

  開關電源的PCB板很小,不好單獨固定,我是將電源外殼鋸掉一部分,利用它內部的卡槽來固定電源。
IMG_20190720_142618.jpg

  右下角那片軟包裝鋰電池是3.7V/180mAh的,在不使用電子鐘時給DS1302供電,以免丟失設置好的時間。
IMG_20190720_142626.jpg


IMG_20190720_142738.jpg
  后蓋板的螺絲孔與里面的螺帽對得很正,我是怎么做到的?給大家分享一點經驗:先在后蓋板適當位置鉆孔,這時只需注意孔的中心與左右邊緣的距離等于螺帽的半徑,也就是說,螺帽應該緊貼著側面板外沿,這個可以用尺子測量畫線再鉆孔;然后將4顆螺絲與螺帽固定在后蓋板上,在前面板還空著的情況下,將后蓋板小心地在后邊推到位,用一根長一點的竹簽粘少許兌好的AB膠,從前面窗口伸進去,將它們涂到螺帽與側面板之間,這時不需要涂多少,只要能將它們粘住就行,等幾個小時AB膠固化后,再將后蓋板及螺絲一同拆下來,這時螺帽就已經粘在側面板上了。再次兌一些AB膠,將螺帽與側面板膠水不足的地方補足即可。
  如果你有更好的方法,就當我沒說。
  薄膜開關的功能定義:
薄膜開關.png


IMG_20200328_221527.jpg

原理圖及代碼:
LED數碼管電子鐘.rar (60.08 KB, 下載次數: 144)

評分

參與人數 2黑幣 +60 收起 理由
王朗的誘惑 + 10 優雅
admin + 50 共享資料的黑幣獎勵!

查看全部評分

回復

使用道具 舉報

ID:328014 發表于 2020-3-31 01:06 | 顯示全部樓層
好東東啊 下面是樓主的主程序:
  1. /*******************************************************
  2. 功能:LED數碼管電子鐘
  3. *******************************************************/
  4. #include <reg52.h>
  5. #include <intrins.h>

  6. #define uchar unsigned char
  7. #define uint unsigned int

  8. //函數定義
  9. void DelayMS(uint x);                                                //延時 xms(晶振:11.0592MHz,)
  10. uchar Get_A_Byte_FROM_DS1302();                                //從DS1302讀取一個字節
  11. uchar Read_Data( uchar addr );                                //從DS1302指定位置讀數據
  12. void Write_A_Byte_TO_DS1302( uchar x );                //向DS1302寫入一個字節
  13. void Write_DS1302( uchar addr, uchar dat );        //向DS1302某地址寫數據
  14. void SET_DS1302();                                                        //設置日期時間
  15. void GetTime();                                                                //讀取當前時間日期
  16. void LedDisplay();                                                        //顯示數據
  17. void Scan_Key();                                                        //掃描鍵盤
  18. void Init();                                                                //系統初始化
  19. void Play();                                                                //蜂鳴器發音
  20. void Format_DS1302();                                                //日期格式化

  21. sbit RST = P3^5;                        //DS1302復位線
  22. sbit SDA = P3^6;                        //DS1302數據線
  23. sbit CLK = P3^7;                        //DS1302時鐘線

  24. sbit NOT = P3^4;                        //日期分隔小數點和時間分隔冒號(1-冒號亮、0-小數點亮)

  25. sbit BEEP = P1^7;                        //蜂鳴器輸出端口

  26. uchar Current_Time[7];                //保存所讀取的日期時間(秒分時日月周年)
  27. uchar Display_Buffer[12];   //處理過的日期時間,用于數碼管顯示

  28. uchar DelayTwinkle = 5;                //閃爍延時長度,原200
  29. uchar TimeTwinkle = 4;                //閃爍顯示時間,原30
  30. uchar WeiTwinkle = 0;                //閃爍的位
  31. uchar TimeShake = 100;                //去抖動延時時間長度

  32. uint BeepTime = 0;                //蜂鳴器響一次的間隔時間

  33. uint Set_State = 0;                        //0:走時狀態、1:設置狀態。
  34. bit DateTime_State = 0;                //0:顯示時間、1:顯示日期。
  35. uint Count = 0;                                //記錄“K_Setup”的狀態

  36. //按鍵定義
  37. sbit K_Setup        = P1^2;                //設置/移動/退出
  38. sbit K_Add                = P1^3;                //加1
  39. sbit K_Sub                = P1^0;                //減1
  40. sbit K_OK                = P1^1;                //保存并退出/翻頁
  41. sbit K_GND                = P1^4;                //由于薄膜開關的原因,此腳定義為地。

  42. sbit K_FORMAT        = P1^5;                //格式化(使日期時間內容為:2019-06-17 12:00:00)

  43. //共陽LED數碼管位碼(從左到右:1、2、3、4、5、6)
  44. //用PNP管驅動
  45. code uchar WEI_CODE [] =
  46. {
  47.         0xFE,                //1          11111110
  48.         0xFD,                //2          11111101
  49.         0xFB,                //3          11111011
  50.         0xF7,                //4          11110111
  51.         0xEF,                //5          11101111
  52.         0xDF                //6          11011111
  53. };

  54. //共陽LED數碼管段碼
  55. code uchar DSY_CODE [] =
  56. {
  57.         0x40,                //0
  58.         0x79,                //1
  59.         0x24,                //2
  60.         0x30,                //3
  61.         0x19,                //4
  62.         0x12,                //5
  63.         0x02,                //6
  64.         0x78,                //7
  65.         0x00,                //8
  66.         0x10                //9
  67. };

  68. // 延時 xms(晶振:11.0592MHz,)
  69. void DelayMS(uint x)
  70. {
  71.         uchar i;
  72.         while( x-- )
  73.         {
  74.                 for( i=0; i<111; i++ );
  75.         }
  76. }

  77. //蜂鳴器發音
  78. void Play()
  79. {
  80.         uchar i, j;
  81.         for( i = 0; i < 250; i++ )
  82.         {
  83.                 BEEP = ~BEEP;
  84.                 for (j = 0; j < 30; j++ )
  85.                 {
  86.                         _nop_();                //延時時間長短決定發音頻率
  87.                 }
  88.         }
  89.         BEEP = 0;
  90. }                                                                                                           

  91. //從DS1302讀取一個字節
  92. uchar Get_A_Byte_FROM_DS1302()
  93. {
  94.         uchar i,b,t;
  95.         for ( i = 0; i < 8; i++ )
  96.         {
  97.                 b >>= 1;
  98.                 t = SDA;
  99.                 b |= t << 7;
  100.                 CLK = 1;
  101.                 CLK = 0;
  102.         }
  103.         //BCD碼轉換
  104.         return b / 16 * 10 + b % 16;
  105. }

  106. //從DS1302指定位置讀數據
  107. uchar Read_Data( uchar addr )
  108. {
  109.         uchar dat;
  110.         RST = 0;
  111.         CLK = 0;
  112.         RST = 1;
  113.         Write_A_Byte_TO_DS1302( addr );
  114.         dat = Get_A_Byte_FROM_DS1302();
  115.         CLK = 1;
  116.         RST = 0;
  117.         return dat;
  118. }

  119. //向DS1302寫入一個字節
  120. void Write_A_Byte_TO_DS1302( uchar x )
  121. {
  122.         uchar i;
  123.         for ( i = 0; i < 8; i++ )
  124.         {
  125.                 SDA = x & 1;
  126.                 CLK = 1;
  127.                 CLK = 0;
  128.                 x >>= 1;
  129.         }
  130. }

  131. //向DS1302某地址寫數據
  132. void Write_DS1302( uchar addr, uchar dat )
  133. {
  134.         CLK = 0;
  135.         RST = 1;
  136.         Write_A_Byte_TO_DS1302( addr );
  137.         Write_A_Byte_TO_DS1302( dat );
  138.         CLK = 0;
  139.         RST = 0;
  140. }

  141. //設置日期時間,括號里面是地址
  142. //秒(0x80)分(0x82)時(0x84)日(0x86)月(0x88)周(0x8a)年(0x8c)
  143. void SET_DS1302()
  144. {
  145.         uchar i;
  146.         Write_DS1302( 0x8E, 0x00 );        //寫控制字,取消寫保護
  147.         for ( i = 0; i < 7; i++ )
  148.         {
  149.                 Write_DS1302( 0x80 + 2 * i, ( Current_Time[i] / 10 << 4 ) | ( Current_Time[i] % 10 ) );
  150.         }
  151.         Write_DS1302( 0x8E, 0x80 );        //加保護
  152. }

  153. //日期格式化,使日期時間值為合法數據(使日期時間內容為:2019-06-20 12:00:00)
  154. void Format_DS1302()
  155. {
  156.         Current_Time[0] = 0x00;                //秒
  157.         Current_Time[1] = 0x00;                //分
  158.         Current_Time[2] = 0x0C;                //12小時
  159.         Current_Time[3] = 0x14;                //20日
  160.         Current_Time[4] = 0x06;                //06月
  161.         Current_Time[5] = 0x05;                //周5(星期日是一周的開始)
  162.         Current_Time[6] = 0x13;                //19年
  163.         
  164.         SET_DS1302();
  165. }

  166. //讀取當前時間日期(秒、分、時、日、月、周、年)
  167. //將讀取到的日期時間保存到顯示緩沖區中。
  168. //運行時間約 2.4ms
  169. void GetTime()
  170. {
  171.         uchar i;
  172.         for ( i = 0; i < 7; i++ )
  173.         {
  174.                 Current_Time[i] = Read_Data( 0x81 + 2 * i );
  175.         }
  176.         Display_Buffer[0] = DSY_CODE[ Current_Time[2] / 10 ];           //小時的十位
  177.         Display_Buffer[1] = DSY_CODE[ Current_Time[2] % 10 ];           //小時的個位
  178.         Display_Buffer[2] = DSY_CODE[ Current_Time[1] / 10 ];           //分的十位
  179.         Display_Buffer[3] = DSY_CODE[ Current_Time[1] % 10 ];           //分的個位
  180.         Display_Buffer[4] = DSY_CODE[ Current_Time[0] / 10 ];           //秒的十位
  181.         Display_Buffer[5] = DSY_CODE[ Current_Time[0] % 10 ];           //秒的個位

  182.         Display_Buffer[6] = DSY_CODE[ Current_Time[6] / 10 ];           //年的十位
  183.         Display_Buffer[7] = DSY_CODE[ Current_Time[6] % 10 ];           //年的個位
  184.         Display_Buffer[8] = DSY_CODE[ Current_Time[4] / 10 ];           //月的十位
  185.         Display_Buffer[9] = DSY_CODE[ Current_Time[4] % 10 ];           //月的個位
  186.         Display_Buffer[10] = DSY_CODE[ Current_Time[3] / 10 ];           //日的十位
  187.         Display_Buffer[11] = DSY_CODE[ Current_Time[3] % 10 ];           //日的個位
  188.         Display_Buffer[12] = DSY_CODE[ Current_Time[5] - 1 ];           //周的個位(星期日是一周的開始)
  189. }

  190. //顯示數據(運行時間約 12ms)
  191. void LedDisplay()
  192. {
  193.         uchar i;
  194.         if ( Set_State == 0 )                //走時狀態
  195.         {
  196.                 WeiTwinkle = 0;
  197.                 if ( DateTime_State == 0 )                        //顯示時間
  198.                 {
  199.                         NOT = 1;
  200.                         for ( i = 0; i < 6; i++ )
  201.                         {
  202.                                 P2 = WEI_CODE[ i ];
  203.                                 P0 = Display_Buffer[ i ];
  204.                                 DelayMS(1);
  205.                                 P2 = 0xFF;
  206.                                 P0 = 0xFF;
  207.                                 DelayMS(1);
  208.                         }
  209.                 }
  210.                 else                        //顯示日期
  211.                 {
  212.                         NOT = 0;
  213.                         for ( i = 0; i < 6; i++ )
  214.                         {
  215.                                 P2 = WEI_CODE[ i ];
  216.                                 P0 = Display_Buffer[ i + 6 ];
  217.                                 DelayMS(1);
  218.                                 P2 = 0xFF;
  219.                                 P0 = 0xFF;
  220.                                 DelayMS(1);
  221.                         }
  222.                 }
  223.         }
  224.         else                //設置狀態
  225.         {
  226.                 uchar j,k;
  227.                 if ( DateTime_State == 0 )                        //顯示時間
  228.                 {
  229.                         NOT = 1;
  230.                         for ( i = 0; i < 6; i++ )
  231.                         {
  232.                                 if ( i != WeiTwinkle &&  i != WeiTwinkle + 1 )         //不閃爍的位
  233.                                 {
  234.                                         P2 = WEI_CODE[ i ];
  235.                                         P0 = Display_Buffer[ i ];
  236.                                         DelayMS(1);
  237.                                 }
  238.                                 else if ( j > DelayTwinkle )   //閃爍的位(2位)
  239.                                 {
  240.                                         for ( k = 0; k < TimeTwinkle; k++ )
  241.                                         {
  242.                                                 P2 = WEI_CODE[ i ];
  243.                                                 P0 = Display_Buffer[ i ];
  244.                                                 DelayMS( 1 );
  245.                                                 P2 = WEI_CODE[ i + 1 ];
  246.                                                 P0 = Display_Buffer[ i + 1 ];
  247.                                                 DelayMS( 1 );
  248.                                         }
  249.                                         j = 0;
  250.                                 }
  251.                                 P2 = 0xFF;
  252.                                 P0 = 0xFF;
  253.                                 DelayMS(1);
  254.                                 j++;
  255.                         }
  256.                 }
  257.                 else                        //顯示日期
  258.                 {
  259.                         NOT = 0;
  260.                         for ( i = 0; i < 6; i++ )
  261.                         {
  262.                                 if ( i != WeiTwinkle &&  i != WeiTwinkle + 1 )         //不閃爍的位
  263.                                 {
  264.                                         P2 = WEI_CODE[ i ];
  265.                                         P0 = Display_Buffer[ i + 6 ];
  266.                                         DelayMS(2);
  267.                                 }
  268.                                 else if ( j > DelayTwinkle )   //閃爍的位(2位)
  269.                                 {
  270.                                         for ( k = 0; k < TimeTwinkle; k++ )
  271.                                         {
  272.                                                 P2 = WEI_CODE[ i ];
  273.                                                 P0 = Display_Buffer[ i + 6 ];
  274.                                                 DelayMS( 1 );
  275.                                                 P2 = WEI_CODE[ i+1 ];
  276.                                                 P0 = Display_Buffer[ i + 7 ];
  277.                                                 DelayMS( 1 );
  278.                                         }
  279.                                         j = 0;
  280.                                 }
  281.                                 P2 = 0xFF;
  282.                                 P0 = 0xFF;
  283.                                 DelayMS(1);
  284.                                 j++;
  285.                         }
  286.                 }
  287.         }
  288. }

  289. //掃描鍵盤
  290. void Scan_Key()
  291. {
  292.         //設置
  293.         if ( K_Setup == 0 )        
  294.         {
  295.                 DelayMS( TimeShake );                   //去抖動
  296.                 if ( K_Setup == 0 )
  297.                 {
  298.                         Set_State ++;

  299.                         if ( Set_State > 6 )
  300.                         {
  301.                                 Set_State = 0;
  302.                                 DateTime_State = 0;
  303.                                 WeiTwinkle = 0;
  304.                         }
  305.                         else
  306.                         {
  307.                                 switch ( Set_State )
  308.                                 {
  309.                                         case 0:
  310.                                                 WeiTwinkle = 0;
  311.                                                 break;
  312.                                         case 1:
  313.                                                 WeiTwinkle = 0;
  314.                                                 break;
  315.                                         case 2:
  316.                                                 WeiTwinkle = 2;
  317.                                                 break;
  318.                                         case 3:
  319.                                                 WeiTwinkle = 4;
  320.                                                 break;
  321.                                         case 4:
  322.                                                 WeiTwinkle = 0;
  323.                                                 break;
  324.                                         case 5:
  325.                                                 WeiTwinkle = 2;
  326.                                                 break;
  327.                                         case 6:
  328.                                                 WeiTwinkle = 4;
  329.                                                 break;
  330.                                 }

  331.                                 if ( Set_State < 4 )
  332.                                 {
  333.                                         DateTime_State = 0;                //第一頁,顯示時間
  334.                                 }
  335.                                 else
  336.                                 {
  337.                                         DateTime_State = 1;                //第二頁,顯示日期
  338.                                 }
  339.                         }
  340.                         DelayMS(1);
  341.                         Play();
  342.                 }
  343.         }
  344.         
  345.         //在設置時才能操作的按鍵
  346.         if ( Set_State != 0 )
  347.         {
  348.                 //調時:增加(設置狀態有效)
  349.                 if ( K_Add == 0 )        
  350.                 {
  351.                         DelayMS( TimeShake );                   //去抖動
  352.                         if ( K_Add == 0 )
  353.                         {
  354.                                 switch( WeiTwinkle )
  355.                                 {
  356.                                         case 0:                //時/年
  357.                                                 if ( DateTime_State == 0 )
  358.                                                 {                        //小時
  359.                                                         Current_Time[2]++;
  360.                                                         if ( Current_Time[2] > 23 )
  361.                                                         {
  362.                                                                 Current_Time[2] = 0;
  363.                                                         }
  364.                                                         Display_Buffer[0] = DSY_CODE[ Current_Time[2] / 10 ];
  365.                                                         Display_Buffer[1] = DSY_CODE[ Current_Time[2] % 10 ];
  366.                                                 }
  367.                                                 else
  368.                                                 {                        //年
  369.                                                         Current_Time[6]++;
  370.                                                         Display_Buffer[6] = DSY_CODE[ Current_Time[6] / 10 ];
  371.                                                         Display_Buffer[7] = DSY_CODE[ Current_Time[6] % 10 ];
  372.                                                 }
  373.                                                 break;
  374.                                         case 2:                //分/月
  375.                                                 if ( DateTime_State == 0 )
  376.                                                 {                //分
  377.                                                         Current_Time[1]++;
  378.                                                         if ( Current_Time[1] > 59 )
  379.                                                         {
  380.                                                                 Current_Time[1] = 0;
  381.                                                         }
  382.                                                         Display_Buffer[2] = DSY_CODE[ Current_Time[1] / 10 ];
  383.                                                         Display_Buffer[3] = DSY_CODE[ Current_Time[1] % 10 ];
  384.                                                 }
  385.                                                 else
  386.                                                 {                //月
  387.                                                         Current_Time[4]++;
  388.                                                         if ( Current_Time[4] > 12 )
  389.                                                         {
  390.                                                                 Current_Time[4] = 1;
  391.                                                         }
  392.                                                         Display_Buffer[8] = DSY_CODE[ Current_Time[4] / 10 ];
  393.                                                         Display_Buffer[9] = DSY_CODE[ Current_Time[4] % 10 ];
  394.                                                 }
  395.                                                 break;
  396.                                         case 4:                //秒/日
  397.                                                 if ( DateTime_State == 0 )
  398.                                                 {                //秒
  399.                                                         Current_Time[0]++;
  400.                                                         if ( Current_Time[0] > 59 )
  401.                                                         {
  402.                                                                 Current_Time[0] = 0;
  403.                                                         }
  404.                                                         Display_Buffer[4] = DSY_CODE[ Current_Time[0] / 10 ];
  405.                                                         Display_Buffer[5] = DSY_CODE[ Current_Time[0] % 10 ];
  406.                                                 }
  407.                                                 else
  408.                                                 {                //日
  409.                                                         Current_Time[3]++;
  410.                                                         if ( Current_Time[3] > 31 )
  411.                                                         {
  412.                                                                 Current_Time[3] = 1;
  413.                                                         }
  414.                                                         Display_Buffer[10] = DSY_CODE[ Current_Time[3] / 10 ];
  415.                                                         Display_Buffer[11] = DSY_CODE[ Current_Time[3] % 10 ];
  416.                                                 }
  417.                                                 break;
  418.                                 }
  419.                                 Play();
  420.                         }
  421.                 }

  422.                 //調時:減小(設置狀態有效)
  423.                 if ( K_Sub == 0 )        
  424.                 {
  425.                         DelayMS( TimeShake );                   //去抖動
  426.                         if ( K_Sub == 0 )
  427.                         {
  428.                                 switch( WeiTwinkle )
  429.                                 {
  430.                                         case 0:                //時/年
  431.                                                 if ( DateTime_State == 0 )
  432.                                                 {                        //小時
  433.                                                         Current_Time[2]--;
  434.                                                         if ( Current_Time[2] < 0 )
  435.                                                         {
  436.                                                                 Current_Time[2] = 23;
  437.                                                         }
  438.                                                         Display_Buffer[0] = DSY_CODE[ Current_Time[2] / 10 ];
  439.                                                         Display_Buffer[1] = DSY_CODE[ Current_Time[2] % 10 ];
  440.                                                 }
  441.                                                 else
  442.                                                 {                        //年
  443.                                                         Current_Time[6]--;
  444.                                                         if ( Current_Time[6] < 0 )
  445.                                                         {
  446.                                                                 Current_Time[6] = 0;
  447.                                                         }
  448.                                                         Display_Buffer[6] = DSY_CODE[ Current_Time[6] / 10 ];
  449.                                                         Display_Buffer[7] = DSY_CODE[ Current_Time[6] % 10 ];
  450.                                                 }
  451.                                                 break;
  452.                                         case 2:                //分/月
  453.                                                 if ( DateTime_State == 0 )
  454.                                                 {                //分
  455.                                                         Current_Time[1]--;
  456.                                                         if ( Current_Time[1] < 0 )
  457.                                                         {
  458.                                                                 Current_Time[1] = 59;
  459.                                                         }
  460.                                                         Display_Buffer[2] = DSY_CODE[ Current_Time[1] / 10 ];
  461.                                                         Display_Buffer[3] = DSY_CODE[ Current_Time[1] % 10 ];
  462.                                                 }
  463.                                                 else
  464.                                                 {                //月
  465.                                                         Current_Time[4]--;
  466.                                                         if ( Current_Time[4] <= 0 )
  467.                                                         {
  468.                                                                 Current_Time[4] = 12;
  469.                                                         }
  470.                                                         Display_Buffer[8] = DSY_CODE[ Current_Time[4] / 10 ];
  471.                                                         Display_Buffer[9] = DSY_CODE[ Current_Time[4] % 10 ];
  472.                                                 }
  473.                                                 break;
  474.                                         case 4:                //秒/日
  475.                                                 if ( DateTime_State == 0 )
  476.                                                 {                //秒
  477.                                                         Current_Time[0]--;
  478.                                                         if ( Current_Time[0] < 0 )
  479.                                                         {
  480.                                                                 Current_Time[0] = 59;
  481.                                                         }
  482.                                                         Display_Buffer[4] = DSY_CODE[ Current_Time[0] / 10 ];
  483.                                                         Display_Buffer[5] = DSY_CODE[ Current_Time[0] % 10 ];
  484.                                                 }
  485.                                                 else
  486.                                                 {                //日
  487.                                                         Current_Time[3]--;
  488.                                                         if ( Current_Time[3] <= 0 )
  489.                                                         {
  490.                                                                 Current_Time[3] = 31;
  491.                                                         }
  492.                                                         Display_Buffer[10] = DSY_CODE[ Current_Time[3] / 10 ];
  493.                                                         Display_Buffer[11] = DSY_CODE[ Current_Time[3] % 10 ];
  494.                                                 }
  495.                                                 break;
  496.                                 }
  497.                                 Play();
  498.                         }
  499.                 }
  500.         
  501.                 //保存數據并退回到走時狀態(設置狀態有效)
  502.                 if ( K_OK == 0 )         
  503.                 {
  504.                         DelayMS( TimeShake );                   //去抖動
  505.                         if ( K_OK == 0 )
  506.                         {
  507.                                 SET_DS1302();
  508.                                 Set_State = 0;
  509.                                 Play();
  510.                         }
  511.                 }

  512.                 //日期格式化,使日期時間值為合法數據(這個按鍵不安裝在機殼上,如要操作,直接用杜邦線短接既可。)
  513.                 if ( K_FORMAT == 0 )
  514.                 {
  515.                         DelayMS( TimeShake );
  516.                         if ( K_FORMAT == 0 )
  517.                         {
  518.                                 Format_DS1302();
  519.                                 Set_State = 0;
  520.                         }
  521.                 }
  522.         }
  523.         else
  524.         {
  525.                 //走時狀態(切換日期與時間)
  526.                 if ( K_OK == 0 )         
  527.                 {
  528.                         DelayMS( TimeShake );                   //去抖動
  529.                         if ( K_OK == 0 )
  530.                         {
  531.                                 DateTime_State = ~DateTime_State;
  532.                                 DelayMS(1);
  533.                                 Play();
  534.                         }
  535.                 }
  536.         }
  537. }

  538. //判斷是否是閏年
  539. //uchar isLeapYear(uint y)
  540. //{
  541. //        return ( y % 4 == 0 && y % 100 != 0 ) || ( y % 400 == 0 );
  542. //}

  543. //系統初始化
  544. //T0 用于鍵盤掃描,每50ms一次。
  545. void Init()
  546. {
  547.         K_GND = 0;                //薄膜開關的地。
  548.         TMOD = 0x01;        //設置定時器0、1為工作方式1
  549.         TH0 = 0;                //65.536ms
  550.         TL0 = 0;
  551.         ET0 = 1;        //允許定時器0
  552.         TR0 = 1;        //啟動定時器0
  553.         EA = 1;                //全局中斷開
  554. }

  555. //主函數
  556. void main()
  557. {
  558.         Init();
  559.         while(1)
  560.         {
  561.                 if ( Set_State == 0 )        //走時狀態
  562.                 {
  563.                         GetTime();                        //讀取時間數據(運行時間約 2.4ms)
  564.                 }
  565.                 LedDisplay();
  566.         }
  567. }

  568. //定時器0中斷
  569. void Time0() interrupt 1
  570. {
  571.         TR0 = 0;        //關閉定時器0
  572.         Scan_Key();                  //掃描鍵盤
  573.         TH0 = 0;                //65.536ms產生一次中斷
  574.         TL0 = 0;
  575.         TR0 = 1;        //啟動定時器0
  576. }

  577. //定時器1中斷
  578. //控制蜂鳴器2秒響一聲
  579. //void Time1() interrupt 3
  580. //{
  581. //        TR1 = 0;
  582. //        if ( BeepTime >= 40 )
  583. //        {
  584. ////                Play();
  585. //                BeepTime = 0;
  586. //        }
  587. //        BeepTime++;
  588. //        TH1 = ( 65536 - 50000 ) / 256;
  589. //        TL1 = ( 65536 - 50000 ) % 256;
  590. //        TR1 = 1;
  591. //}
復制代碼
回復

使用道具 舉報

ID:141556 發表于 2020-3-31 08:29 | 顯示全部樓層
手工真好。
回復

使用道具 舉報

ID:691573 發表于 2020-3-31 09:08 | 顯示全部樓層
不錯不錯,贊一個!!!!好資料,51黑有你更精彩!!!
回復

使用道具 舉報

ID:284488 發表于 2020-3-31 09:09 | 顯示全部樓層
好東東啊!謝謝樓主的分享。
回復

使用道具 舉報

ID:388929 發表于 2020-3-31 10:28 | 顯示全部樓層
動手能力強,不錯,而已很漂亮
回復

使用道具 舉報

ID:342822 發表于 2020-3-31 13:00 | 顯示全部樓層
數碼管前貼黑膜~~~
回復

使用道具 舉報

ID:143767 發表于 2020-3-31 17:30 | 顯示全部樓層
有定鬧功能嗎?
回復

使用道具 舉報

ID:97023 發表于 2020-3-31 21:56 | 顯示全部樓層

暫時沒有,包括日期、時間設置都還沒有進行限制。
回復

使用道具 舉報

ID:97023 發表于 2020-3-31 21:57 | 顯示全部樓層
taotie 發表于 2020-3-31 13:00
數碼管前貼黑膜~~~

謝謝,還沒想到這一點。
回復

使用道具 舉報

ID:584814 發表于 2020-4-2 10:36 | 顯示全部樓層
手工能力超贊
回復

使用道具 舉報

ID:116662 發表于 2020-4-4 20:17 | 顯示全部樓層
這需要時間呀,多謝樓主分享
回復

使用道具 舉報

ID:282850 發表于 2020-4-8 17:14 | 顯示全部樓層
裝1個DS18B20測溫,如果用2個,一個測室外溫度,一個測室內。我經常出門才知道衣服不夠。
DS18b20精度、可靠性極高。程序想必你有了,如需要,我發給你。當然如果用無線把室外溫度傳來更好,推薦nrf24L01,不過MCU要低功耗的。
回復

使用道具 舉報

ID:34298 發表于 2020-4-8 20:32 | 顯示全部樓層
費勁做的最后時間誤差太大 還是扔了 換成ds3231吧
回復

使用道具 舉報

ID:690448 發表于 2020-4-8 21:54 | 顯示全部樓層
樓主手藝好,殼子漂亮,但是瓤子太單調,建議換我這個方案。

20200323_135350.jpg



20200323_150835.jpg




101.jpg

評分

參與人數 1黑幣 +10 收起 理由
王朗的誘惑 + 10 優雅

查看全部評分

回復

使用道具 舉報

ID:630491 發表于 2020-4-13 18:58 | 顯示全部樓層
推薦樓主學習ad,這樣的話設計出pcb直接交付制作,這樣只需要焊接元件,不需要焊接線路了
回復

使用道具 舉報

ID:704585 發表于 2020-4-16 10:05 | 顯示全部樓層
多謝樓主分享。
回復

使用道具 舉報

ID:66679 發表于 2020-4-18 21:55 | 顯示全部樓層

不錯不錯,贊一個!!!!好資料,51黑有你更精彩!!!
回復

使用道具 舉報

ID:97023 發表于 2020-4-27 00:42 | 顯示全部樓層
1679079206 發表于 2020-4-13 18:58
推薦樓主學習ad,這樣的話設計出pcb直接交付制作,這樣只需要焊接元件,不需要焊接線路了

謝謝推薦,其實AD我會的,只是平時制作一些小東西,專門去打板有點不劃算。
年青時候不喜歡洞洞板,覺得一邊焊接,一邊思考,太痛苦了,特別是焊接好了以后要拆下來,更難。
最近幾年接觸到了洞洞板布線軟件:LochMaster 4.0,先規劃再焊接,這樣輕松多了,目前對我來說用洞洞板制作是一種享受。至于打板,等今后制作更復雜的東西再說吧。
對你的《USB轉TTL模塊制作》文章很感興趣,期待著更新。
回復

使用道具 舉報

ID:128463 發表于 2020-5-25 16:45 | 顯示全部樓層
多謝樓主分享!!!
回復

使用道具 舉報

ID:430492 發表于 2020-5-25 19:15 | 顯示全部樓層
做得不錯,動手能力很棒啊!
回復

使用道具 舉報

ID:743028 發表于 2020-5-26 10:35 來自手機 | 顯示全部樓層
收藏一下
回復

使用道具 舉報

ID:56960 發表于 2020-8-3 14:22 | 顯示全部樓層
樓主強大,木制機箱是亮點,榫鉚結構!
回復

使用道具 舉報

ID:23303 發表于 2021-9-21 15:50 | 顯示全部樓層
下載學習一下,謝謝樓主分享!
回復

使用道具 舉報

ID:908826 發表于 2021-9-21 16:58 | 顯示全部樓層
博主可以試試ds3231,這玩意還有溫度采集功能。我覺得挺好用的
回復

使用道具 舉報

ID:1011444 發表于 2022-6-30 20:43 | 顯示全部樓層
樓主的動手能力,一個字“棒”,三個字“非常棒”,做出的產品幾乎達到適用的機制水平,這對手工制作電子產品的電子業余愛好者來說,要做到是非常不容易。我也是diy愛好者,業余時間學點兒單片機知識,樓主應為我的學習的榜樣。多謝了
回復

使用道具 舉報

ID:832201 發表于 2022-7-3 23:35 | 顯示全部樓層
佩服,
回復

使用道具 舉報

ID:870445 發表于 2022-7-31 12:46 | 顯示全部樓層
看到這個 真不錯,正想做一個,謝謝了
回復

使用道具 舉報

ID:1064667 發表于 2023-7-25 17:19 | 顯示全部樓層
真不錯,花了不少時間吧
回復

使用道具 舉報

ID:397054 發表于 2023-7-29 17:49 | 顯示全部樓層
同好啊,前兩年我也做了個,形式跟你這個差不多,呵呵:

開工

開工


焊接中

焊接中



基本焊好

基本焊好



去年電路板上斷了根線,缺比劃,一直沒功夫弄它,放在書架上吃了不少灰,前幾天把它翻出來打算弄好那根線并修改一下程序:

51hei圖片_20230729173223.jpg

回復

使用道具 舉報

ID:1089276 發表于 2023-7-30 06:48 | 顯示全部樓層
相當的牛叉
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 国产精品视频在线播放 | 羞羞网站免费 | 免费视频久久 | 欧美一区二区在线观看 | 在线视频一区二区三区 | 美女操网站 | 欧美日韩久 | 99视频网| 国产精品99久久久久久久vr | 日韩一区二区三区在线看 | 亚洲一区在线免费观看 | 羞羞在线视频 | 亚洲国产aⅴ成人精品无吗 亚洲精品久久久一区二区三区 | 国产成人午夜精品影院游乐网 | 日韩五月天| 一区二区三区欧美大片 | 国产亚洲欧美在线 | 日韩成人在线电影 | 91视频网| www.久| 成年免费视频 | 中文精品视频 | 久久久.com| 欧美久久天堂 | 天天操天天插 | a视频在线观看 | 91在线观看视频 | 中文无码日韩欧 | 成人国产精品 | 国产午夜精品久久久 | 在线观看国产精品视频 | 亚洲精品电影网在线观看 | 91麻豆蜜桃一区二区三区 | 五月天婷婷狠狠 | 99精品一区二区三区 | 一区二区三区视频在线免费观看 | 午夜不卡福利视频 | 中文字幕亚洲一区二区三区 | 亚洲精品久久久一区二区三区 | 久久精品一二三影院 | 亚av在线|