找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 15125|回復(fù): 30
打印 上一主題 下一主題
收起左側(cè)

紅外遙控單片機(jī)數(shù)碼管時(shí)鐘制作

  [復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
#
ID:76686 發(fā)表于 2015-4-11 22:35 | 只看該作者 回帖獎(jiǎng)勵(lì) |正序?yàn)g覽 |閱讀模式
      初學(xué)單片機(jī)的菜鳥們,都很想自己制作一款單片機(jī)電子鐘,放在自己的電腦桌上,展現(xiàn)一下學(xué)習(xí)單片機(jī)的成果,現(xiàn)在就來(lái)講一講制作這款遙控單片機(jī)數(shù)碼管時(shí)鐘的過(guò)程。單片機(jī)采用STC89C52RC單片機(jī),時(shí)鐘芯片采用DS1302控時(shí),18B20采集溫度,紅外遙控(通用電視機(jī)頂盒遙控器),萬(wàn)年歷顯示,一路鬧鐘,自動(dòng)/手動(dòng)切換顯示,超低功耗掉電工作模式(適合電池供電),擁有備用電源掉電不掉時(shí)。數(shù)碼管經(jīng)消影處理,亮度顯示均勻,兩個(gè)二位一體數(shù)碼管是互相倒過(guò)來(lái)安裝的,從而讓兩個(gè)小數(shù)點(diǎn)在中間形成一個(gè)冒號(hào)。完整程序下載: 遙控單片機(jī)數(shù)碼管時(shí)鐘程序(無(wú)鬧鐘版).rar (47.93 KB, 下載次數(shù): 292)




       測(cè)量溫度時(shí)的情況:




        制作一款單片機(jī)電子鐘需要那些元器件呢?請(qǐng)看下圖,所需要的元件名稱、外形及數(shù)量都在圖中。



        數(shù)碼管的選擇,本作品要選用的是二位一體共陽(yáng)極0.56寸數(shù)碼管,下圖有兩種二位一體共陽(yáng)極數(shù)碼管,但左邊的共有18個(gè)引腳,右邊的只有10個(gè),為了方便布線,我們選擇右邊的10引腳哪種數(shù)碼管。數(shù)碼管的引腳,本作品將兩個(gè)數(shù)碼管相倒安裝,所以其引腳順序也不一樣了,請(qǐng)對(duì)照下面兩幅圖片,安裝時(shí)看清認(rèn)準(zhǔn)。







        這里就不給出電原理圖,而直接給出實(shí)物連接圖,下面給出的圖,布的是雙層板,新手們先從單層的練起,然后再縮小布局,采用雙層板。圖中藍(lán)色線表示洞洞板的布線,紅色線表示頂層線。安裝時(shí)整板是根據(jù)洞洞板來(lái)布局的,焊接時(shí),紅線作為飛線來(lái)布,圖中的Z1表示接線端子,H1是一體化紅外接受頭,數(shù)碼管一定是共陽(yáng)極數(shù)碼管,焊接時(shí)先焊飛線,再焊元件。數(shù)碼管的四角都有突起,所以放在洞洞板上與板面之間會(huì)有縫隙,可以將飛線隱藏在數(shù)碼管的下面。本作品中的DS1302沒有裝備用電池。本程序加入了自動(dòng)軟件校時(shí),但由于硬件本身,每個(gè)人做出來(lái)的時(shí)間誤差都不一樣,只要修改校時(shí)數(shù)據(jù)就可以了,只要對(duì)時(shí)準(zhǔn)確,天誤差一般都可調(diào)整到小于一秒。





        下面說(shuō)一下遙控器的用法,是不是很熟悉啊,電視機(jī)頂盒的遙控器......
        電源鍵:進(jìn)入/退出待機(jī)狀態(tài),待機(jī)時(shí)第一個(gè)小數(shù)點(diǎn)閃爍
        待機(jī)鍵:開啟/關(guān)閉掉電模式
        聲道鍵:切換自動(dòng)/手動(dòng)顯示
        確認(rèn)鍵:手動(dòng)切換顯示界面
        電視鍵:時(shí)間小時(shí)/月加一
        點(diǎn)播鍵:時(shí)間小時(shí)/月減一
        廣播鍵:時(shí)間分鐘/年/日加一
        資訊鍵:時(shí)間分鐘/年/日減一
        調(diào)整方法:在各自的顯示界面,按加一或減一鍵即可調(diào)整時(shí)間/年份/日月



        制作遙控單片機(jī)數(shù)碼管時(shí)鐘的注意事項(xiàng):
        1、先說(shuō)一下數(shù)碼管斷碼的問(wèn)題,大家可以看到,一共用了兩個(gè)二位一體的數(shù)碼管,第一個(gè)是正放的,第二個(gè)是反放的,所以兩個(gè)數(shù)碼管的引腳順序是不一樣的,再有就是根據(jù)硬件來(lái)接線的,為了方便走線,所以數(shù)碼管的段碼引腳和P0口的連接不是按照a,b,c,d,e,f,g,dp的順序來(lái)的,所以大家可能會(huì)覺得程序里的數(shù)碼管段碼數(shù)組會(huì)很奇怪,只要大家自己根據(jù)自己的接法改一下就好了。
        2、硬件布局方面,由于都是沒有錢的學(xué)生,那種專門的印制的電路板我們是做不起的,但是大家都應(yīng)該有洞洞板(萬(wàn)用板)。洞洞板是個(gè)好東西,在洞洞板上做東西能極大的提高我們硬件布局和接線的能力,要盡量少使用飛線,元器件的擺放要合理,比如說(shuō)晶振與芯片的連接不能太遠(yuǎn),18B20溫度傳感器要遠(yuǎn)離單片機(jī),數(shù)碼管等會(huì)發(fā)熱的元器件,不然就不準(zhǔn)了......
        3、軟件方面,理論上說(shuō),軟件是萬(wàn)能的,但有時(shí)候一個(gè)復(fù)雜的軟件所完成的工作只需幾個(gè)簡(jiǎn)單的硬件就能完成,我們?cè)诳紤]成本的基礎(chǔ)上最好還是選擇硬件,畢竟現(xiàn)在很多的電子元件都很便宜,因?yàn)閺?fù)雜的軟件會(huì)增加CPU的負(fù)擔(dān)且降低系統(tǒng)工作的穩(wěn)定性。當(dāng)然,反之亦然......
        4、關(guān)于DS1302發(fā)熱的問(wèn)題,可能很多朋友都遇到過(guò)DS1302發(fā)熱的問(wèn)題,首先請(qǐng)查看你的DS1302是不是1108批次的貨(芯片上面有),這個(gè)批次的貨有缺陷,一般情況下?lián)Q幾個(gè)1302會(huì)好的。再有試著將VCC1和VCC2調(diào)換這接一下試試。如果再不行,請(qǐng)檢查程序。
        5、由于程序及電路圖這里不好貼出來(lái),需要的愛好者可以自己下載
        遙控單片機(jī)數(shù)碼管時(shí)鐘資料來(lái)源于網(wǎng)絡(luò),這里得感謝一葉知秋無(wú)私提供

源程序:1.頭文件DS18B20_3.H:

  1. sbit DQ = P1^0;                // 定義DQ引腳為P2.3

  2. /*******************************  延時(shí)函數(shù) ********************************
  3. *  功能:在11.059MHz的晶振條件下調(diào)用本函數(shù)需要24μs ,然后每次計(jì)數(shù)需16μ
  4. **************************************************************************/
  5. void DS18_delay(int useconds) {
  6. int s;
  7. for (s=0; s<useconds;s++);
  8. }


  9. /*******************************  復(fù)位函數(shù) *******************************
  10. * 功能:完成單總線的復(fù)位操作。
  11. * 復(fù)位時(shí)間為480μs,因此延時(shí)時(shí)間為(480-24)/16 = 28.5,取29μs
  12. * 經(jīng)過(guò)70μs之后檢測(cè)存在脈沖,因此延時(shí)時(shí)間為(70-24)/16 = 2.875,取3μs
  13. **************************************************************************/
  14. unsigned char ow_reset(void) {
  15. unsigned char presence;
  16. DQ = 0;                          // 將 DQ 線拉低
  17. DS18_delay(29);                         // 保持 480μs
  18. DQ = 1;                         // DQ返回高電平
  19. DS18_delay(3);                         // 等待存在脈沖
  20. presence = DQ;                 // 獲得存在信號(hào)
  21. DS18_delay(25);                         // 等待時(shí)間隙結(jié)束
  22. return(presence);         // 返回存在信號(hào),0 = 器件存在, 1 = 無(wú)器件
  23. }


  24. /****************************** 位寫入函數(shù) *******************************
  25. * 功能:向單總線寫入1位值:bitval
  26. *************************************************************************/
  27. void write_bit(char bitval) {
  28. DQ = 0;                                 // 將DQ 拉低開始寫時(shí)間隙
  29. if(bitval==1) DQ =1;         // 如果寫1,DQ 返回高電平
  30. DS18_delay(5);                                 // 在時(shí)間隙內(nèi)保持電平值,
  31. DQ = 1;         // DS18_delay函數(shù)每次循環(huán)延時(shí)16μs,因此DS18_delay(5) = 104μs
  32. }       


  33. /**************************** 字節(jié)寫入函數(shù) *******************************
  34. * 功能:向單總線寫入一個(gè)字節(jié)值:val
  35. *************************************************************************/
  36. void ds18write_byte(char val) {
  37. unsigned char i;
  38. unsigned char temp;
  39. for (i=0; i<8; i++) {        // 寫入字節(jié), 每次寫入一位
  40. temp = val>>i;                
  41. temp &= 0x01;                
  42. write_bit(temp);
  43. }
  44. DS18_delay(5);
  45. }

  46. /**************************** 位讀取函數(shù) ********************************
  47. * 功能:從單總線上讀取一位信號(hào),所需延時(shí)時(shí)間為15μs,因此無(wú)法調(diào)用前面定義
  48. * 的DS18_delay()函數(shù),而采用一個(gè)for()循環(huán)來(lái)實(shí)現(xiàn)延時(shí)。
  49. * ***********************************************************************/
  50. unsigned char read_bit(void) {
  51. unsigned char i;
  52. DQ = 0;                      //將DQ 拉低開始讀時(shí)間隙
  53. DQ = 1;                         // then return high
  54. for (i=0; i<3; i++);         // 延時(shí)15μs
  55. return(DQ);                         // 返回 DQ 線上的電平值
  56. }

  57. /**************************** 字節(jié)讀取函數(shù) *******************************
  58. * 功能:從單總線讀取一個(gè)字節(jié)的值
  59. *************************************************************************/
  60. unsigned char DSread_byte(void) {
  61. unsigned char i;
  62. unsigned char value = 0;
  63. for (i=0;i<8;i++) {                                  // 讀取字節(jié),每次讀取一個(gè)字節(jié)
  64. if(read_bit()) value|=0x01<<i;         // 然后將其左移
  65. DS18_delay(6);                                        
  66. }
  67. return(value);
  68. }


  69. /******************************* 讀取溫度函數(shù) *****************************
  70. * 功能:如果單總線節(jié)點(diǎn)上只有一個(gè)器件則可以直接掉用本函數(shù)。如果節(jié)點(diǎn)上有多個(gè)器
  71. *      件,為了避免數(shù)據(jù)沖突,應(yīng)使用Match ROM函數(shù)來(lái)選中特定器件。
  72. * 注: 本函數(shù)是根據(jù)DS1820的溫度數(shù)據(jù)格式編寫的,若用于DS18B20,必須根據(jù)
  73. *      DS18B20的溫度數(shù)據(jù)格式作適當(dāng)修改。
  74. **************************************************************************/unsigned
  75. int ReadTemperature(void) {
  76. unsigned char get[10];
  77. unsigned char temp_lsb,temp_msb;
  78. unsigned int t;
  79. unsigned char k;
  80. ow_reset();
  81. ds18write_byte(0xCC);                                         // 跳過(guò) ROM
  82. ds18write_byte(0x44);                                         // 啟動(dòng)溫度轉(zhuǎn)換
  83. DS18_delay(5);
  84. ow_reset();
  85. ds18write_byte(0xCC);                                         // 跳過(guò) ROM
  86. ds18write_byte(0xBE);                                         // 讀暫存器
  87. for (k=0;k<2;k++){get[k]=DSread_byte();}

  88. temp_msb = get[1]; // Sign byte + lsbit
  89. temp_lsb = get[0]; // Temp data plus lsb

  90. t=temp_msb*256+temp_lsb;
  91. t=t&0x0ff0;
  92. if(t<0xff&&t>0xf0)
  93. t=(-1)*t;
  94. return t>>4;
  95. //temp_f = (((int)temp_c)* 9)/5 + 32;
  96.                  // 輸出華氏溫度值

  97. }
復(fù)制代碼

2.主程序:
  1. /**********************************WAYNE*********************************/
  2. #include<reg52.h>
  3. #include<intrins.h>
  4. #include"DS18B20_3.H"       //18B20溫度傳感器頭文件,18B20的服務(wù)程序都在這里
  5. #define uchar unsigned char
  6. #define uint  unsigned int
  7. unsigned int distemp=8;       //紅外接收返回值
  8. unsigned char IRCOM[7];
  9. unsigned char temp;
  10. unsigned char sec, min, hour, day, month, year;
  11. unsigned char aa=0;       //遙控器中間變量
  12. unsigned char bb=1;       //顯示界面中間變量
  13. unsigned char cc=0;       //自動(dòng)切換中間變量
  14. unsigned char dd=0;       //掉電模式中間變量
  15. unsigned char ee=0;
  16. unsigned char flag;
  17. uchar code table[10] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};       //數(shù)碼管段碼
  18. sbit ACC0 = ACC^0;
  19. sbit ACC7 = ACC^7;
  20. sbit T_CLK = P3^5;       //實(shí)時(shí)時(shí)鐘時(shí)鐘線引腳
  21. sbit T_IO = P3^6;       //實(shí)時(shí)時(shí)鐘數(shù)據(jù)線引腳
  22. sbit T_RST = P3^7;       //實(shí)時(shí)時(shí)鐘復(fù)位線引腳
  23. sbit Y1=P2^6;       //第一位數(shù)碼管共陽(yáng)極引腳
  24. sbit Y2=P2^3;       //第二位數(shù)碼管共陽(yáng)極引腳
  25. sbit Y3=P2^1;       //第三位數(shù)碼管共陽(yáng)極引腳
  26. sbit Y4=P2^0;       //第四位數(shù)碼管共陽(yáng)極引腳
  27. sbit led=P0^7;       //數(shù)碼管小數(shù)點(diǎn)陰極引腳
  28. sbit IRIN = P3^2;       //紅外接收器數(shù)據(jù)線與單片機(jī)引腳之間的定義

  29. /*********************************延時(shí)函數(shù)**************************************/
  30. void Delay_1ms(uint i)       //1ms延時(shí)
  31. {
  32.         uchar x,j;
  33.         for(j=0;j<i;j++)
  34.         for(x=0;x<=148;x++);       
  35. }
  36. void delay1(unsigned char x)       //延時(shí)函數(shù)x*0.14MS
  37. {
  38. unsigned char i;
  39.   while(x--)
  40. {
  41.   for (i = 0; i<13; i++) {}
  42. }
  43. }

  44. /**********************************往DS1302寫入1Byte數(shù)據(jù)*************************************/
  45. void v_RTInputByte(uchar ucDa)
  46. {
  47.         uchar i;
  48.         ACC = ucDa;
  49.         T_RST = 1;
  50.         for(i=8; i>0; i--)
  51.         {
  52.                 T_IO = ACC0;
  53.                 T_CLK = 1;
  54.                 T_CLK = 0;
  55.                 ACC = ACC >> 1;
  56.         }
  57. }

  58. /******************************從DS1302讀取1Byte數(shù)據(jù)*****************************************/
  59. uchar uc_RTOutputByte(void)
  60. {
  61.         uchar i;
  62.         T_RST = 1;
  63.         for(i=8; i>0; i--)
  64.         {
  65.                 ACC = ACC >>1;
  66.                 T_IO=1;
  67.                 ACC7 = T_IO;
  68.                 T_CLK = 1;
  69.                 T_CLK = 0;
  70.         }
  71.         return(ACC);
  72. }

  73. /*******************************往DS1302寫入數(shù)據(jù)****************************************/
  74. void v_W1302(uchar ucAddr, uchar ucDa)
  75. {
  76.         T_RST = 0;
  77.         T_CLK = 0;
  78.         T_RST = 1;
  79.         v_RTInputByte(ucAddr);       // 寫地址
  80.         _nop_();
  81.         _nop_();
  82.         v_RTInputByte(ucDa);       // 寫1Byte數(shù)據(jù)
  83.         T_CLK = 1;
  84.         T_RST = 0;
  85. }

  86. /**********************************讀取DS1302某地址的數(shù)據(jù)*************************************/
  87. uchar uc_R1302(uchar ucAddr)
  88. {
  89.         uchar ucDa;
  90.         T_RST = 0;
  91.         T_CLK = 0;
  92.         T_RST = 1;
  93.         v_RTInputByte(ucAddr);       //寫地址,命令
  94.         _nop_();
  95.         _nop_();
  96.         ucDa = uc_RTOutputByte();       //讀1Byte數(shù)據(jù)
  97.         T_CLK = 1;
  98.         T_RST = 0;
  99.         return(ucDa);
  100. }

  101. /*********************************DEC碼轉(zhuǎn)換為BCD碼**************************************/
  102. uchar dectobcd(uchar dec)
  103. {
  104.         uchar bcd;
  105.         bcd = 0;
  106.         while(dec >= 10)
  107.         {              
  108.                 dec -= 10;                        
  109.                 bcd++;
  110.         }
  111.         bcd <<= 4;
  112.         bcd |= dec;
  113.         return bcd;
  114. }

  115. /*******************************BCD碼轉(zhuǎn)換為DEC碼****************************************/
  116. uchar bcdtodec(uchar bcd)
  117. {
  118.         uchar data1;
  119.         data1 = bcd & 0x0f;       //取BCD低4位
  120.         bcd = bcd & 0x70;       //剔除BCD的最高位和低4位。
  121.         data1 += bcd >> 1;
  122.         data1 += bcd >> 3;       //用位移代替乘法運(yùn)算
  123.         return data1;
  124. }

  125. /*********************************往DS1302中寫入數(shù)據(jù)**************************************/
  126. void Write_DS1302Init(void)
  127. {
  128.         v_W1302(0x8e,0x00);       //屏蔽一下語(yǔ)句,則掉電走時(shí)有效;屏蔽則掉電走時(shí)失效,且每次上電后顯示12:00(時(shí))/2012(年)/1(月)1(日)
  129.         v_W1302(0x80,0x00);       //寫入秒
  130.         v_W1302(0x82,0x00);       //寫入分
  131.         v_W1302(0x84,0x12);       //寫入小時(shí)
  132.         v_W1302(0x86,0x01);       //寫入日
  133.         v_W1302(0x88,0x01);       //寫入月
  134.         v_W1302(0x8a,0x00);       //寫入星期
  135.         v_W1302(0x8c,0x12);       //寫入年
  136.         v_W1302(0x8e,0x80);
  137. }

  138. /*********************************數(shù)碼管位選碼**************************************/
  139. void Y_1()       //選通第一位數(shù)碼管
  140. {
  141.   Y1=0;
  142.   Y2=1;
  143.   Y3=1;
  144.   Y4=1;
  145. }
  146. void Y_2()       //選通第二位數(shù)碼管
  147. {
  148.   Y1=1;
  149.   Y2=0;
  150.   Y3=1;
  151.   Y4=1;
  152. }
  153. void Y_3()       //選通第三位數(shù)碼管
  154. {
  155.   Y1=1;
  156.   Y2=1;
  157.   Y3=0;
  158.   Y4=1;
  159. }
  160. void Y_4()       //選通第四位數(shù)碼管
  161. {
  162.   Y1=1;
  163.   Y2=1;
  164.   Y3=1;
  165.   Y4=0;
  166. }
  167. void Y_5()       //切斷所有數(shù)碼管,用于數(shù)碼管消隱
  168. {
  169.   Y1=1;
  170.   Y2=1;
  171.   Y3=1;
  172.   Y4=1;
  173. }


  174. /*******************************顯示程序****************************************/
  175. void Run_DS1302(void)
  176. {
  177.                 v_W1302(0x8f, 0x00);
  178.                 sec = bcdtodec(uc_R1302(0x81));       //讀出DS1302中的秒
  179.                 min = bcdtodec(uc_R1302(0x83));       //讀出DS1302中的分
  180.                 hour = bcdtodec(uc_R1302(0x85));       //讀出DS1302中的小時(shí)
  181.                 day = bcdtodec(uc_R1302(0x87));       //讀出DS1302中的日
  182.                 month = bcdtodec(uc_R1302(0x89));       //讀出DS1302中的月
  183.                 year = bcdtodec(uc_R1302(0x8d));       //讀出DS1302中的年   
  184.             v_W1302(0x8f,0x80);
  185.                 if(distemp == 0)
  186.                 {   distemp = 8;
  187.                     aa++;
  188.                 }
  189.                 if(distemp ==7)
  190.                 {   distemp = 8;
  191.                     ee++;
  192.                 }
  193.                 if(ee == 2)
  194.                 ee=0;
  195.                 if(aa==4)       //判斷顯示數(shù)據(jù)
  196.                 aa=0;
  197.                 if(aa == 0)
  198.                 {
  199.                         bb = 1;       //顯示時(shí)間
  200.                 }
  201.                 if(aa == 1)
  202.                 {
  203.                         bb = 2;       //顯示溫度
  204.                 }
  205.         if(aa == 2)
  206.                 {
  207.                         bb = 3;       //顯示年份
  208.                 }
  209.                 if(aa == 3)
  210.                 {
  211.                         bb = 4;       //顯示日期
  212.                 }
  213.         if(ee == 1)
  214.                 bb = 5;
  215.                 if(bb == 1)       //時(shí)間顯示界面
  216.                 {   if(hour / 10 % 10!=0)       //十位為0則不顯示
  217.                         {P1 = ~table[hour / 10 % 10];       //顯示小時(shí)的十位數(shù)據(jù)
  218.              led=1;
  219.                          Y_1();       //選通第一位數(shù)碼管
  220.                          Delay_1ms(1);       //短暫停留
  221.                          P1 = 0xff;       //數(shù)碼管消隱
  222.                           led=1;
  223.                          Y_5();       //切斷所有數(shù)碼管
  224.                         }
  225.                         P1 = ~table[hour % 10];       //顯示小時(shí)的個(gè)位數(shù)據(jù)
  226.                         if(sec%2==0)       //判斷是否秒閃爍
  227.                         led=1;
  228.                         else led=0;
  229.                         Y_2();       //選通第二位數(shù)碼管
  230.                         Delay_1ms(1);       //短暫停留
  231.             P1 = 0xff;       //數(shù)碼管消隱
  232.                         led=1;
  233.                         Y_5();       //切斷所有數(shù)碼管
  234.                         P1 = ~table[min / 10 % 10];       //顯示分鐘的十位數(shù)據(jù)
  235.             if(sec%2==0)       //判斷是否秒閃爍
  236.                         led=1;
  237.                         else led=0;
  238.                         Y_3();       //選通第三位數(shù)碼管
  239.                         Delay_1ms(1);       //短暫停留
  240.                         P1 = 0xff;       //數(shù)碼管消隱
  241.                         led=1;
  242.                         Y_5();       //切斷所有數(shù)碼管
  243.                         P1 = ~table[min % 10];       //顯示分鐘的個(gè)位數(shù)據(jù)
  244.             led=1;
  245.                         Y_4();       //選通第四位數(shù)碼管
  246.                         Delay_1ms(1);       //短暫停留
  247.                         P1 = 0xff;       //數(shù)碼管消隱
  248.                         led=1;
  249.                         Y_5();       //切斷所有數(shù)碼管
  250.                 }
  251.                 if(bb == 2)       //溫度顯示界面
  252.                 {
  253.                         P1 = ~table[(flag-1) / 10 % 10];       //顯示溫度的十位數(shù)據(jù)
  254.             led=1;
  255.                         Y_2();       //選通第二位數(shù)碼管
  256.                         Delay_1ms(1);       //短暫停留
  257.                         P1 = 0xff;       //數(shù)碼管消隱
  258.                         led=1;
  259.                         Y_5();       //切斷所有數(shù)碼管
  260.                         P1 = ~table[(flag-1) % 10];       //顯示溫度的個(gè)位數(shù)據(jù)
  261.             led=1;
  262.                         Y_3();       //選通第三位數(shù)碼管
  263.                         Delay_1ms(1);       //短暫停留
  264.                         P1 = 0xff;       //數(shù)碼管消隱
  265.                         led=1;
  266.                         Y_5();       //切斷所有數(shù)碼管
  267.                         P1 = ~0x58;       //顯示攝氏溫度標(biāo)志
  268.                         led=0;
  269.                         Y_4();       //選通第四位數(shù)碼管
  270.                         Delay_1ms(1);       //短暫停留
  271.                         P1 = 0xff;       //數(shù)碼管消隱
  272.                         led=1;
  273.                         Y_5();       //切斷所有數(shù)碼管
  274.                 }
  275.                 if(bb == 3)       //年份顯示界面
  276.                 {
  277.                         P1 = ~0x6e;       //顯示年份千位數(shù)據(jù),默認(rèn)為2
  278.             led=1;
  279.                         Y_1();       //選通第一位數(shù)碼管
  280.                         Delay_1ms(1);       //短暫停留
  281.                         P1 = 0xff;       //數(shù)碼管消隱
  282.                         led=1;
  283.                         Y_5();       //切斷所有數(shù)碼管
  284.                         P1 = ~0x77;       //顯示年份百位數(shù)據(jù),默認(rèn)為0
  285.             led=1;
  286.                         Y_2();       //選通第二位數(shù)碼管
  287.                         Delay_1ms(1);       //短暫停留
  288.                         P1 = 0xff;       //數(shù)碼管消隱
  289.                         led=1;
  290.                         Y_5();       //切斷所有數(shù)碼管
  291.                     P1 = ~table[year / 10 % 10];       //顯示年份十位數(shù)據(jù)
  292.             led=1;
  293.                         Y_3();       //選通第三位數(shù)碼管
  294.                         Delay_1ms(1);       //短暫停留
  295.                         P1 = 0xff;       //數(shù)碼管消隱
  296.                         led=1;
  297.                         Y_5();       //切斷所有數(shù)碼管
  298.                         P1 = ~table[year % 10];       //顯示年份個(gè)位數(shù)據(jù)
  299.             led=1;
  300.                         Y_4();       //選通第四位數(shù)碼管
  301.                         Delay_1ms(1);       //短暫停留
  302.                         P1 = 0xff;       //數(shù)碼管消隱
  303.                         led=1;
  304.                         Y_5();       //切斷所有數(shù)碼管
  305.                 }
  306.                 if(bb == 4)       //月日顯示界面
  307.                 {   if(month / 10 % 10!=0)       //十位為0則不顯示
  308.                         {P1 = ~table[month / 10 % 10];       //顯示月十位數(shù)據(jù)
  309.              led=1;
  310.                          Y_1();       //選通第一位數(shù)碼管
  311.                          Delay_1ms(1);       //短暫停留
  312.              P1 = 0xff;       //數(shù)碼管消隱
  313.                            led=1;
  314.                          Y_5();       //切斷所有數(shù)碼管
  315.                          }
  316.                         P1 = ~table[month % 10];       //顯示月個(gè)位數(shù)據(jù)
  317.             led=0;
  318.                         Y_2();       //選通第二位數(shù)碼管
  319.                         Delay_1ms(1);       //短暫停留
  320.                         P1 = 0xff;       //數(shù)碼管消隱
  321.                         led=1;
  322.                         Y_5();       //切斷所有數(shù)碼管                       
  323.                         if(day / 10 % 10!=0)       //十位為0則不顯示
  324.                         {P1 = ~table[day / 10 % 10];       //顯示日十位數(shù)據(jù)
  325.              led=1;
  326.                          Y_3();       //選通第三位數(shù)碼管
  327.                          Delay_1ms(1);       //短暫停留
  328.                          P1 = 0xff;       //數(shù)碼管消隱
  329.                          led=1;
  330.                          Y_5();       //切斷所有數(shù)碼管
  331.                          }
  332.                         P1 = ~table[day % 10];       //顯示日個(gè)位數(shù)據(jù)
  333.             led=1;
  334.                         Y_4();       //選通第四位數(shù)碼管
  335.                         Delay_1ms(1);       //短暫停留
  336.                         P1 = 0xff;       //數(shù)碼管消隱
  337.                         led=1;
  338.                         Y_5();       //切斷所有數(shù)碼管                       
  339.                 }
  340.                 if(bb == 5)
  341.                 {  
  342.                  P1=0xff;
  343.                  if(sec%2==0)       //判斷是否秒閃爍
  344.                         led=1;
  345.                         else led=0;
  346.          Y_1();       //選通第四位數(shù)碼管
  347.                  Delay_1ms(1);       //短暫停留
  348.                  }
  349. }

  350. /**********************************自動(dòng)切換程序*************************************/
  351. void zdqh()
  352. {
  353. if(distemp==6)
  354. {distemp=8;
  355.   cc++;
  356. }
  357. if(cc==2)       //切換為手動(dòng)顯示
  358. cc=0;
  359. if(cc==1)       //切換為自動(dòng)循環(huán)顯示
  360. {
  361.   if(sec%10==0)       //每10秒內(nèi),前7秒顯示時(shí)間界面
  362.   aa = 0;
  363.   if(sec==7||sec==37)       //7秒和37秒切換為溫度顯示
  364.   aa = 1;
  365.   if(sec==17||sec==47)       //17秒和47秒切換為年份顯示
  366.   aa = 2;
  367.   if(sec==27||sec==57)       //27秒和57秒切換為月日顯示
  368.   aa = 3;
  369. }
  370. }

  371. /*********************************調(diào)節(jié)程序**************************************/
  372. void tj()
  373. {
  374. if(distemp == 1)       //判斷按下的鍵值
  375. {distemp=8;       //返回值回位
  376.   if(bb==1)       //判斷當(dāng)前顯示界面
  377.   {
  378.    hour++;       //小時(shí)加一調(diào)節(jié)
  379.    if(hour==24)       //限制小時(shí)數(shù)據(jù)在0~23之間
  380.    hour=0;
  381.    temp=dectobcd(hour);       //將十進(jìn)制數(shù)轉(zhuǎn)換成十六禁止數(shù)
  382.    v_W1302(0x8e,0x00);       //禁止寫保護(hù)
  383.    v_W1302(0x84,temp);       //寫入小時(shí)數(shù)據(jù)
  384.    v_W1302(0x80,0x00);
  385.    v_W1302(0x8e,0x80);       //打開寫保護(hù)
  386.   }
  387.   if(bb==4)       //判斷當(dāng)前顯示界面
  388.   {
  389.    month++;       //月加一調(diào)節(jié)
  390.    if(month==13)       //限制月數(shù)據(jù)在1~12之間
  391.    month=1;
  392.    temp=dectobcd(month);       //將十進(jìn)制數(shù)轉(zhuǎn)換成十六禁止數(shù)
  393.    v_W1302(0x8e,0x00);       //禁止寫保護(hù)
  394.    v_W1302(0x88,temp);       //寫入月數(shù)據(jù)
  395.    v_W1302(0x8e,0x80);       //打開寫保護(hù)
  396.   }
  397. }
  398. if(distemp == 2)       //判斷按下的鍵值
  399. {distemp=8;       //返回值回位
  400.   if(bb==1)       //判斷當(dāng)前顯示界面
  401.   {
  402.    min++;//分鐘加一調(diào)節(jié)
  403.    if(min==60)//限制分鐘數(shù)據(jù)在0~59之間
  404.    min=0;
  405.    temp=dectobcd(min);//將十進(jìn)制數(shù)轉(zhuǎn)換成十六禁止數(shù)
  406.    v_W1302(0x8e,0x00);//禁止寫保護(hù)
  407.    v_W1302(0x82,temp);//寫入分鐘數(shù)據(jù)
  408.    v_W1302(0x80,0x00);
  409.    v_W1302(0x8e,0x80);//打開寫保護(hù)
  410.   }
  411.   if(bb==3)//判斷當(dāng)前顯示界面
  412.   {
  413.    year++;//年份加一調(diào)節(jié)
  414.    if(year==100)//限制年份數(shù)據(jù)在0~99之間
  415.    year=0;
  416.    temp=dectobcd(year);//將十進(jìn)制數(shù)轉(zhuǎn)換成十六禁止數(shù)
  417.    v_W1302(0x8e,0x00);//禁止寫保護(hù)
  418.    v_W1302(0x8c,temp);//寫入年數(shù)據(jù)
  419.    v_W1302(0x8e,0x80);//打開寫保護(hù)
  420.   }
  421.   if(bb==4)//判斷當(dāng)前顯示界面
  422.   {
  423.    day++;       //日加一調(diào)節(jié)
  424.    if(day==32)       //限制日數(shù)據(jù)在1~31之間
  425.    day=1;
  426.    temp=dectobcd(day);       //將十進(jìn)制數(shù)轉(zhuǎn)換成十六禁止數(shù)
  427.    v_W1302(0x8e,0x00);       //禁止寫保護(hù)
  428.    v_W1302(0x86,temp);       //寫入日數(shù)據(jù)
  429.    v_W1302(0x8e,0x80);       //打開寫保護(hù)
  430.   }
  431. }
  432. if(distemp == 3)       //判斷按下的鍵值
  433. {distemp=8;       //返回值回位
  434.   if(bb==1)       //判斷當(dāng)前顯示界面
  435.   {
  436.    hour--;       //小時(shí)減一調(diào)節(jié)
  437.    if(hour==-1)       //限制小時(shí)數(shù)據(jù)在0~23之間
  438.    hour=23;
  439.    temp=dectobcd(hour);       //將十進(jìn)制數(shù)轉(zhuǎn)換成十六禁止數(shù)
  440.    v_W1302(0x8e,0x00);       //禁止寫保護(hù)
  441.    v_W1302(0x84,temp);       //寫入小時(shí)數(shù)據(jù)
  442.    v_W1302(0x80,0x00);
  443.    v_W1302(0x8e,0x80);       //打開寫保護(hù)
  444.   }
  445.   if(bb==4)       //判斷當(dāng)前顯示界面
  446.   {
  447.    month--;       //月減一調(diào)節(jié)
  448.    if(month==0)       //限制月數(shù)據(jù)在1~12之間
  449.    month=12;
  450.    temp=dectobcd(month);       //將十進(jìn)制數(shù)轉(zhuǎn)換成十六禁止數(shù)
  451.    v_W1302(0x8e,0x00);       //禁止寫保護(hù)
  452.    v_W1302(0x88,temp);       //寫入月數(shù)據(jù)
  453.    v_W1302(0x8e,0x80);       //打開寫保護(hù)
  454.   }
  455. }
  456. if(distemp == 4)       //判斷按下的鍵值
  457. {distemp=8;       //返回值回位
  458.   if(bb==1)       //判斷當(dāng)前顯示界面
  459.   {
  460.    min--;       //分鐘減一調(diào)節(jié)
  461.    if(min==-1)       //限制分鐘數(shù)據(jù)在0~59之間
  462.    min=59;
  463.    temp=dectobcd(min);       //將十進(jìn)制數(shù)轉(zhuǎn)換成十六禁止數(shù)
  464.    v_W1302(0x8e,0x00);       //禁止寫保護(hù)
  465.    v_W1302(0x82,temp);       //寫入分鐘數(shù)據(jù)
  466.    v_W1302(0x80,0x00);
  467.    v_W1302(0x8e,0x80);       //打開寫保護(hù)
  468.   }
  469.   if(bb==3)       //判斷當(dāng)前顯示界面
  470.   {
  471.    year--;       //年份減一調(diào)節(jié)
  472.    if(year==-1)       //限制年份數(shù)據(jù)在0~99之間
  473.    year=99;
  474.    temp=dectobcd(year);       //將十進(jìn)制數(shù)轉(zhuǎn)換成十六禁止數(shù)
  475.    v_W1302(0x8e,0x00);       //禁止寫保護(hù)
  476.    v_W1302(0x8c,temp);       //寫入年數(shù)據(jù)
  477.    v_W1302(0x8e,0x80);       //打開寫保護(hù)
  478.   }
  479.   if(bb==4)       //判斷當(dāng)前顯示界面
  480.   {
  481.    day--;       //日減一調(diào)節(jié)
  482.    if(day==0)       //限制日數(shù)據(jù)在1~31之間
  483.    day=31;
  484.    temp=dectobcd(day);       //將十進(jìn)制數(shù)轉(zhuǎn)換成十六禁止數(shù)
  485.    v_W1302(0x8e,0x00);       //禁止寫保護(hù)
  486.    v_W1302(0x86,temp);       //寫入日數(shù)據(jù)
  487.    v_W1302(0x8e,0x80);       //打開寫保護(hù)
  488.   }
  489. }
  490. }

  491. /*******************************掉電模式程序****************************************/
  492. void xmms()
  493. {
  494. if(dd == 1)       //單片機(jī)進(jìn)入掉電工作模式,該模式下只有首位數(shù)碼管的小數(shù)點(diǎn)常亮
  495. {
  496.   P0=~0xff;       //在掉電模式下,只有第一位數(shù)碼管的小數(shù)點(diǎn)亮
  497.   led=1;
  498.   Y_5();
  499.   aa=0;
  500.   ee=0;
  501.   PCON=0x02;       //設(shè)置掉電模式寄存器,這句一定要放在該子程序的最后
  502. }
  503. }

  504. /********************************自動(dòng)校時(shí)***************************************/
  505. void zdjs()
  506. {
  507. if(hour==3&&min==0&&sec==30)
  508.    {
  509.         v_W1302(0x8e,0x00);      
  510.         v_W1302(0x80,0x00);
  511.     v_W1302(0x8e,0x80);
  512.     }
  513. }

  514. /********************************主函數(shù)***************************************/
  515. void Main(void)
  516. {   
  517.     EA=1;       //打開總中斷
  518.         EX0=1;       //允許外部0中斷
  519.     IT0=1;       //設(shè)置外部中斷0為邊沿方式觸發(fā)
  520.     IRIN=1;
  521.         Write_DS1302Init();
  522.         while(1)       //無(wú)限循環(huán)以下子程序
  523.         {
  524.          Run_DS1302();       //顯示程序
  525.          flag=ReadTemperature();       //將18b2頭文件運(yùn)行返回的函數(shù)結(jié)果送到變量flag中,用于顯示
  526.          tj();       //調(diào)節(jié)程序
  527.          xmms();       //休眠模式
  528.          zdqh();       //自動(dòng)切換
  529.          zdjs();       //自動(dòng)校時(shí)
  530.          }
  531. }

  532. /*********************紅外接收程序**********************/
  533. void IR_IN() interrupt 0       //外部中斷0
  534. {
  535.   unsigned char p,q,R=0;
  536.   EA = 0;
  537.   delay1(15);
  538.   if (IRIN==1)
  539.    { EA =1;
  540.          return;
  541.         }                  
  542.   while (!IRIN)            
  543.     {delay1(1);}
  544.   for (p=0;p<4;p++)         
  545.   {
  546.    for (q=0;q<8;q++)      
  547.    {
  548.     while (IRIN)            
  549.      {delay1(1);}
  550.     while (!IRIN)        
  551.      {delay1(1);}
  552.     while (IRIN)         
  553.      {
  554.       delay1(1);
  555.       R++;           
  556.       if (R>=30)
  557.            { EA=1;
  558.              return;}               
  559.       }                                 
  560.      IRCOM[p]=IRCOM[p] >> 1;                 
  561.      if (R>=8) {IRCOM[p] = IRCOM[p] | 0x80;}
  562.      R=0;
  563.   }                        
  564. }                          
  565.    if (IRCOM[2]!=~IRCOM[3])
  566.    { EA=1;
  567.      return; }
  568.    switch(IRCOM[2])
  569.    {
  570.                    case 0x07:       //顯示切換鍵
  571.                         distemp = 0;
  572.                         break;
  573.                 case 0x44:       //左加一鍵
  574.                         distemp = 1;
  575.                         break;
  576.                 case 0x45:       //右加一鍵
  577.                         distemp = 2;
  578.                         break;
  579.                 case 0x46:       //左減一鍵
  580.                         distemp = 3;
  581.                         break;
  582.                 case 0x47:       //右減一鍵
  583.                         distemp = 4;
  584.                         break;
  585.         case 0x16:       //掉電模式開關(guān)鍵
  586.                         distemp = 5;
  587.                         break;
  588.                 case 0x10:       //自動(dòng)切換開關(guān)鍵
  589.                         distemp = 6;
  590.                         break;
  591.                 case 0x1c:       //待機(jī)模式開關(guān)鍵
  592.                         distemp = 7;
  593.                         break;
  594.    }
  595.     if(distemp == 5)       //開啟、關(guān)閉掉電模式,因掉電模式只能由外部中斷喚醒,所以下面的程序必須放在中斷函數(shù)中
  596.     {distemp = 8;       //返回值回位
  597.      dd++;
  598.     }
  599.     if(dd == 2)
  600.     dd = 0;
  601.         if(dd == 0)       //退出掉電模式
  602.         {PCON=0x00;       //設(shè)置掉電模式工作寄存器
  603.          }
  604.         if(dd == 1)       //掉電模式下,其他按鍵無(wú)效
  605.         distemp = 8;       //不返回任何鍵值
  606.         if(ee==1)
  607.          {if(distemp==0||distemp==1||distemp==2||distemp==3||distemp==4||distemp==6)
  608.           distemp = 8;
  609.           }
  610.         EA = 1;       //打開總中斷
  611. }
復(fù)制代碼




分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏14 分享淘帖 頂 踩1
回復(fù)

使用道具 舉報(bào)

30#
ID:517951 發(fā)表于 2020-11-15 17:31 | 只看該作者
很詳細(xì)不錯(cuò),值得學(xué)習(xí)。51hei有你更精彩!
回復(fù)

使用道具 舉報(bào)

29#
ID:759683 發(fā)表于 2020-7-5 19:14 | 只看該作者
沒有原理圖,經(jīng)試驗(yàn)程序和電路不符
回復(fù)

使用道具 舉報(bào)

28#
ID:21568 發(fā)表于 2019-6-12 14:58 | 只看該作者
程序跟電路板的圖對(duì)不上啊,是P1口還是P0口?
回復(fù)

使用道具 舉報(bào)

27#
ID:168038 發(fā)表于 2019-4-8 17:47 | 只看該作者
資料不錯(cuò),做一回伸手黨了,拿來(lái)就用
回復(fù)

使用道具 舉報(bào)

26#
ID:492822 發(fā)表于 2019-4-7 18:52 | 只看該作者
nsj21n 發(fā)表于 2016-2-17 13:52
不錯(cuò)哦,我始終沒有搞懂紅外遙控后如何退出

求原理圖怎么畫
回復(fù)

使用道具 舉報(bào)

25#
ID:492822 發(fā)表于 2019-4-6 14:17 | 只看該作者
樓主能不能發(fā)一下原理圖!急用啊
回復(fù)

使用道具 舉報(bào)

24#
ID:492589 發(fā)表于 2019-3-17 21:58 | 只看該作者
有沒有圖
回復(fù)

使用道具 舉報(bào)

23#
ID:315554 發(fā)表于 2018-5-3 17:32 | 只看該作者
樓主好,很喜歡這個(gè)程序,選了同樣的MCU晶振等配件,搭起硬件,寫入程序,只顯示兩個(gè)秒點(diǎn)(正常秒閃),數(shù)字不顯示,請(qǐng)教什么原因?
回復(fù)

使用道具 舉報(bào)

22#
ID:314979 發(fā)表于 2018-4-24 14:49 | 只看該作者
我下了一個(gè),學(xué)學(xué)
回復(fù)

使用道具 舉報(bào)

21#
ID:270854 發(fā)表于 2018-1-21 10:58 | 只看該作者
不顯示
回復(fù)

使用道具 舉報(bào)

20#
ID:159139 發(fā)表于 2017-6-20 23:50 | 只看該作者
謝謝分享,我下了一個(gè),學(xué)學(xué)分時(shí)顯示。
回復(fù)

使用道具 舉報(bào)

19#
ID:35873 發(fā)表于 2017-6-19 01:55 | 只看該作者
這個(gè)詳細(xì)  簡(jiǎn)直就是一教程 支持下
回復(fù)

使用道具 舉報(bào)

18#
ID:136460 發(fā)表于 2016-12-31 10:47 | 只看該作者
很好的資料要看看
回復(fù)

使用道具 舉報(bào)

17#
ID:157847 發(fā)表于 2016-12-29 18:37 | 只看該作者
挺好的
回復(fù)

使用道具 舉報(bào)

16#
ID:146910 發(fā)表于 2016-11-27 19:28 | 只看該作者
        v_W1302(0x8e,0x00);       //屏蔽一下語(yǔ)句,則掉電走時(shí)有效;屏蔽則掉電走時(shí)失效,且每次上電后顯示12:00(時(shí))/2012(年)/1(月)1(日)
        v_W1302(0x80,0x00);       //寫入秒
        v_W1302(0x82,0x00);       //寫入分
        v_W1302(0x84,0x12);       //寫入小時(shí)
        v_W1302(0x86,0x01);       //寫入日
        v_W1302(0x88,0x01);       //寫入月
        v_W1302(0x8a,0x00);       //寫入星期
        v_W1302(0x8c,0x12);       //寫入年
        v_W1302(0x8e,0x80);
要怎么修改下電后不初使化(每次上電后顯示12:00(時(shí))/2012(年)/1(月)1(日)
回復(fù)

使用道具 舉報(bào)

15#
ID:146910 發(fā)表于 2016-11-26 19:57 | 只看該作者
很好的資料要看看
回復(fù)

使用道具 舉報(bào)

14#
ID:93911 發(fā)表于 2016-11-15 21:40 | 只看該作者
值得學(xué)習(xí)。謝謝分享
回復(fù)

使用道具 舉報(bào)

13#
ID:145554 發(fā)表于 2016-11-1 21:07 | 只看該作者
很好的資料要看看
回復(fù)

使用道具 舉報(bào)

12#
ID:126935 發(fā)表于 2016-6-16 09:11 | 只看該作者
謝謝樓主
回復(fù)

使用道具 舉報(bào)

11#
ID:126485 發(fā)表于 2016-6-15 23:24 | 只看該作者
謝謝樓主學(xué)習(xí)了
回復(fù)

使用道具 舉報(bào)

10#
ID:126447 發(fā)表于 2016-6-15 21:34 | 只看該作者
資料不錯(cuò)值得一看
回復(fù)

使用道具 舉報(bào)

9#
ID:120731 發(fā)表于 2016-5-17 17:59 | 只看該作者
看一下,向大神學(xué)習(xí)
回復(fù)

使用道具 舉報(bào)

8#
ID:105697 發(fā)表于 2016-2-17 22:09 來(lái)自手機(jī) | 只看該作者
酷。!謝謝樓主
回復(fù)

使用道具 舉報(bào)

7#
ID:64089 發(fā)表于 2016-2-17 13:52 | 只看該作者
不錯(cuò)哦,我始終沒有搞懂紅外遙控后如何退出
回復(fù)

使用道具 舉報(bào)

6#
ID:41337 發(fā)表于 2015-12-23 23:09 | 只看該作者
感謝樓主分享
回復(fù)

使用道具 舉報(bào)

5#
ID:92539 發(fā)表于 2015-12-21 08:24 | 只看該作者
很好,正有急用
回復(fù)

使用道具 舉報(bào)

地板
ID:33101 發(fā)表于 2015-12-10 10:40 | 只看該作者
感謝樓主分享
回復(fù)

使用道具 舉報(bào)

板凳
ID:95976 發(fā)表于 2015-11-16 14:21 | 只看該作者
感謝樓主分享
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:95498 發(fā)表于 2015-11-12 11:54 | 只看該作者
感謝樓主。。!很有用
回復(fù)

使用道具 舉報(bào)

樓主
ID:89183 發(fā)表于 2015-9-25 22:53 | 只看該作者
很好謝謝樓主分享,有沒有帶鬧鐘版的啊,有的話給我一份吧謝謝了 xstao@qq.com
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

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

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表