標(biāo)題: 基于單片機(jī)多位LED數(shù)碼管的數(shù)字鐘設(shè)計報告 [打印本頁]

作者: 可樂333    時間: 2018-5-19 12:52
標(biāo)題: 基于單片機(jī)多位LED數(shù)碼管的數(shù)字鐘設(shè)計報告
基于多位LED數(shù)碼管的數(shù)字鐘設(shè)計
【中文摘要】設(shè)計的主要內(nèi)容就是結(jié)合軟件Keil和Proteus來仿真一個由單片機(jī)AT89C51芯片和多位LED數(shù)碼管為核心的單片機(jī)數(shù)字時鐘,從而鍛煉出學(xué)習(xí)、設(shè)計、開發(fā)軟、硬件的能力。設(shè)計已完成的數(shù)宇鐘的基本功能:正常走時(年、月、日、時、分、秒)、校正時間和秒表功能。且操作簡單、運(yùn)行穩(wěn)定。


1前言
     數(shù)字鐘具有走時準(zhǔn)確,一鐘多用等特點(diǎn),在生活中已經(jīng)得到廣泛的應(yīng)用。雖然現(xiàn)在市場上已有現(xiàn)成的電子鐘集成電路芯片,價格便宜、使用也方便。但是,人們對電子產(chǎn)品的應(yīng)用要求越來越高,數(shù)字鐘不但可以顯示當(dāng)前的時問,而且可以顯示期、農(nóng)歷、以及星期等,給人們的生活帶來了方便。
    時鐘電路在計算機(jī)系統(tǒng)中起著非常重要的作用,是保證系統(tǒng)正常工作的基礎(chǔ)。在一個單片機(jī)應(yīng)用系統(tǒng)中,時鐘有兩方面的含義:一是指為保障系統(tǒng)正常工作的基準(zhǔn)振蕩定時信號,主要由晶振和外圍電路組成,晶振頻率的大小決定了單片機(jī)系統(tǒng)工作的快慢。二是指系統(tǒng)的標(biāo)準(zhǔn)定時時鐘,即定時時間,它通常有兩種實(shí)現(xiàn)方法:一是用軟件實(shí)現(xiàn),即用單片機(jī)內(nèi)部的可編程定時/計數(shù)器來實(shí)現(xiàn),但誤差很大;二是用專門的時鐘芯片實(shí)現(xiàn),在對時間精度要求很高的情況下,通常采用這種方法。
本文主要介紹用單片機(jī)內(nèi)部的定時/計數(shù)器來實(shí)現(xiàn)多功能時鐘的方法,設(shè)計由單片機(jī)AT89C51芯片和和多位LED數(shù)碼管為核心,輔以必要的電路等,構(gòu)成的一個單片機(jī)數(shù)字時鐘。
2設(shè)計方案
2.1設(shè)計思路
    數(shù)字鐘的功能就是顯示秒、分和小時,其算法是60秒為1分鐘,60分鐘為1小時,一天為24小時。因此需要秒計數(shù)器到59秒的時候,再加1秒時,秒計數(shù)器清0,分鐘計數(shù)器加1;秒計數(shù)器加到59秒,分鐘計數(shù)器到59分時,再加1秒時,秒計數(shù)器和分計數(shù)器同時清0,小時計數(shù)器加1;當(dāng)小時計數(shù)器為23小時,分計數(shù)器為59分,秒為59秒的時候,再加1秒時,秒計數(shù)器、分計數(shù)器和小時計數(shù)器同時清零。數(shù)字鐘的核心就是要產(chǎn)生秒信號,這里利用單片機(jī)的定時器TO產(chǎn)生。定時器TO有4種工作方式,可以采用中斷方式和查詢方式編程。
此數(shù)字時鐘由主模塊(AT89C51)、顯示模塊(多位LED數(shù)碼管)、控制模塊和計時運(yùn)算模塊四大部分組成。其中控制模塊和計時運(yùn)算模塊主要對年月日、時分秒的數(shù)值顯示和調(diào)整進(jìn)行操作,并且秒計算到60時,自動清零并向分進(jìn)1;分計算到60時,自動清零并向時進(jìn)1;時計算到24時,自動清零。這樣,就形成了循環(huán)計時,顯示模塊主要用來顯示當(dāng)前計數(shù)值。AT89C51是整個設(shè)計的核心,主要用來產(chǎn)生定時中斷,傳輸數(shù)據(jù)和控制各個部件工作。   
數(shù)字鐘格式:XX.XX.XX ,從左向右分別為時/年、分/月、秒/日。時分秒完成由秒01一直加1至59,再恢復(fù)00;分加1,由00至01,一直加1至59,再恢復(fù)00;時加1,時由00加至23后秒分時全部清零;該鐘使用TO做定時中斷。
時鐘校正:走時過程中直接調(diào)整且不影響走時準(zhǔn)確性。按下相應(yīng)次數(shù)功能鍵S1進(jìn)入相應(yīng)數(shù)位的調(diào)整;按下S2按鍵加,相應(yīng)數(shù)位加1;按下S3按鍵減,相應(yīng)數(shù)位減1。
秒表功能:按下功能鍵S1對應(yīng)次數(shù),進(jìn)入秒表計時功能;按下S2按鍵加,開始計時;按下S3按鍵減,暫停計時;暫停計時時,按下S2按鍵加,繼續(xù)計時;按下S4按鍵,退出。
年月顯示:按住S4按鍵不放,顯示年月日。
2.2模塊功能說明
(1)單片機(jī)AT89C51簡介,如下圖1
圖1  AT89C51引腳圖
VCC:供電電壓。
    GND:接地。
    P0口:P0口為一個8位漏級開路雙向I/O口,每腳可吸收8TTL門電流。當(dāng)P1口的管腳第一次寫1時,被定義為高阻輸入。P0能夠用于外部程序數(shù)據(jù)存儲器,它可以被定義為數(shù)據(jù)/地址的第八位。在FIASH編程時,P0 口作為原碼輸入口,當(dāng)FIASH進(jìn)行校驗(yàn)時,P0輸出原碼,此時P0外部必須被拉高。P1口:P1口是一個內(nèi)部提供上拉電阻的8位雙向I/O口,P1口緩沖器能接收輸出4TTL門電流。P1口管腳寫入1后,被內(nèi)部上拉為高,可用作輸入,P1口被外部下拉為低電平時,將輸出電流,這是由于內(nèi)部上拉的緣故。在FLASH編程和校驗(yàn)時,P1口作為第八位地址接口。
P2口:P2口為一個內(nèi)部上拉電阻的8位雙向I/O口,P2口緩沖器可接收,輸出4個TTL門電流,當(dāng)P2口被寫“1”時,其管腳被內(nèi)部上拉電阻拉高,且作為輸入。并因此作為輸入時,P2口的管腳被外部拉低,將輸出電流。這是由于內(nèi)部上拉的緣故。P2口當(dāng)用于外部程序存儲器或16位地址外部數(shù)據(jù)存儲器進(jìn)行存取時,P2口輸出地址的高八位。在給出地址“1”時,它利用內(nèi)部上拉優(yōu)勢,當(dāng)對外部八位地址數(shù)據(jù)存儲器進(jìn)行讀寫時,P2口輸出其特殊功能寄存器的內(nèi)容。P2口在FLASH編程和校驗(yàn)時接收高八位地址信號和控制信號。
P3口:P3口管腳是8個帶內(nèi)部上拉電阻的雙向I/O口,可接收輸出4個TTL門電流。當(dāng)P3口寫入“1”后,它們被內(nèi)部上拉為高電平,并用作輸入。作為輸入,由于外部下拉為低電平,P3口將輸出電流(ILL)這是由于上拉的緣故。
RST:復(fù)位輸入。當(dāng)振蕩器復(fù)位器件時,要保持RST腳兩個機(jī)器周期的高電平時間。
    ALE/PROG:當(dāng)訪問外部存儲器時,地址鎖存允許的輸出電平用于鎖存地址的地位字節(jié)。在FLASH編程期間,此引腳用于輸入編程脈沖。在平時,ALE端以不變的頻率周期輸出正脈沖信號,此頻率為振蕩器頻率的1/6。因此它可用作對外部輸出的脈沖或用于定時目的。然而要注意的是:每當(dāng)用作外部數(shù)據(jù)存儲器時,將跳過一個ALE脈沖。如想禁止ALE的輸出可在SFR8EH地址上置0。此時, ALE只有在執(zhí)行MOVX,MOVC指令是ALE才起作用。另外,該引腳被略微拉高。如果微處理在外部執(zhí)行狀態(tài)ALE禁止,置位無效。
/PSEN:外部程序存儲器的選通信號。在由外部程序存儲器取指期間,每個機(jī)器周期兩次/PSEN有效。但在訪問外部數(shù)據(jù)存儲器時,這兩次有效的/PSEN信號將不出現(xiàn)。
  /EA/VPP:當(dāng)/EA保持低電平時,則在此期間外部程序存儲器(0000H-FFFFH),不管是否有內(nèi)部程序存儲器。注意加密方式1時,/EA將內(nèi)部鎖定為RESET;當(dāng)/EA端保持高電平時,此間內(nèi)部程序存儲器。在FLASH編程期間,此引腳也用于施加12V編程電源(VPP)。
XTAL1:反向振蕩放大器的輸入及內(nèi)部時鐘工作電路的輸入。
XTAL2:來自反向振蕩器的輸出。
    ①TMOD定時器/計數(shù)器方式寄存器
定時器方式控制寄存器TMOD在特殊功能寄存器中,字節(jié)地址為89H,無位地址。
  ②TCON定時器/計數(shù)器控制寄存器
TCON在特殊功能寄存器中,字節(jié)地址為88H,位地址(由低位到高位)為88H--8FH,由于有位地址,十分便于進(jìn)行位操作。
③定時器/計數(shù)器的初始化
由于定時器/計數(shù)器的功能是由軟件編程確定的,所以一般在使用定時/計數(shù)器前都要對其進(jìn)行初始化,使其按設(shè)定的功能工作.初始貨的步驟一般如下:
2、根據(jù)需要開放定時器/計數(shù)器的中斷(直接對IE位賦值)。
3、啟動定時器/計數(shù)器。
(2)多位LED數(shù)碼管7SEG-MPX6-CA簡介如下2
           圖2  7SEG-MPX6-CA數(shù)碼管模型圖
    7SEG-MPX6-CA是7段6位共陽級數(shù)碼管,DP為小數(shù)點(diǎn),位碼(1-6)應(yīng)輪流通高電位,段碼控制數(shù)碼管的顯示:0-e,1-d,2-p,3-c,4-g,5-b,6-f,7-a.共陽極LED數(shù)碼管,它是將發(fā)光二極管的陽極(正極)短接后作為公共陽極.當(dāng)驅(qū)動信號為低電平才能發(fā)光。
本實(shí)驗(yàn)采用動態(tài)顯示,即節(jié)省了I/O口,又能降低能耗。
顯示過程注意消影。
(3)其余件如下3
    BUTTON             PNP
   POWER       GROUND          RES
             圖3  所需用到的其余元件
2.3系統(tǒng)總體原理圖如下4
                    圖4  基于多位LED數(shù)碼管的數(shù)字鐘總圖
2.4電路圖的接法設(shè)計
鑒于仿真的單片機(jī)數(shù)字時鐘的美觀性,取消各模塊間的可見連線,利用Proteus中的Edit Wire Style 按鈕來連接各個端口。
單片機(jī)P1端口接按鍵S輸入;單片機(jī)P0端口接段碼驅(qū)動到數(shù)碼管;單片機(jī)P2端口接位碼驅(qū)動到數(shù)碼管。
2.5按鍵功能說明
  1、功能鍵--根據(jù)按下的次數(shù),分別調(diào)節(jié)時間和年月,按位調(diào)節(jié),同時調(diào)整位閃爍,按下11次后進(jìn)入秒表,期間可以按退出鍵退出功能調(diào)節(jié)或秒表。
  2、數(shù)字加---進(jìn)入時間或年月調(diào)節(jié)時,按此鍵閃爍位數(shù)字加一,秒表模式下為秒表開始鍵。
  3、數(shù)字減---進(jìn)入時間或年月調(diào)節(jié)時,按此鍵閃爍位數(shù)字減一,秒表模式下為秒表暫停鍵。
  4、退出鍵---進(jìn)入時間或年月調(diào)節(jié)時,按此鍵保存調(diào)節(jié)并退出,沒進(jìn)入時間或年月調(diào)節(jié)時按此鍵顯示年月。
3 程序流程圖
3.1時鐘顯示程序流程圖如下圖5
    圖5 時鐘顯示程序流程圖
3.2外部中斷處理流程圖如下圖6
     圖6  外部中斷處理流程圖



3.3函數(shù)模塊及功能
(1)Void Time0() interrupt 1
     定時器0中斷服務(wù)程序,供時鐘主程序使用
(2)Void Time1() interrupt 3
     定時器1中斷服務(wù)程序,供秒表使用
(3)Void yanshi(uint z)
     延時程序,供動態(tài)掃描與按鍵去抖
(4)Void xianshi()
     動態(tài)掃描程序
(5)Void shizhong()
     時鐘主程序
(6)Void key1()
     按鍵1檢測,按的次數(shù)不同進(jìn)入不同調(diào)節(jié)功能
(7)Void key2()
     按鍵2檢測,數(shù)字加或秒表計時
(8)Void key3()
     按鍵3檢測,數(shù)字減或秒表暫停
(9)Void key4()
     按鍵4檢測,按住不放顯示年月,退出功能
(10)Void nyr()
     年月日調(diào)節(jié)
(11)Void miaobiao()
     秒表,精確到1%秒
(12)Void init()
     初始化設(shè)置中斷
4 設(shè)計總結(jié)
這次對數(shù)字鐘的設(shè)計,經(jīng)過認(rèn)真地查找資料、編寫程序以及調(diào)試程序,結(jié)果達(dá)到驗(yàn)證無誤。從開始設(shè)計到仿真實(shí)現(xiàn),再到論文文章的完成,每走一步對我來說都是新的嘗試與挑戰(zhàn)。從單片機(jī)模塊數(shù)字鐘的設(shè)計過程中我找到了一些單片機(jī)開發(fā)的規(guī)律:先了解所有元件的具體內(nèi)容,從而畫出其電路圖,使數(shù)字鐘從簡易變成多功能的方式,雖沒有做鬧鈴功能的多功能數(shù)字鐘,卻知曉了其方法。從而更好地讓自己踏入單片機(jī)應(yīng)用領(lǐng)域的第一步。
【參考文獻(xiàn)】
[1]趙文博,劉文濤.單片機(jī)語言C51程序設(shè)計[M].人民郵電出版社,2006
[2]石從剛.MCS-51單片機(jī)原理與應(yīng)用實(shí)驗(yàn)實(shí)訓(xùn)教程[M].北京航空航天大學(xué)出版社,2007
[3]張靖武.單片機(jī)系統(tǒng)的PROTEUS設(shè)計與仿真[M].電子工業(yè)出版社,2009
[4]李精華.基于數(shù)字鐘設(shè)計的單片機(jī)課程項(xiàng)目開發(fā)[J].桂林航天工業(yè)高等?茖W(xué)校學(xué)報,2010
附錄:
程序代碼及說明
  1. #include <AT89X51.H>
  2. #define uint unsigned int
  3. #define uchar unsigned char
  4. /*********************************
  5.                             定義變量和數(shù)碼表
  6. *********************************/
  7. uchar code shuma[]={
  8. 0x14,0xd7,0x4c,0x45,0x87,
  9. 0x25,0x24,0x57,0x04,0x05};//數(shù)碼表
  10. uchar code fenge[]={
  11. 0x10,0xD3,0x48,0x41,0x83,
  12. 0x21,0x20,0x53,0x00,0x01};
  13. //帶點(diǎn)的數(shù)碼表
  14. uchar code weixuan []={
  15. 0x7f,0xBf,0xDf,0xEf,0xf7,0xfb,0xff};
  16. //位選控制表
  17. uchar t,tt,a,b,c,d,e,f,x,y,id,fen
  18. ,miao,hm,mm,ff,shi,ri,yue,nian;
  19. sbit s1=P1^0;//
  20. 菜單鍵,按下的次數(shù)進(jìn)入不同的調(diào)節(jié)功能
  21. sbit s2=P1^1;//數(shù)字加鍵、秒表開始鍵
  22. sbit s3=P1^2;//數(shù)字減鍵、秒表暫停鍵
  23. sbit s4=P1^3;
  24. //顯示年月日,菜單退出鍵
  25. /**********************************
  26.                             定時器0中斷服務(wù)程序
  27.                             供時鐘主程序使用
  28. **********************************/
  29. void Time0()interrupt 1
  30. { TH0=(65536-49990)/256;
  31. //裝初值,使定時器0每50毫秒產(chǎn)生一次中斷
  32.   TL0=(65536-49990)%256;
  33. //裝初值,使定時器0每50毫秒產(chǎn)生一次中斷
  34.               t++;//中斷次數(shù)
  35.               if(t==21)
  36. //在調(diào)節(jié)時間或年月時把t控制在20以內(nèi)
  37. //避免中斷次數(shù)不受控
  38.               {  t=0; }
  39. }
  40. /************************************
  41.                             定時器1中斷服務(wù)程序
  42.                                           供秒表使用
  43. ************************************/
  44. void Time1() interrupt 3
  45. { TH1=(65536-1001)/256;
  46. //裝初值,使定時器1每1毫秒產(chǎn)生一次中斷
  47.    TL1=(65536-1001)%256;
  48. //裝初值,使定時器1每1毫秒產(chǎn)生一次中斷
  49. tt++;
  50. if(tt==11)
  51. tt=0; }
  52. /************************************
  53.                                           延時程序
  54.                             供動態(tài)掃描和按鍵去抖用
  55. 如果是實(shí)物的話,x的值設(shè)為3就可以了
  56. ************************************/
  57. void yanshi(uint z)
  58. { for (x=25;x>0;x--)
  59.   for (y=z;y>0;y--); }
  60. /************************************
  61.                                動態(tài)掃描程序
  62. ************************************/
  63. void xianshi ()
  64. { P0=0xff;//消影
  65.   P2=weixuan[0];//第一位數(shù)碼管
  66.   if(t<=10)//數(shù)碼管閃爍
  67. { if(id==1)//調(diào)節(jié)小時十位時閃爍
  68.   { P2=weixuan[6]; }
  69.               if(id==5)//調(diào)節(jié)年十位時閃爍
  70.               { P2=weixuan[6]; }
  71. }
  72. P0=shuma[a];//顯示數(shù)碼
  73. yanshi(5);
  74. //提高亮度,使每一位數(shù)碼管一樣亮
  75. P0=0xff;//消影
  76. P2=weixuan[1];//第二位數(shù)碼管
  77. if(t<=10)//數(shù)碼管閃爍
  78. { if(id==2)//調(diào)節(jié)小時個位時閃爍
  79. { P2=weixuan[6]; }
  80. if(id==6)//調(diào)節(jié)年十位時閃爍
  81. { P2=weixuan[6]; }
  82. }
  83. P0=fenge[b];//顯示數(shù)碼
  84. yanshi(5);
  85. //提高亮度,使每一位數(shù)碼管一樣亮
  86. P0=0xff;//消影
  87. P2=weixuan[2];//第三位數(shù)碼管
  88. if(t<=10)//數(shù)碼管閃爍
  89. {if(id==3)
  90. //調(diào)節(jié)分十位時閃爍
  91. { P2=weixuan[6]; }
  92.    if(id==7)//調(diào)節(jié)月十位時閃爍
  93.    { P2=weixuan[6]; }
  94. }
  95. P0=shuma[c];//顯示數(shù)碼
  96. yanshi(5);
  97. //提高亮度,使每一位數(shù)碼管一樣亮
  98. P0=0xff;//消影
  99. P2=weixuan[3];//第四位數(shù)碼管
  100. if(t<=10)//數(shù)碼管閃爍
  101. { if(id==4)//調(diào)節(jié)分個位時閃爍
  102.   { P2=weixuan[6]; }
  103.    if(id==8)//調(diào)節(jié)月個位時閃爍
  104.               { P2=weixuan[6]; }
  105. }
  106. P0=fenge[d];//顯示數(shù)碼
  107. yanshi(5);
  108. //提高亮度,使每一位數(shù)碼管一樣亮
  109. P0=0xff;//消影
  110. P2=weixuan[4];//第五位數(shù)碼管
  111. if(t<=10)
  112. {if(id==9)//調(diào)節(jié)日十位時閃爍
  113. { P2=weixuan[6]; }
  114. }
  115. P0=shuma[e];//顯示數(shù)碼
  116. yanshi(5);
  117. //提高亮度,使每一位數(shù)碼管一樣亮
  118. P0=0xff;//消影
  119. P2=weixuan[5];//第六位數(shù)碼管
  120. if(t<=10)
  121. { if(id==10)//調(diào)節(jié)日的個位時閃爍
  122. { P2=weixuan[6]; }
  123. }
  124. P0=shuma[f];//顯示數(shù)碼
  125. yanshi(5);
  126. //提高亮度,使每一位數(shù)碼管一樣亮
  127. }
  128. /************************************
  129.                                           時鐘主程序
  130. ************************************/
  131. void shizhong()
  132. { if(t==20)
  133. //進(jìn)入20次中斷后秒加1,50ms*20=1s
  134. { t=0;
  135.    miao++; }
  136.    if(miao==60)//秒夠60清零,分加1
  137.               { miao=0;
  138.               fen++; }
  139.               if(fen==60)//分夠60清零,時加1
  140.               { fen=0;
  141.                  shi++; }
  142.                 if(shi==24)//時夠24清零,日加1
  143.                 { ri++;
  144.                             shi=0; }
  145. }
  146. /************************************
  147.                                           按鍵1檢測
  148. 按鍵檢測,按的次數(shù)不同進(jìn)入不同調(diào)節(jié)功能
  149. ************************************/
  150. void key1()
  151. { while(s1==0)
  152. { yanshi(300);//延時去抖
  153.    while(s1==0)
  154.   { id++;//根據(jù)ID值的不同進(jìn)入各種功能
  155.               while(s1==0);//等待松開菜單鍵
  156.               yanshi(350);
  157.               while(s1==0); }
  158.               }
  159. }
  160. /************************************
  161.                                           按鍵2檢測
  162.        按鍵檢測,數(shù)字加或秒表開始
  163. ************************************/
  164. void key2()
  165. { while(s2==0)
  166. { yanshi(300);//延時去抖
  167.    while(s2==0)
  168.   { if(id==11)
  169. //只允許在秒表模式下開始
  170.    { TR1=1;//秒表開始 }
  171.               switch(id)//根據(jù)ID值調(diào)整不同的位
  172.               { case 1:a++;break;                                                                                   
  173.                 case 2:b++;break;                                                                                   
  174.                 case 3:c++;break;                                                                                   
  175.                 case 4:d++;break;
  176.                 case 5:a++;break;
  177.                 case 6:b++;break;
  178.                 case 7:c++;break;
  179.                 case 8:d++;break;
  180.                 case 9:e++;break;
  181.                 case 10:f++;break;
  182.                 }
  183.               if(id<=4)
  184. //使時分調(diào)節(jié)時數(shù)值限制在合理范圍
  185.               { if(a==3)                                                                     
  186.                  a=0;
  187.                  if(a==2)
  188.                             { if(b>4)
  189.                                b=0;              }
  190.                  if(b==10)
  191.                             b=0;
  192.                  if(c==6)
  193.                             c=0;
  194.                  if(d==10)
  195.                             d=0;
  196.                             shi=a*10+b;                                                                     
  197.                             fen=c*10+d; }
  198.         if(id>=5,id<11)
  199. //使年月日調(diào)節(jié)時數(shù)值限制在合理范圍
  200.               { if(a==10)
  201.                  a=0;
  202.                 if(b==10)
  203.                  b=0;                                                                                   
  204.                 if(c==2)
  205.                  c=0;
  206.                 if(c*10+d>12)
  207.                  d=0;
  208.                 if(e==4)
  209.                  e=0;
  210.                 if(e*10+f>31)
  211.                  f=0;
  212.                 nian=a*10+b;
  213.                 yue=c*10+d;
  214.                 ri=e*10+f; }
  215.                 miao=0;
  216.                 while(s2==0);
  217. //等待放開數(shù)字加鍵
  218.                 yanshi(350);
  219.                 while(s2==0); }
  220.                             }
  221. }
  222. /************************************
  223.                                           按鍵3檢測
  224.               按鍵檢測,數(shù)字減鍵、秒表暫停鍵
  225. ************************************/
  226. void key3()
  227. { while(s3==0)
  228. { yanshi(300);//延時去抖
  229.    while(s3==0)
  230.   { if(id==11)
  231. //只允許在秒表模式下暫停
  232.    { TR1=0;//秒表暫停 }
  233.               switch(id)
  234.               { case 1:a--;break;                                                                       
  235.                 case 2:b--;break;                                                                                   
  236.                 case 3:c--;break;                                                                                   
  237.                 case 4:d--;break;
  238.                 case 5:a--;break;                                                                     
  239.                 case 6:b--;break;                                                                                   
  240.                 case 7:c--;break;                                                                                   
  241.                 case 8:d--;break;
  242.                 case 9:e--;break;
  243.                 case 10:f--;break; }
  244.               if(id<=4)
  245. //使時分調(diào)節(jié)時數(shù)值限制在合理范圍
  246.               { if(a==-1)
  247.                 a=2;
  248.               if(a==2)
  249.               { if(b>=5)
  250.                 b=0; }                                         
  251.               if(b==-1)
  252.                 b=9;
  253.               if(c==-1)
  254.                 c=5;
  255.               if(d==-1)
  256.                 d=9;
  257.               shi=a*10+b;
  258.               fen=c*10+d; }
  259.               if(id>4,id<11)
  260. //使年月日調(diào)節(jié)時數(shù)值限制在合理范圍
  261.    { if(a==-1)
  262.                 a=9;
  263.               if(b==-1)
  264.                 b=9;
  265.               if(c==-1)
  266.                 c=1;
  267.               if(d==-1)
  268.                 d=9;
  269.               if(c*10+d>12)
  270.                 d=0;
  271.               if(e==-1)
  272.                 e=3;
  273.               if(f==-1)
  274.                 f=9;
  275.               if(e*10+f>31)
  276.                 f=0;            
  277.               nian=a*10+b;
  278.               yue=c*10+d;
  279.               ri=e*10+f;              }                                                                                   
  280.               miao=0;
  281.               while(s3==0);
  282. //等待放開數(shù)字減鍵
  283.               yanshi(350);
  284.               while(s3==0); }
  285.               }
  286. }
  287. /************************************
  288.                             按鍵4檢測--退出菜單
  289. 按鍵檢測,按住S4不放時顯示年月日
  290.           退出功能鍵
  291. ************************************/
  292. void key4()
  293. { while(s4==0)
  294. { yanshi(300);//延時去抖
  295.               while(s4==0)
  296.   { id=12;//退出菜單
  297.               TR1=0;//關(guān)閉定時器1
  298.               hm=0;//退出秒表時初始化秒表
  299.               mm=0;//退出秒表時初始化秒表
  300.               ff=0;//退出秒表時初始化秒表
  301.               shizhong();
  302. //顯示年月時讓時鐘繼續(xù)走
  303.               a=nian/10;
  304.               b=nian%10;
  305.               c=yue/10;
  306.               d=yue%10;
  307.               e=ri/10;
  308.               f=ri%10;
  309.               xianshi(); }
  310.               }
  311. }
  312. /************************************
  313.                                           年月日調(diào)節(jié)
  314. ************************************/
  315. void nyr()
  316. { while(id==5)
  317. //按下菜單鍵5次時進(jìn)入年月日調(diào)節(jié)
  318. { while(id<11)
  319.   { key1();//調(diào)節(jié)位檢測
  320.               key2();//數(shù)值加檢測
  321.               key3();//數(shù)值減檢測
  322.     a=nian/10;
  323.               b=nian%10;
  324.               c=yue/10;
  325.               d=yue%10;
  326.               e=ri/10;
  327.               f=ri%10;
  328.               xianshi();
  329.               miao=0;
  330.               key4();//退出檢測 }
  331.               }
  332. }
  333. /************************************
  334.                                                         秒表
  335.                                           精確到1%秒
  336. ************************************/
  337. void miaobiao()
  338. { while(id==11)
  339. //按下菜單鍵11次時進(jìn)入秒表
  340. { shizhong();
  341. //進(jìn)入秒表功能時讓時鐘繼續(xù)走
  342.   key2();//秒表開始檢測
  343.   if(tt==10)
  344.   {              tt=0;
  345.               hm++; }
  346.   if(hm==100)
  347.   { mm++;
  348.               hm=0; }
  349.   if(mm==60)
  350.   { mm=0;
  351.               ff++; }
  352.    key3();//秒表暫停檢測
  353.               a=ff/10;
  354.               b=ff%10;
  355.               c=mm/10;
  356.               d=mm%10;
  357.               e=hm/10;
  358.               f=hm%10;                           
  359.               xianshi();
  360.               key4();//退出秒表檢測 }

  361. /***********************************
  362.                                           初始化程序
  363. ************************************/
  364. void init()
  365. { t=0;//定時器0中斷次數(shù)初始化
  366.   tt=0;//定時器1中斷次數(shù)初始化
  367.   id=0;//調(diào)整位初始化
  368.   hm=0;//秒表初始化
  369.   mm=0;//秒表初始化
  370.   miao=0;//秒初始化
  371.   fen=53;//分初始化
  372.   shi=12;//時初始化
  373.   ri=5;//日初始化
  374.   yue=5;//月初始化
  375.   nian=9;//年初始化
  376.   EA=1;//開總中斷
  377.   ET0=1;//開定時器0中斷
  378.   ET1=1;//開定時器1中斷
  379.   TMOD=0x11;//設(shè)置定時器為工作方式1
  380.   TH0=(65536-49380)/256;
  381. //裝初值,使定時器0每50毫秒產(chǎn)生一次中斷
  382.   TL0=(65536-49380)%256;
  383. //裝初值,使定時器0每50毫秒產(chǎn)生一次中斷
  384.   TH1=(65536-1001)/256;
  385. //裝初值,使定時器1每1毫秒產(chǎn)生一次中斷
  386.   TL1=(65536-1001)%256;
  387. //裝初值,使定時器1每1毫秒產(chǎn)生一次中斷
  388.   TR0=1;//開啟定時器0
  389.   TR1=1;//開啟定時器1 }
  390. /************************************
  391.                                                         主程序
  392. ************************************/
  393. void main()
  394. { init();//初始化
  395.   while(1)
  396. { shizhong();//時鐘主程序
  397.    key1();//按鍵1檢測
  398.    if(id!=0)
  399. //沒有按下功能鍵時按鍵1按鍵2無效
  400.    { key2();//按鍵2檢測
  401.               key3();//按鍵3檢測 }
  402.               key4();//按鍵4檢測
  403.               nyr();//年月日調(diào)節(jié)
  404.               miaobiao();//秒表
  405.               if(id==12)//S1按鍵功能初始化
  406.               id=0;//S1按鍵功能初始化
  407.               a=shi/10;
  408. //當(dāng)沒有按鍵按下時,顯示時分秒
  409.               b=shi%10;//當(dāng)無按鍵按下時,顯示時分秒
  410.               c=fen/10;//當(dāng)無按鍵按下時,顯示時分秒
  411.               d=fen%10;//當(dāng)無按鍵按下時,顯示時分秒
  412.               e=miao/10;//當(dāng)無按鍵按下時,顯示時分秒
  413.               f=miao%10;//當(dāng)無按鍵按下時,顯示時分秒
  414.               xianshi();//動態(tài)掃描程序 }
  415. }
復(fù)制代碼


完整的Word格式文檔51黑下載地址:
課程論文——基于多位LED數(shù)碼管的數(shù)字鐘設(shè)計.doc (267.24 KB, 下載次數(shù): 29)








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