基于多位LED數(shù)碼管的數(shù)字鐘設(shè)計(jì) 【中文摘要】設(shè)計(jì)的主要內(nèi)容就是結(jié)合軟件Keil和Proteus來(lái)仿真一個(gè)由單片機(jī)AT89C51芯片和多位LED數(shù)碼管為核心的單片機(jī)數(shù)字時(shí)鐘,從而鍛煉出學(xué)習(xí)、設(shè)計(jì)、開(kāi)發(fā)軟、硬件的能力。設(shè)計(jì)已完成的數(shù)宇鐘的基本功能:正常走時(shí)(年、月、日、時(shí)、分、秒)、校正時(shí)間和秒表功能。且操作簡(jiǎn)單、運(yùn)行穩(wěn)定。
1前言 數(shù)字鐘具有走時(shí)準(zhǔn)確,一鐘多用等特點(diǎn),在生活中已經(jīng)得到廣泛的應(yīng)用。雖然現(xiàn)在市場(chǎng)上已有現(xiàn)成的電子鐘集成電路芯片,價(jià)格便宜、使用也方便。但是,人們對(duì)電子產(chǎn)品的應(yīng)用要求越來(lái)越高,數(shù)字鐘不但可以顯示當(dāng)前的時(shí)問(wèn),而且可以顯示期、農(nóng)歷、以及星期等,給人們的生活帶來(lái)了方便。 時(shí)鐘電路在計(jì)算機(jī)系統(tǒng)中起著非常重要的作用,是保證系統(tǒng)正常工作的基礎(chǔ)。在一個(gè)單片機(jī)應(yīng)用系統(tǒng)中,時(shí)鐘有兩方面的含義:一是指為保障系統(tǒng)正常工作的基準(zhǔn)振蕩定時(shí)信號(hào),主要由晶振和外圍電路組成,晶振頻率的大小決定了單片機(jī)系統(tǒng)工作的快慢。二是指系統(tǒng)的標(biāo)準(zhǔn)定時(shí)時(shí)鐘,即定時(shí)時(shí)間,它通常有兩種實(shí)現(xiàn)方法:一是用軟件實(shí)現(xiàn),即用單片機(jī)內(nèi)部的可編程定時(shí)/計(jì)數(shù)器來(lái)實(shí)現(xiàn),但誤差很大;二是用專門的時(shí)鐘芯片實(shí)現(xiàn),在對(duì)時(shí)間精度要求很高的情況下,通常采用這種方法。 本文主要介紹用單片機(jī)內(nèi)部的定時(shí)/計(jì)數(shù)器來(lái)實(shí)現(xiàn)多功能時(shí)鐘的方法,設(shè)計(jì)由單片機(jī)AT89C51芯片和和多位LED數(shù)碼管為核心,輔以必要的電路等,構(gòu)成的一個(gè)單片機(jī)數(shù)字時(shí)鐘。 2設(shè)計(jì)方案 2.1設(shè)計(jì)思路 數(shù)字鐘的功能就是顯示秒、分和小時(shí),其算法是60秒為1分鐘,60分鐘為1小時(shí),一天為24小時(shí)。因此需要秒計(jì)數(shù)器到59秒的時(shí)候,再加1秒時(shí),秒計(jì)數(shù)器清0,分鐘計(jì)數(shù)器加1;秒計(jì)數(shù)器加到59秒,分鐘計(jì)數(shù)器到59分時(shí),再加1秒時(shí),秒計(jì)數(shù)器和分計(jì)數(shù)器同時(shí)清0,小時(shí)計(jì)數(shù)器加1;當(dāng)小時(shí)計(jì)數(shù)器為23小時(shí),分計(jì)數(shù)器為59分,秒為59秒的時(shí)候,再加1秒時(shí),秒計(jì)數(shù)器、分計(jì)數(shù)器和小時(shí)計(jì)數(shù)器同時(shí)清零。數(shù)字鐘的核心就是要產(chǎn)生秒信號(hào),這里利用單片機(jī)的定時(shí)器TO產(chǎn)生。定時(shí)器TO有4種工作方式,可以采用中斷方式和查詢方式編程。 此數(shù)字時(shí)鐘由主模塊(AT89C51)、顯示模塊(多位LED數(shù)碼管)、控制模塊和計(jì)時(shí)運(yùn)算模塊四大部分組成。其中控制模塊和計(jì)時(shí)運(yùn)算模塊主要對(duì)年月日、時(shí)分秒的數(shù)值顯示和調(diào)整進(jìn)行操作,并且秒計(jì)算到60時(shí),自動(dòng)清零并向分進(jìn)1;分計(jì)算到60時(shí),自動(dòng)清零并向時(shí)進(jìn)1;時(shí)計(jì)算到24時(shí),自動(dòng)清零。這樣,就形成了循環(huán)計(jì)時(shí),顯示模塊主要用來(lái)顯示當(dāng)前計(jì)數(shù)值。AT89C51是整個(gè)設(shè)計(jì)的核心,主要用來(lái)產(chǎn)生定時(shí)中斷,傳輸數(shù)據(jù)和控制各個(gè)部件工作。 數(shù)字鐘格式:XX.XX.XX ,從左向右分別為時(shí)/年、分/月、秒/日。時(shí)分秒完成由秒01一直加1至59,再恢復(fù)00;分加1,由00至01,一直加1至59,再恢復(fù)00;時(shí)加1,時(shí)由00加至23后秒分時(shí)全部清零;該鐘使用TO做定時(shí)中斷。 時(shí)鐘校正:走時(shí)過(guò)程中直接調(diào)整且不影響走時(shí)準(zhǔn)確性。按下相應(yīng)次數(shù)功能鍵S1進(jìn)入相應(yīng)數(shù)位的調(diào)整;按下S2按鍵加,相應(yīng)數(shù)位加1;按下S3按鍵減,相應(yīng)數(shù)位減1。 秒表功能:按下功能鍵S1對(duì)應(yīng)次數(shù),進(jìn)入秒表計(jì)時(shí)功能;按下S2按鍵加,開(kāi)始計(jì)時(shí);按下S3按鍵減,暫停計(jì)時(shí);暫停計(jì)時(shí)時(shí),按下S2按鍵加,繼續(xù)計(jì)時(shí);按下S4按鍵,退出。 年月顯示:按住S4按鍵不放,顯示年月日。 2.2模塊功能說(shuō)明 (1)單片機(jī)AT89C51簡(jiǎn)介,如下圖1 圖1 AT89C51引腳圖 VCC:供電電壓。
GND:接地。
P0口:P0口為一個(gè)8位漏級(jí)開(kāi)路雙向I/O口,每腳可吸收8TTL門電流。當(dāng)P1口的管腳第一次寫1時(shí),被定義為高阻輸入。P0能夠用于外部程序數(shù)據(jù)存儲(chǔ)器,它可以被定義為數(shù)據(jù)/地址的第八位。在FIASH編程時(shí),P0 口作為原碼輸入口,當(dāng)FIASH進(jìn)行校驗(yàn)時(shí),P0輸出原碼,此時(shí)P0外部必須被拉高。P1口:P1口是一個(gè)內(nèi)部提供上拉電阻的8位雙向I/O口,P1口緩沖器能接收輸出4TTL門電流。P1口管腳寫入1后,被內(nèi)部上拉為高,可用作輸入,P1口被外部下拉為低電平時(shí),將輸出電流,這是由于內(nèi)部上拉的緣故。在FLASH編程和校驗(yàn)時(shí),P1口作為第八位地址接口。 P2口:P2口為一個(gè)內(nèi)部上拉電阻的8位雙向I/O口,P2口緩沖器可接收,輸出4個(gè)TTL門電流,當(dāng)P2口被寫“1”時(shí),其管腳被內(nèi)部上拉電阻拉高,且作為輸入。并因此作為輸入時(shí),P2口的管腳被外部拉低,將輸出電流。這是由于內(nèi)部上拉的緣故。P2口當(dāng)用于外部程序存儲(chǔ)器或16位地址外部數(shù)據(jù)存儲(chǔ)器進(jìn)行存取時(shí),P2口輸出地址的高八位。在給出地址“1”時(shí),它利用內(nèi)部上拉優(yōu)勢(shì),當(dāng)對(duì)外部八位地址數(shù)據(jù)存儲(chǔ)器進(jìn)行讀寫時(shí),P2口輸出其特殊功能寄存器的內(nèi)容。P2口在FLASH編程和校驗(yàn)時(shí)接收高八位地址信號(hào)和控制信號(hào)。 P3口:P3口管腳是8個(gè)帶內(nèi)部上拉電阻的雙向I/O口,可接收輸出4個(gè)TTL門電流。當(dāng)P3口寫入“1”后,它們被內(nèi)部上拉為高電平,并用作輸入。作為輸入,由于外部下拉為低電平,P3口將輸出電流(ILL)這是由于上拉的緣故。 RST:復(fù)位輸入。當(dāng)振蕩器復(fù)位器件時(shí),要保持RST腳兩個(gè)機(jī)器周期的高電平時(shí)間。
ALE/PROG:當(dāng)訪問(wèn)外部存儲(chǔ)器時(shí),地址鎖存允許的輸出電平用于鎖存地址的地位字節(jié)。在FLASH編程期間,此引腳用于輸入編程脈沖。在平時(shí),ALE端以不變的頻率周期輸出正脈沖信號(hào),此頻率為振蕩器頻率的1/6。因此它可用作對(duì)外部輸出的脈沖或用于定時(shí)目的。然而要注意的是:每當(dāng)用作外部數(shù)據(jù)存儲(chǔ)器時(shí),將跳過(guò)一個(gè)ALE脈沖。如想禁止ALE的輸出可在SFR8EH地址上置0。此時(shí), ALE只有在執(zhí)行MOVX,MOVC指令是ALE才起作用。另外,該引腳被略微拉高。如果微處理在外部執(zhí)行狀態(tài)ALE禁止,置位無(wú)效。 /PSEN:外部程序存儲(chǔ)器的選通信號(hào)。在由外部程序存儲(chǔ)器取指期間,每個(gè)機(jī)器周期兩次/PSEN有效。但在訪問(wèn)外部數(shù)據(jù)存儲(chǔ)器時(shí),這兩次有效的/PSEN信號(hào)將不出現(xiàn)。
/EA/VPP:當(dāng)/EA保持低電平時(shí),則在此期間外部程序存儲(chǔ)器(0000H-FFFFH),不管是否有內(nèi)部程序存儲(chǔ)器。注意加密方式1時(shí),/EA將內(nèi)部鎖定為RESET;當(dāng)/EA端保持高電平時(shí),此間內(nèi)部程序存儲(chǔ)器。在FLASH編程期間,此引腳也用于施加12V編程電源(VPP)。 XTAL1:反向振蕩放大器的輸入及內(nèi)部時(shí)鐘工作電路的輸入。 XTAL2:來(lái)自反向振蕩器的輸出。 ①TMOD定時(shí)器/計(jì)數(shù)器方式寄存器
定時(shí)器方式控制寄存器TMOD在特殊功能寄存器中,字節(jié)地址為89H,無(wú)位地址。 ②TCON定時(shí)器/計(jì)數(shù)器控制寄存器
TCON在特殊功能寄存器中,字節(jié)地址為88H,位地址(由低位到高位)為88H--8FH,由于有位地址,十分便于進(jìn)行位操作。 ③定時(shí)器/計(jì)數(shù)器的初始化 由于定時(shí)器/計(jì)數(shù)器的功能是由軟件編程確定的,所以一般在使用定時(shí)/計(jì)數(shù)器前都要對(duì)其進(jìn)行初始化,使其按設(shè)定的功能工作.初始貨的步驟一般如下: - 確定工作方式(即對(duì)TMOD賦值),預(yù)置定時(shí)或計(jì)數(shù)的初值。
2、根據(jù)需要開(kāi)放定時(shí)器/計(jì)數(shù)器的中斷(直接對(duì)IE位賦值)。 3、啟動(dòng)定時(shí)器/計(jì)數(shù)器。 (2)多位LED數(shù)碼管7SEG-MPX6-CA簡(jiǎn)介如下圖2 圖2 7SEG-MPX6-CA數(shù)碼管模型圖 7SEG-MPX6-CA是7段6位共陽(yáng)級(jí)數(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.共陽(yáng)極LED數(shù)碼管,它是將發(fā)光二極管的陽(yáng)極(正極)短接后作為公共陽(yáng)極.當(dāng)驅(qū)動(dòng)信號(hào)為低電平才能發(fā)光。 本實(shí)驗(yàn)采用動(dòng)態(tài)顯示,即節(jié)省了I/O口,又能降低能耗。 顯示過(guò)程注意消影。 (3)其余元件如下圖3 BUTTON PNP 圖3 所需用到的其余元件 2.3系統(tǒng)總體原理圖如下圖4 圖4 基于多位LED數(shù)碼管的數(shù)字鐘總圖 2.4電路圖的接法設(shè)計(jì) 鑒于仿真的單片機(jī)數(shù)字時(shí)鐘的美觀性,取消各模塊間的可見(jiàn)連線,利用Proteus中的Edit Wire Style 按鈕來(lái)連接各個(gè)端口。 單片機(jī)P1端口接按鍵S輸入;單片機(jī)P0端口接段碼驅(qū)動(dòng)到數(shù)碼管;單片機(jī)P2端口接位碼驅(qū)動(dòng)到數(shù)碼管。 2.5按鍵功能說(shuō)明 1、功能鍵--根據(jù)按下的次數(shù),分別調(diào)節(jié)時(shí)間和年月,按位調(diào)節(jié),同時(shí)調(diào)整位閃爍,按下11次后進(jìn)入秒表,期間可以按退出鍵退出功能調(diào)節(jié)或秒表。 2、數(shù)字加---進(jìn)入時(shí)間或年月調(diào)節(jié)時(shí),按此鍵閃爍位數(shù)字加一,秒表模式下為秒表開(kāi)始鍵。 3、數(shù)字減---進(jìn)入時(shí)間或年月調(diào)節(jié)時(shí),按此鍵閃爍位數(shù)字減一,秒表模式下為秒表暫停鍵。 4、退出鍵---進(jìn)入時(shí)間或年月調(diào)節(jié)時(shí),按此鍵保存調(diào)節(jié)并退出,沒(méi)進(jìn)入時(shí)間或年月調(diào)節(jié)時(shí)按此鍵顯示年月。 3 程序流程圖 3.1時(shí)鐘顯示程序流程圖如下圖5 圖5 時(shí)鐘顯示程序流程圖 3.2外部中斷處理流程圖如下圖6 圖6 外部中斷處理流程圖
3.3函數(shù)模塊及功能 (1)Void Time0() interrupt 1 定時(shí)器0中斷服務(wù)程序,供時(shí)鐘主程序使用 (2)Void Time1() interrupt 3 定時(shí)器1中斷服務(wù)程序,供秒表使用 (3)Void yanshi(uint z) 延時(shí)程序,供動(dòng)態(tài)掃描與按鍵去抖 (4)Void xianshi() 動(dòng)態(tài)掃描程序 (5)Void shizhong() 時(shí)鐘主程序 (6)Void key1() 按鍵1檢測(cè),按的次數(shù)不同進(jìn)入不同調(diào)節(jié)功能 (7)Void key2() 按鍵2檢測(cè),數(shù)字加或秒表計(jì)時(shí) (8)Void key3() 按鍵3檢測(cè),數(shù)字減或秒表暫停 (9)Void key4() 按鍵4檢測(cè),按住不放顯示年月,退出功能 (10)Void nyr() 年月日調(diào)節(jié) (11)Void miaobiao() 秒表,精確到1%秒 (12)Void init() 初始化設(shè)置中斷 4 設(shè)計(jì)總結(jié) 這次對(duì)數(shù)字鐘的設(shè)計(jì),經(jīng)過(guò)認(rèn)真地查找資料、編寫程序以及調(diào)試程序,結(jié)果達(dá)到驗(yàn)證無(wú)誤。從開(kāi)始設(shè)計(jì)到仿真實(shí)現(xiàn),再到論文文章的完成,每走一步對(duì)我來(lái)說(shuō)都是新的嘗試與挑戰(zhàn)。從單片機(jī)模塊數(shù)字鐘的設(shè)計(jì)過(guò)程中我找到了一些單片機(jī)開(kāi)發(fā)的規(guī)律:先了解所有元件的具體內(nèi)容,從而畫出其電路圖,使數(shù)字鐘從簡(jiǎn)易變成多功能的方式,雖沒(méi)有做鬧鈴功能的多功能數(shù)字鐘,卻知曉了其方法。從而更好地讓自己踏入單片機(jī)應(yīng)用領(lǐng)域的第一步。 【參考文獻(xiàn)】 [1]趙文博,劉文濤.單片機(jī)語(yǔ)言C51程序設(shè)計(jì)[M].人民郵電出版社,2006 [2]石從剛.MCS-51單片機(jī)原理與應(yīng)用實(shí)驗(yàn)實(shí)訓(xùn)教程[M].北京航空航天大學(xué)出版社,2007 [3]張靖武.單片機(jī)系統(tǒng)的PROTEUS設(shè)計(jì)與仿真[M].電子工業(yè)出版社,2009 [4]李精華.基于數(shù)字鐘設(shè)計(jì)的單片機(jī)課程項(xiàng)目開(kāi)發(fā)[J].桂林航天工業(yè)高等專科學(xué)校學(xué)報(bào),2010 附錄: 程序代碼及說(shuō)明
- #include <AT89X51.H>
- #define uint unsigned int
- #define uchar unsigned char
- /*********************************
- 定義變量和數(shù)碼表
- *********************************/
- uchar code shuma[]={
- 0x14,0xd7,0x4c,0x45,0x87,
- 0x25,0x24,0x57,0x04,0x05};//數(shù)碼表
- uchar code fenge[]={
- 0x10,0xD3,0x48,0x41,0x83,
- 0x21,0x20,0x53,0x00,0x01};
- //帶點(diǎn)的數(shù)碼表
- uchar code weixuan []={
- 0x7f,0xBf,0xDf,0xEf,0xf7,0xfb,0xff};
- //位選控制表
- uchar t,tt,a,b,c,d,e,f,x,y,id,fen
- ,miao,hm,mm,ff,shi,ri,yue,nian;
- sbit s1=P1^0;//
- 菜單鍵,按下的次數(shù)進(jìn)入不同的調(diào)節(jié)功能
- sbit s2=P1^1;//數(shù)字加鍵、秒表開(kāi)始鍵
- sbit s3=P1^2;//數(shù)字減鍵、秒表暫停鍵
- sbit s4=P1^3;
- //顯示年月日,菜單退出鍵
- /**********************************
- 定時(shí)器0中斷服務(wù)程序
- 供時(shí)鐘主程序使用
- **********************************/
- void Time0()interrupt 1
- { TH0=(65536-49990)/256;
- //裝初值,使定時(shí)器0每50毫秒產(chǎn)生一次中斷
- TL0=(65536-49990)%256;
- //裝初值,使定時(shí)器0每50毫秒產(chǎn)生一次中斷
- t++;//中斷次數(shù)
- if(t==21)
- //在調(diào)節(jié)時(shí)間或年月時(shí)把t控制在20以內(nèi)
- //避免中斷次數(shù)不受控
- { t=0; }
- }
- /************************************
- 定時(shí)器1中斷服務(wù)程序
- 供秒表使用
- ************************************/
- void Time1() interrupt 3
- { TH1=(65536-1001)/256;
- //裝初值,使定時(shí)器1每1毫秒產(chǎn)生一次中斷
- TL1=(65536-1001)%256;
- //裝初值,使定時(shí)器1每1毫秒產(chǎn)生一次中斷
- tt++;
- if(tt==11)
- tt=0; }
- /************************************
- 延時(shí)程序
- 供動(dòng)態(tài)掃描和按鍵去抖用
- 如果是實(shí)物的話,x的值設(shè)為3就可以了
- ************************************/
- void yanshi(uint z)
- { for (x=25;x>0;x--)
- for (y=z;y>0;y--); }
- /************************************
- 動(dòng)態(tài)掃描程序
- ************************************/
- void xianshi ()
- { P0=0xff;//消影
- P2=weixuan[0];//第一位數(shù)碼管
- if(t<=10)//數(shù)碼管閃爍
- { if(id==1)//調(diào)節(jié)小時(shí)十位時(shí)閃爍
- { P2=weixuan[6]; }
- if(id==5)//調(diào)節(jié)年十位時(shí)閃爍
- { P2=weixuan[6]; }
- }
- P0=shuma[a];//顯示數(shù)碼
- yanshi(5);
- //提高亮度,使每一位數(shù)碼管一樣亮
- P0=0xff;//消影
- P2=weixuan[1];//第二位數(shù)碼管
- if(t<=10)//數(shù)碼管閃爍
- { if(id==2)//調(diào)節(jié)小時(shí)個(gè)位時(shí)閃爍
- { P2=weixuan[6]; }
- if(id==6)//調(diào)節(jié)年十位時(shí)閃爍
- { P2=weixuan[6]; }
- }
- P0=fenge[b];//顯示數(shù)碼
- yanshi(5);
- //提高亮度,使每一位數(shù)碼管一樣亮
- P0=0xff;//消影
- P2=weixuan[2];//第三位數(shù)碼管
- if(t<=10)//數(shù)碼管閃爍
- {if(id==3)
- //調(diào)節(jié)分十位時(shí)閃爍
- { P2=weixuan[6]; }
- if(id==7)//調(diào)節(jié)月十位時(shí)閃爍
- { P2=weixuan[6]; }
- }
- P0=shuma[c];//顯示數(shù)碼
- yanshi(5);
- //提高亮度,使每一位數(shù)碼管一樣亮
- P0=0xff;//消影
- P2=weixuan[3];//第四位數(shù)碼管
- if(t<=10)//數(shù)碼管閃爍
- { if(id==4)//調(diào)節(jié)分個(gè)位時(shí)閃爍
- { P2=weixuan[6]; }
- if(id==8)//調(diào)節(jié)月個(gè)位時(shí)閃爍
- { P2=weixuan[6]; }
- }
- P0=fenge[d];//顯示數(shù)碼
- yanshi(5);
- //提高亮度,使每一位數(shù)碼管一樣亮
- P0=0xff;//消影
- P2=weixuan[4];//第五位數(shù)碼管
- if(t<=10)
- {if(id==9)//調(diào)節(jié)日十位時(shí)閃爍
- { P2=weixuan[6]; }
- }
- P0=shuma[e];//顯示數(shù)碼
- yanshi(5);
- //提高亮度,使每一位數(shù)碼管一樣亮
- P0=0xff;//消影
- P2=weixuan[5];//第六位數(shù)碼管
- if(t<=10)
- { if(id==10)//調(diào)節(jié)日的個(gè)位時(shí)閃爍
- { P2=weixuan[6]; }
- }
- P0=shuma[f];//顯示數(shù)碼
- yanshi(5);
- //提高亮度,使每一位數(shù)碼管一樣亮
- }
- /************************************
- 時(shí)鐘主程序
- ************************************/
- void shizhong()
- { if(t==20)
- //進(jìn)入20次中斷后秒加1,50ms*20=1s
- { t=0;
- miao++; }
- if(miao==60)//秒夠60清零,分加1
- { miao=0;
- fen++; }
- if(fen==60)//分夠60清零,時(shí)加1
- { fen=0;
- shi++; }
- if(shi==24)//時(shí)夠24清零,日加1
- { ri++;
- shi=0; }
- }
- /************************************
- 按鍵1檢測(cè)
- 按鍵檢測(cè),按的次數(shù)不同進(jìn)入不同調(diào)節(jié)功能
- ************************************/
- void key1()
- { while(s1==0)
- { yanshi(300);//延時(shí)去抖
- while(s1==0)
- { id++;//根據(jù)ID值的不同進(jìn)入各種功能
- while(s1==0);//等待松開(kāi)菜單鍵
- yanshi(350);
- while(s1==0); }
- }
- }
- /************************************
- 按鍵2檢測(cè)
- 按鍵檢測(cè),數(shù)字加或秒表開(kāi)始
- ************************************/
- void key2()
- { while(s2==0)
- { yanshi(300);//延時(shí)去抖
- while(s2==0)
- { if(id==11)
- //只允許在秒表模式下開(kāi)始
- { TR1=1;//秒表開(kāi)始 }
- switch(id)//根據(jù)ID值調(diào)整不同的位
- { case 1:a++;break;
- case 2:b++;break;
- case 3:c++;break;
- case 4:d++;break;
- case 5:a++;break;
- case 6:b++;break;
- case 7:c++;break;
- case 8:d++;break;
- case 9:e++;break;
- case 10:f++;break;
- }
- if(id<=4)
- //使時(shí)分調(diào)節(jié)時(shí)數(shù)值限制在合理范圍
- { if(a==3)
- a=0;
- if(a==2)
- { if(b>4)
- b=0; }
- if(b==10)
- b=0;
- if(c==6)
- c=0;
- if(d==10)
- d=0;
- shi=a*10+b;
- fen=c*10+d; }
- if(id>=5,id<11)
- //使年月日調(diào)節(jié)時(shí)數(shù)值限制在合理范圍
- { if(a==10)
- a=0;
- if(b==10)
- b=0;
- if(c==2)
- c=0;
- if(c*10+d>12)
- d=0;
- if(e==4)
- e=0;
- if(e*10+f>31)
- f=0;
- nian=a*10+b;
- yue=c*10+d;
- ri=e*10+f; }
- miao=0;
- while(s2==0);
- //等待放開(kāi)數(shù)字加鍵
- yanshi(350);
- while(s2==0); }
- }
- }
- /************************************
- 按鍵3檢測(cè)
- 按鍵檢測(cè),數(shù)字減鍵、秒表暫停鍵
- ************************************/
- void key3()
- { while(s3==0)
- { yanshi(300);//延時(shí)去抖
- while(s3==0)
- { if(id==11)
- //只允許在秒表模式下暫停
- { TR1=0;//秒表暫停 }
- switch(id)
- { case 1:a--;break;
- case 2:b--;break;
- case 3:c--;break;
- case 4:d--;break;
- case 5:a--;break;
- case 6:b--;break;
- case 7:c--;break;
- case 8:d--;break;
- case 9:e--;break;
- case 10:f--;break; }
- if(id<=4)
- //使時(shí)分調(diào)節(jié)時(shí)數(shù)值限制在合理范圍
- { if(a==-1)
- a=2;
- if(a==2)
- { if(b>=5)
- b=0; }
- if(b==-1)
- b=9;
- if(c==-1)
- c=5;
- if(d==-1)
- d=9;
- shi=a*10+b;
- fen=c*10+d; }
- if(id>4,id<11)
- //使年月日調(diào)節(jié)時(shí)數(shù)值限制在合理范圍
- { if(a==-1)
- a=9;
- if(b==-1)
- b=9;
- if(c==-1)
- c=1;
- if(d==-1)
- d=9;
- if(c*10+d>12)
- d=0;
- if(e==-1)
- e=3;
- if(f==-1)
- f=9;
- if(e*10+f>31)
- f=0;
- nian=a*10+b;
- yue=c*10+d;
- ri=e*10+f; }
- miao=0;
- while(s3==0);
- //等待放開(kāi)數(shù)字減鍵
- yanshi(350);
- while(s3==0); }
- }
- }
- /************************************
- 按鍵4檢測(cè)--退出菜單
- 按鍵檢測(cè),按住S4不放時(shí)顯示年月日
- 退出功能鍵
- ************************************/
- void key4()
- { while(s4==0)
- { yanshi(300);//延時(shí)去抖
- while(s4==0)
- { id=12;//退出菜單
- TR1=0;//關(guān)閉定時(shí)器1
- hm=0;//退出秒表時(shí)初始化秒表
- mm=0;//退出秒表時(shí)初始化秒表
- ff=0;//退出秒表時(shí)初始化秒表
- shizhong();
- //顯示年月時(shí)讓時(shí)鐘繼續(xù)走
- a=nian/10;
- b=nian%10;
- c=yue/10;
- d=yue%10;
- e=ri/10;
- f=ri%10;
- xianshi(); }
- }
- }
- /************************************
- 年月日調(diào)節(jié)
- ************************************/
- void nyr()
- { while(id==5)
- //按下菜單鍵5次時(shí)進(jìn)入年月日調(diào)節(jié)
- { while(id<11)
- { key1();//調(diào)節(jié)位檢測(cè)
- key2();//數(shù)值加檢測(cè)
- key3();//數(shù)值減檢測(cè)
- a=nian/10;
- b=nian%10;
- c=yue/10;
- d=yue%10;
- e=ri/10;
- f=ri%10;
- xianshi();
- miao=0;
- key4();//退出檢測(cè) }
- }
- }
- /************************************
- 秒表
- 精確到1%秒
- ************************************/
- void miaobiao()
- { while(id==11)
- //按下菜單鍵11次時(shí)進(jìn)入秒表
- { shizhong();
- //進(jìn)入秒表功能時(shí)讓時(shí)鐘繼續(xù)走
- key2();//秒表開(kāi)始檢測(cè)
- if(tt==10)
- { tt=0;
- hm++; }
- if(hm==100)
- { mm++;
- hm=0; }
- if(mm==60)
- { mm=0;
- ff++; }
- key3();//秒表暫停檢測(cè)
- a=ff/10;
- b=ff%10;
- c=mm/10;
- d=mm%10;
- e=hm/10;
- f=hm%10;
- xianshi();
- key4();//退出秒表檢測(cè) }
-
- /***********************************
- 初始化程序
- ************************************/
- void init()
- { t=0;//定時(shí)器0中斷次數(shù)初始化
- tt=0;//定時(shí)器1中斷次數(shù)初始化
- id=0;//調(diào)整位初始化
- hm=0;//秒表初始化
- mm=0;//秒表初始化
- miao=0;//秒初始化
- fen=53;//分初始化
- shi=12;//時(shí)初始化
- ri=5;//日初始化
- yue=5;//月初始化
- nian=9;//年初始化
- EA=1;//開(kāi)總中斷
- ET0=1;//開(kāi)定時(shí)器0中斷
- ET1=1;//開(kāi)定時(shí)器1中斷
- TMOD=0x11;//設(shè)置定時(shí)器為工作方式1
- TH0=(65536-49380)/256;
- //裝初值,使定時(shí)器0每50毫秒產(chǎn)生一次中斷
- TL0=(65536-49380)%256;
- //裝初值,使定時(shí)器0每50毫秒產(chǎn)生一次中斷
- TH1=(65536-1001)/256;
- //裝初值,使定時(shí)器1每1毫秒產(chǎn)生一次中斷
- TL1=(65536-1001)%256;
- //裝初值,使定時(shí)器1每1毫秒產(chǎn)生一次中斷
- TR0=1;//開(kāi)啟定時(shí)器0
- TR1=1;//開(kāi)啟定時(shí)器1 }
- /************************************
- 主程序
- ************************************/
- void main()
- { init();//初始化
- while(1)
- { shizhong();//時(shí)鐘主程序
- key1();//按鍵1檢測(cè)
- if(id!=0)
- //沒(méi)有按下功能鍵時(shí)按鍵1按鍵2無(wú)效
- { key2();//按鍵2檢測(cè)
- key3();//按鍵3檢測(cè) }
- key4();//按鍵4檢測(cè)
- nyr();//年月日調(diào)節(jié)
- miaobiao();//秒表
- if(id==12)//S1按鍵功能初始化
- id=0;//S1按鍵功能初始化
- a=shi/10;
- //當(dāng)沒(méi)有按鍵按下時(shí),顯示時(shí)分秒
- b=shi%10;//當(dāng)無(wú)按鍵按下時(shí),顯示時(shí)分秒
- c=fen/10;//當(dāng)無(wú)按鍵按下時(shí),顯示時(shí)分秒
- d=fen%10;//當(dāng)無(wú)按鍵按下時(shí),顯示時(shí)分秒
- e=miao/10;//當(dāng)無(wú)按鍵按下時(shí),顯示時(shí)分秒
- f=miao%10;//當(dāng)無(wú)按鍵按下時(shí),顯示時(shí)分秒
- xianshi();//動(dòng)態(tài)掃描程序 }
- }
復(fù)制代碼
完整的Word格式文檔51黑下載地址:
課程論文——基于多位LED數(shù)碼管的數(shù)字鐘設(shè)計(jì).doc
(267.24 KB, 下載次數(shù): 29)
2018-5-19 12:52 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
|