1系統(tǒng)分析 1.1功能 本文設(shè)計(jì)一款采用LED顯示器件顯示的電子時(shí)鐘,有效克服了時(shí)鐘存在的誤差問(wèn)題,并能在夜間不必其它照明就能看到時(shí)間,且以60只發(fā)光管實(shí)現(xiàn)秒顯示,接近于傳統(tǒng)的秒針來(lái)顯示秒的形式。另加七只裝飾用的LED燈,使整個(gè)時(shí)鐘顯的相當(dāng)美觀新穎,故還可作為室內(nèi)裝飾用。 電子鐘的外觀如圖1所示。周邊60只發(fā)光管順時(shí)旋轉(zhuǎn)來(lái)顯示秒,中間四只LED數(shù)碼管用于顯示時(shí)間,中下方的七只LED燈順時(shí)旋轉(zhuǎn),供裝飾用。其主要功能有: (1)整點(diǎn)報(bào)時(shí); (2)四只LED數(shù)碼管顯示當(dāng)前時(shí)分; (3)每隔一秒鐘周邊的60只LED發(fā)光管旋轉(zhuǎn)一格,裝飾用的LED每隔一秒旋轉(zhuǎn)一次; (4)當(dāng)發(fā)生停電事件時(shí),由后備電池供電,系統(tǒng)進(jìn)入低功耗狀態(tài),所有顯示部件停止顯示,這樣即延長(zhǎng)了電池的壽命,同時(shí)又保證了CPU繼續(xù)計(jì)數(shù),不至于因停電而時(shí)鐘停止運(yùn)行。當(dāng)恢復(fù)供電后,系統(tǒng)自動(dòng)恢復(fù)工作狀態(tài),不影響計(jì)時(shí)。
1.2方案論證 電腦鐘的原理框圖如圖2所示。它由以下幾個(gè)部件組成:?jiǎn)纹瑱C(jī)89C2051、電源、時(shí)分顯示部件、60秒旋轉(zhuǎn)譯碼驅(qū)動(dòng)電路。 file:///C:/Users/jiaxin/AppData/Local/Temp/msohtmlclip1/01/clip_image002.png
時(shí)分顯示采用動(dòng)態(tài)掃描,以降低對(duì)單片機(jī)端口數(shù)的要求,同時(shí)也降低系統(tǒng)的功耗。時(shí)分顯示模塊、60秒旋轉(zhuǎn)譯碼驅(qū)動(dòng)電路以及顯示驅(qū)動(dòng)都通過(guò)89C2051的I/O口控制。 電源部分:電源部分有二部分組成。一部分是由220V的市電通過(guò)變壓、整流穩(wěn)壓來(lái)得到+5V電壓,維持系統(tǒng)的正常工作;另一部分是由3V的電池供電,以保證停電時(shí)正常走時(shí)。正常情況下電池是不提供電能的,以保證電池的壽命。
2 系統(tǒng)設(shè)計(jì) 2.1 系統(tǒng)硬件電路的設(shè)計(jì) 本系統(tǒng)的應(yīng)用程序主要由主程序、中斷服務(wù)程序和子程序組成。主程序的任務(wù)是對(duì)系統(tǒng)進(jìn)行初始化,實(shí)現(xiàn)參數(shù)輸入,并控制電加熱爐的正常運(yùn)行。主程序主要由系統(tǒng)初始化、數(shù)據(jù) 2.1.1 60秒旋轉(zhuǎn)譯碼驅(qū)動(dòng)原理 按常規(guī)傳統(tǒng)設(shè)計(jì),需60進(jìn)制譯碼驅(qū)動(dòng)電路才能實(shí)現(xiàn)60秒旋轉(zhuǎn)譯碼驅(qū)動(dòng),若用六片十進(jìn)制計(jì)數(shù)譯碼器構(gòu)成六十進(jìn)制計(jì)數(shù)譯碼電路,則電路連線多(需要120根連線),硬件電路龐大,開(kāi)銷大。為此,本文巧妙地采用了兩片CD4017進(jìn)行六十進(jìn)制計(jì)數(shù)譯碼,實(shí)現(xiàn)60秒旋轉(zhuǎn)譯碼驅(qū)動(dòng)。既減少了電路的復(fù)雜程度又可降低了成本。圖3為CD4017功能引腳圖和工作時(shí)序圖。
CD4017集成電路是十進(jìn)制計(jì)數(shù)/時(shí)序譯碼器,共有10個(gè)譯碼輸出Q0~Q9;每個(gè)譯碼輸出通常處于低電平,且在時(shí)鐘脈沖由低到高的上升沿輸出高電平;每個(gè)高電平輸出維持1個(gè)時(shí)鐘周期;每輸入10個(gè)時(shí)鐘脈沖,輸出一個(gè)進(jìn)位脈沖,因此進(jìn)位輸出信號(hào)可作為下一級(jí)計(jì)數(shù)器的時(shí)鐘信號(hào)。在清零輸入端(R)加高電平或正脈沖時(shí),只有輸出端Q0為高電平,其余各輸出端均為低電平“0”。 為實(shí)現(xiàn)對(duì)發(fā)光二極管的驅(qū)動(dòng),將每一個(gè)譯碼輸出端口接一只發(fā)光二極管,并將二極管串聯(lián)限流電阻后接地。當(dāng)譯碼端口Q0~Q9中任一端口為高電平,則對(duì)應(yīng)的發(fā)光二極管點(diǎn)亮,如圖4(左)所示。根據(jù)CD4017的功能,可發(fā)現(xiàn)其10個(gè)輸出的高電平是相互排斥的,即任一時(shí)刻只有一只發(fā)光二極管點(diǎn)亮,因此可電路進(jìn)一步簡(jiǎn)化為如圖4(右)所示,從而簡(jiǎn)化電路設(shè)計(jì)。
在本電子鐘設(shè)計(jì)中,每秒點(diǎn)亮一個(gè)發(fā)光二極管,循環(huán)點(diǎn)亮一周共需60個(gè)發(fā)光二極管,若用上述的6片CD4017實(shí)現(xiàn)驅(qū)動(dòng),顯然電路復(fù)雜。為此我們選用兩片CD4017和一片6反相器,采用“縱橫雙譯碼”技術(shù),巧妙地實(shí)現(xiàn)60秒旋轉(zhuǎn)譯碼驅(qū)動(dòng),其中一片接成10進(jìn)制,一片接成6進(jìn)制,實(shí)現(xiàn)6×10=60的功能,具體連接方法如圖5所示。
將周期為1秒的輸入脈沖作為其中一片CD4017的時(shí)鐘脈沖,而此片的級(jí)聯(lián)進(jìn)位輸出端(QC)作為另一片的時(shí)鐘輸入,并將Q6與復(fù)位端相連。在兩片譯碼輸出端交叉點(diǎn)上接入發(fā)光二極管,構(gòu)成6×10矩陣。根據(jù)CD4017時(shí)序特點(diǎn),在初始狀態(tài),作為高位(縱)的CD4017譯碼器輸出端口Q0處于高平,經(jīng)反相器反相后為低電平。當(dāng)作為低位(橫)的CD4017譯碼器輸出端口Q0~Q9依次輸出高電平后,則對(duì)應(yīng)的二極管LD1~LD10依次點(diǎn)亮;此后由于QC端的進(jìn)位,高位CD4017譯碼輸出端口Q1輸出高電平,反相后輸出低電平,當(dāng)?shù)臀坏腃D4017譯碼輸出端口Q0~Q9依次輸出高電平后,二極管LD11~LD20依次點(diǎn)亮。如此往復(fù),直至高位Q6向復(fù)位端輸入高電平,CD4017復(fù)位,60秒循環(huán)點(diǎn)亮重新開(kāi)始。 2.1.2 時(shí)分顯示部件 由于系統(tǒng)要顯示的內(nèi)容較簡(jiǎn)單,顯示量不多,所以選用數(shù)碼管既方便又經(jīng)濟(jì)。LED有共陰極和共陽(yáng)極兩種。二極管的陰極連接在一起,通常此公共陰極接地,而共陽(yáng)極則將發(fā)光二極管的陽(yáng)極連接在一起,接入+5V的電壓。一位顯示器由8個(gè)發(fā)光二極管組成,其中7個(gè)發(fā)光二極管構(gòu)成字型“8”的各個(gè)筆劃(段)a~g,另一個(gè)小數(shù)點(diǎn)為dp發(fā)光二極管。當(dāng)在某段發(fā)光二極管施加一定的正向電壓時(shí),該段筆劃即亮;不加電壓則暗。為了保護(hù)各段LED不被損壞,需外加限流電阻,如圖6所示。
眾所周知,LED顯示數(shù)碼管通常由硬件7段譯碼集成電路,完成從數(shù)字到顯示碼的譯碼驅(qū)動(dòng)。本系統(tǒng)采用軟件譯碼,以減小體積,降低成本和功耗,軟件譯碼的另一優(yōu)勢(shì)還在于比硬件譯碼有更大的靈活性。所謂軟件譯碼,即由單片機(jī)軟件完成從數(shù)字到顯示碼的轉(zhuǎn)換。從LED數(shù)碼管結(jié)構(gòu)原理可知,為了顯示字符,要為L(zhǎng)ED顯示數(shù)碼管提供顯示段碼,組成一個(gè)“8”字形字符的7段,再加上1個(gè)小數(shù)點(diǎn)位,共計(jì)8段,因此提供給LED數(shù)碼管的顯示段碼為1個(gè)字節(jié)。各段碼位與顯示段的對(duì)應(yīng)關(guān)系如表1。 表1 各段碼位的對(duì)應(yīng)關(guān)系
注:(1)本表所列各字符的顯示段碼均為小數(shù)點(diǎn)不亮的情況。 (2)“空白”字符即沒(méi)有任何顯示。 根據(jù)AT89C2051單片機(jī)灌電流能力強(qiáng),拉電流能力弱的特點(diǎn),我們選用共陽(yáng)數(shù)碼管。將AT89C2051的P1.0~P1.7分別與共陽(yáng)數(shù)碼管的a~g及dp相連,高電平的位對(duì)應(yīng)的LED數(shù)碼管的段暗,低電平的位對(duì)應(yīng)的LED數(shù)碼管的段亮,這樣,當(dāng)P0口輸出不同的段碼,就可以控制數(shù)碼管顯示不同的字符。如:當(dāng)P0口輸出的段碼為1100 0000,數(shù)碼管顯示的字符為0。 數(shù)碼管顯示器有二種工作方式,即靜態(tài)顯示方式和動(dòng)態(tài)掃描顯示方式。為節(jié)省端口及降低功耗,本系統(tǒng)采用動(dòng)態(tài)掃描顯示方式。動(dòng)態(tài)掃描顯示方式需解決多位LED數(shù)碼管的“段控”和“位控”問(wèn)題,本電路的“段控”(即要顯示的段碼的控制)通過(guò)P0口實(shí)現(xiàn);而每一位的公共端,即LED數(shù)碼管的“位控”,則由P3口控制。這種連接方式由于多位字段線連在一起,因此,要想顯示不同的內(nèi)容,必然要采取輪流顯示的方式,即在某一瞬間,只讓其中的某一位的字位線處于選通狀態(tài),其它各位的字位線處于斷開(kāi)狀態(tài),同時(shí)字段線上輸出這一位相應(yīng)要顯示字符的字段碼。在這一瞬時(shí),只有這一位在顯示,其他幾位則暗。在本系統(tǒng)中,字位線的選通與否是通過(guò)PNP三極管的導(dǎo)通與截止來(lái)控制,即三極管處于“開(kāi)關(guān)”狀態(tài)。 系統(tǒng)的時(shí)分顯示部件由4只7段共陽(yáng)LED數(shù)碼管構(gòu)成,前兩只用于時(shí)的顯示,后兩只用于分的顯示。值得一提的是,在設(shè)計(jì)中需要實(shí)現(xiàn)時(shí)與分之間的兩個(gè)閃爍點(diǎn),為此,將第三只LED數(shù)碼管倒置擺放,這樣就形成了兩個(gè)很自然的閃爍點(diǎn)。與此同時(shí),為了能使兩點(diǎn)顯示能夠形象的表示時(shí)鐘“秒”的變化,設(shè)計(jì)時(shí),將兩個(gè)點(diǎn)由P1.7單獨(dú)控制,每隔一秒使P1.7發(fā)送一個(gè)正脈沖,從而實(shí)現(xiàn)了兩個(gè)點(diǎn)的閃爍顯示,閃爍周期為一秒。 2.2 系統(tǒng)程序的設(shè)計(jì) 本系統(tǒng)的軟件系統(tǒng)主要可分為主程序和定時(shí)器中斷程序兩大模塊。在程序過(guò)程中,加入了抗干擾措施。下面對(duì)部分模塊作介紹。 2.1.1 系統(tǒng)主程序設(shè)計(jì) 主程序的功能是完成系統(tǒng)的初始化,在顯示時(shí)間之前,對(duì)系統(tǒng)是否停電狀態(tài)進(jìn)行檢測(cè);若停電,將系統(tǒng)進(jìn)入低功耗狀態(tài),用電池電壓維持單片機(jī)計(jì)時(shí)工作,但此時(shí)不顯示時(shí)間,用節(jié)省用電;若不停電,則將時(shí)分發(fā)送顯示。程序流程如圖7所示。 2.2.2 中斷程序設(shè)計(jì) 中斷程序(如圖8所示)完成時(shí)間計(jì)數(shù),時(shí)間調(diào)整,誤差消除等功能。中斷采用AT89C2051內(nèi)部T0中斷實(shí)現(xiàn),定時(shí)時(shí)間為125ms,當(dāng)時(shí)間到達(dá)125ms×8,即1分鐘時(shí),分計(jì)數(shù)緩沖器MINBUFFER增加1,到達(dá)1小時(shí),則時(shí)計(jì)數(shù)緩沖器HOURBUFFER增加1,并將分、時(shí)的個(gè)位、十位放入顯示緩沖器。當(dāng)分計(jì)數(shù)緩沖器和時(shí)計(jì)數(shù)緩沖器分別到達(dá)60min、24h時(shí),則對(duì)它們清零,以便從新計(jì)數(shù)。在中斷設(shè)計(jì)中,還通過(guò)軟件實(shí)現(xiàn)了累計(jì)誤差消除功能,使整個(gè)系統(tǒng)時(shí)間的精確度得到保證。
3 結(jié)束語(yǔ) 上述電子鐘,無(wú)論在外觀上還是功能上都實(shí)現(xiàn)了較為完善的設(shè)計(jì)。特別值得一提的是本系統(tǒng)在精度上的設(shè)計(jì),突破傳統(tǒng)的方法,對(duì)可能產(chǎn)生的積累誤差采用“抵消法”,從而有效地降低了時(shí)間誤差。 由于計(jì)數(shù)時(shí)產(chǎn)生的積累誤差所導(dǎo)致的時(shí)間誤差,是所有的電子計(jì)時(shí)系統(tǒng)共同存在的問(wèn)題。但在目前市場(chǎng)上的電子時(shí)鐘產(chǎn)品,如計(jì)算機(jī)中的時(shí)鐘,手機(jī)中的時(shí)鐘等并沒(méi)有有效的采取消除誤差的措施。本系統(tǒng)設(shè)計(jì)的消除積累誤差來(lái)減少時(shí)間誤差的軟件方法,并不需要任何的硬件,因此在不增加成本的情況下,可以普遍用于所有的電子時(shí)鐘產(chǎn)品。
附錄主要程序清單 - ALARMHBUFF2 EQU 77H ;鬧鈴時(shí)間的時(shí)十位計(jì)時(shí)綬沖
- ALARMHBUFF1 EQU 76H ;鬧鈴時(shí)間的時(shí)個(gè)位計(jì)時(shí)綬沖
- ALARMMBUFF2 EQU 75H ;鬧鈴時(shí)間的分十位計(jì)時(shí)綬沖
- ALARMMBUFF1 EQU 74H ;鬧鈴時(shí)間的分個(gè)位計(jì)時(shí)綬沖
- HBUFF2 EQU 73H ;時(shí)十位計(jì)時(shí)綬沖
- HBUFF1 EQU 72H ;時(shí)個(gè)位計(jì)時(shí)綬沖
- MBUFF2 EQU 71H ;分十位計(jì)時(shí)綬沖
- MBUFF1 EQU 70H ;分個(gè)位計(jì)時(shí)綬沖
- DP EQU 6FH ;控制數(shù)碼管點(diǎn)的亮暗
- NUM EQU 78H ;前四秒還是后四秒計(jì)數(shù)
- SBUFF EQU 79H ;秒十進(jìn)制計(jì)時(shí)綬沖(低四位對(duì)應(yīng)個(gè)位,高四位對(duì)應(yīng)十位)
- MBUFF EQU 7AH ;分十進(jìn)制計(jì)時(shí)綬沖
- HBUFF EQU 7BH ;時(shí)十進(jìn)制計(jì)時(shí)綬沖
- ALARMMBUFF EQU 7CH ;鬧鈴時(shí)間的分十進(jìn)制計(jì)時(shí)綬沖
- ALARMHBUFF EQU 7DH ;鬧鈴時(shí)間的時(shí)十進(jìn)制計(jì)時(shí)綬沖
- NUMT1 EQU 67H;用于控制時(shí)間調(diào)整時(shí)按鍵p3.2一次按下時(shí),計(jì)數(shù)器T1中斷的次數(shù)
- NUMT2 EQU 68H;用于控制時(shí)間調(diào)整時(shí)按鍵p3.3一次按下時(shí),計(jì)數(shù)器T1中斷的次數(shù)
- KEYNUMT1 EQU 69H ;用于存儲(chǔ)NUMT1已經(jīng)計(jì)數(shù)到第幾個(gè)半秒
- KEYNUMT2 EQU 6AH ;用于存儲(chǔ)NUMT1已經(jīng)計(jì)數(shù)到第幾個(gè)半秒
- STOREKEYNUMT2 EQU 6BH ;用于存儲(chǔ)當(dāng)前KEYNUMT1的值,以和下次做比較,看是否有變化
- STOREKEYNUMT1 EQU 6CH ;用于存儲(chǔ)當(dāng)前KEYNUMT2的值,以和下次做比較,看是否有變化
- ORG 0000H
- AJMP START
- ORG 000BH
- MOV TH0 , #0BH ;設(shè)置計(jì)數(shù)初值,R4用來(lái)存儲(chǔ)低位的初值
- MOV TL0 , R4
- AJMP INTERT0
- ORG 001BH
- AJMP INTERT1
- ORG 0040H
- START: MOV NUMT1 , #00H
- MOV NUMT2 , #00H
- MOV KEYNUMT1 , #00H
- MOV KEYNUMT2 , #00H
- MOV STOREKEYNUMT2 , #00H
- MOV STOREKEYNUMT1 , #00H
- MOV NUM , #8
- MOV DPTR , #TAB
- MOV ALARMHBUFF , #18H ;置鬧鈴時(shí)間初始值為18:55
- MOV ALARMMBUFF , #55H
- MOV ALARMHBUFF2, #01H
- MOV ALARMHBUFF1, #08H
- MOV ALARMMBUFF2 , #05H
- MOV ALARMMBUFF1 , #05H
- MOV HBUFF2, #01H ;置鬧鐘時(shí)間為18:53
- MOV HBUFF1, #08H
- MOV MBUFF2 , #05H
- MOV MBUFF1 , #03H
- MOV HBUFF , #18H
- MOV MBUFF , #53H
- MOV SBUFF , #3CH ;置初始秒為60,計(jì)時(shí)時(shí)減
- MOV TCON , #05H ;下降沿觸發(fā)
- MOV TMOD , #11H ;初始化定時(shí)器,T0,T1 16位計(jì)時(shí)
- MOV TH0 , #0BH ;設(shè)置計(jì)數(shù)初值,125ms計(jì)時(shí)
- MOV TL0 , #0DBH
- MOV TH1 , #3CH ;T1置初值,進(jìn)行100ms計(jì)時(shí),用于調(diào)整時(shí)間
- MOV TL1 , #0B0H
- MOV IE , #82H ;開(kāi)T0中斷
- SETB PT0 ;T0中斷優(yōu)先級(jí)最高
- SETB TR0 ;允許T0計(jì)數(shù)
- SETB P3.2
- SETB P3.3
- START1:MOV A , HBUFF ; 顯示時(shí),7點(diǎn)以前及21點(diǎn)以后亮度調(diào)暗
- SUBB A , #7H
- JC START2
- MOV A , HBUFF
- SUBB A, #21H
- JNC START2
- ACALL DISPLAY
- ACALL ZDBS
- AJMP START3
- START2:ACALL NIGHTDISPLAY
- START3:MOV A ,ALARMHBUFF ;檢測(cè)是否是定鬧時(shí)間
- CJNE A , HBUFF , START4
- MOV A , ALARMMBUFF
- CJNE A , MBUFF ,START4
- MOV C, DP ;若是定鬧時(shí)間,則利用dp的值來(lái)決定蜂鳴
- MOV P3.2, C
- MOV A , SBUFF
- JNZ START1 ;若還沒(méi)到1分鐘,則繼續(xù)蜂鳴
- SETB P3.2
- START4:JNB P3.2,ADJUSTTIME1 ;循環(huán)等待中斷,并檢測(cè)是否鍵按下,若是,則進(jìn)入相應(yīng)程序
- JNB P3.3,ADJUSTTIME2
- AJMP START1
- AJMP START1
- ;****************
- ;*int0中斷子程序*
- ;****************
- ADJUSTTIME1:NOP
- MOV KEYNUMT1 ,#00H
- MOV TH1 , #3CH ;T1置初值,進(jìn)行100ms計(jì)時(shí),用于調(diào)整時(shí)間
- MOV TL1 , #0B0H
- SETB ET1 ;開(kāi)T1中斷
- SETB PT1 ;設(shè)T1中斷優(yōu)先級(jí)最高
- SETB TR1 ;允許T1計(jì)時(shí)
- MOV STOREKEYNUMT1 , KEYNUMT1 ;存儲(chǔ)當(dāng)前次KEYNUMT1的值
- TIME1_1:ACALL DISPLAY
- MOV A , KEYNUMT1
- CJNE A , STOREKEYNUMT1,TIME1_2 ;若當(dāng)前KEYNUMT1的值與上一次的值不等,則時(shí)間加1分,否則繼續(xù)循環(huán),等等至半分鐘
- AJMP TIME1_3
- TIME1_2:MOV STOREKEYNUMT1 , KEYNUMT1 ;加1后存儲(chǔ)當(dāng)前的KEYNUMT1的值
- ACALL ADDBUFF0 ;分加1
- TIME1_3:JNB P3.2,TIME1_1 ;若p3.2已關(guān),則退出增時(shí),否則繼續(xù)循環(huán)
- CLR ET1
- CLR PT1
- CLR TR1
- AJMP START1
- ;********************
- ;*****時(shí)間增1分******
- ;********************
- ADDBUFF0:MOV A , MBUFF ; 若按鍵小于1s,則分增1
- ADD A , #1
- DA A
- MOV MBUFF , A
- ANL A , #0FH
- MOV MBUFF1 , A
- MOV A , MBUFF
- SWAP A
- ANL A , #0FH
- MOV MBUFF2 , A
- MOV A , MBUFF
- CJNE A , #60H , ADDBUFF1
- MOV MBUFF , #00H
- MOV MBUFF2 , #00H
- MOV MBUFF1 , #00H
- MOV A , HBUFF ;時(shí)增1
- ADD A , #1
- DA A
- MOV HBUFF , A
- ANL A , #0FH
- MOV HBUFF1 , A
- MOV A , HBUFF
- SWAP A
- ANL A , #0FH
- MOV HBUFF2 , A
- MOV A , HBUFF
- CJNE A , #24H , ADDBUFF1 ;若沒(méi)到24小時(shí),則不必初值置0
- MOV HBUFF , #00H
- MOV HBUFF2 , #00H
- MOV HBUFF1 , #00H
- ADDBUFF1:RET
- ;*********************************
- ;*int1中斷子程序******************
- ;*********************************
-
- ADJUSTTIME2:NOP
- ACALL DL100MS
- MOV C , P3.3
- JC TIME2_6 ;如果(P3.3按鍵<100ms以上) 則不做處理
- MOV KEYNUMT2 , #00H ;否則進(jìn)入定鬧設(shè)置
- MOV STOREKEYNUMT2 , KEYNUMT2 ;記錄當(dāng)前NUMT2的數(shù)據(jù),以看下次有沒(méi)改變
- TIME2_1:NOP
- MOV TH1 , #3CH ;T1置初值,進(jìn)行100ms計(jì)時(shí),用于調(diào)整時(shí)間
- MOV TL1 , #0B0H
- SETB ET1 ;開(kāi)T1中斷
- SETB PT1 ;設(shè)T1中斷優(yōu)先級(jí)最高
- SETB TR1 ;允許T1計(jì)時(shí)
- TIME2_2:ACALL ALARMDISPLAY
- MOV A , KEYNUMT2
- CJNE A , STOREKEYNUMT2 ,TIME2_3
- AJMP TIME2_4
- TIME2_3:MOV STOREKEYNUMT2 , KEYNUMT2
- MOV A , ALARMMBUFF ; 若按鍵小于1s,則分增1
- ADD A , #1
- DA A
- MOV ALARMMBUFF , A
- ANL A , #0FH
- MOV ALARMMBUFF1 , A
- MOV A , ALARMMBUFF
- SWAP A
- ANL A , #0FH
- MOV ALARMMBUFF2 , A
- MOV A , ALARMMBUFF
- CJNE A , #60H , TIME2_4
- MOV ALARMMBUFF , #00H
- MOV ALARMMBUFF2 , #00H
- MOV ALARMMBUFF1 , #00H
- MOV A , ALARMHBUFF ;時(shí)增1
- ADD A , #1
- DA A
- MOV ALARMHBUFF , A
- ANL A , #0FH
- MOV ALARMHBUFF1 , A
- MOV A , ALARMHBUFF
- SWAP A
- ANL A , #0FH
- MOV ALARMHBUFF2 , A
- MOV A , ALARMHBUFF
- CJNE A , #24H , TIME2_4 ;若沒(méi)到24小時(shí),則初值不必置0
- MOV ALARMHBUFF , #00H
- MOV ALARMHBUFF2 , #00H
- MOV ALARMHBUFF1 , #00H
- TIME2_4:NOP
- JNB P3.3,TIME2_2 ;若按鍵已經(jīng)未按,則退出循環(huán)
- CLR ET1
- CLR TR1
- MOV KEYNUMT2 , #00H
- MOV NUMT2 , #00H
- MOV R2 , #10 ; 直到p3.3 20s鐘內(nèi)都是未按,此時(shí)復(fù)原數(shù)據(jù),即退出設(shè)置
- TIME2_7:MOV R1 , #200
- TIME2_5:ACALL ALARMDISPLAY
- ACALL DL1MS
- JNB P3.3 , TIME2_1
- DJNZ R1 , TIME2_5
- DJNZ R2 , TIME2_7
- TIME2_6:CLR ET1
- CLR PT1
- CLR TR1
- LJMP START1
- ;***********************************
- ;**T1中斷子程序*********************
- ;***********************************
- INTERT1:NOP
- MOV TH1 , #3CH ;T1置初值,進(jìn)行100ms計(jì)時(shí),用于調(diào)整時(shí)間
- MOV TL1 , #0B0H
- PUSH ACC
- PUSH PSW
- CLR ET0
- CLR ET1 ;關(guān)T1中斷
- MOV A , NUMT1
- INC A
- MOV NUMT1 , A ;中斷一次則相應(yīng)的增加NUMT1
- CJNE A , #5 , INTERT1NEXT ;每中斷五次,即半秒,都增加KEYNUMT1
- MOV A ,KEYNUMT1
- INC A
- MOV KEYNUMT1 , A
- MOV NUMT1 , #00H ;NUMT1已經(jīng)是5了,則處理過(guò)KEYNUMT1后,重置NUMT1
- INTERT1NEXT:NOP
- MOV A , NUMT2 ;中斷一次則相應(yīng)的增加NUMT1
- INC A
- MOV NUMT2 , A
- CJNE A, #5,ENDINTERT1 ;每中斷五次,即半秒,都增加KEYNUMT1
- MOV A , KEYNUMT2
- INC A
- MOV KEYNUMT2 , A
- MOV NUMT2 , #00H ;NUMT1已經(jīng)是5了,則處理過(guò)KEYNUMT1后,重置NUMT1
- ENDINTERT1:SETB ET1
- SETB ET0
- POP ACC
- POP PSW
- RETI
- ;**************
- ;** 整點(diǎn)報(bào)時(shí)**
- ;**************
- ZDBS: MOV A , MBUFF ;在整點(diǎn)時(shí),響半秒
- JNZ ZDBSEND
- MOV A , SBUFF
- CJNE A , #3CH , ZDBSEND
- CLR P3.2
- ACALL DL0FIVE
- SETB P3.2
- ZDBSEND:RET
- ;**************
- ;**定鬧顯示子程序**
- ;**************
- ALARMDISPLAY:MOV P1 ,#0FFH ;使時(shí)的十位亮
- MOV A , ALARMHBUFF2
- MOVC A , @A+DPTR
- SETB ACC.7
- MOV P1 , A
- CLR P3.0
- ACALL DL1MS
- SETB P3.0
- MOV A , ALARMHBUFF1 ;使時(shí)的個(gè)位亮
- MOVC A , @A+DPTR
- MOV C , DP
- MOV ACC.7 , C
- MOV P1 , A
- CLR P3.1
- ACALL DL1MS
- SETB P3.1
- MOV A ,ALARMMBUFF2 ;使分的十位亮
- MOVC A , @A+DPTR
- MOV C , DP
- MOV ACC.7 , C
- MOV P1 , A
- CLR P3.4
- ACALL DL1MS
- SETB P3.4
- MOV A , ALARMMBUFF1 ;使時(shí)的個(gè)位亮
- MOVC A , @A+DPTR
- SETB ACC.7
- MOV P1,A
- CLR P3.5
- ACALL DL1MS
- SETB P3.5
- RET
- ;********************************
- ;**晚上顯示子程序****************
- ;******************************** ;降低顯示的占空比,數(shù)碼管進(jìn)入節(jié)能
- NIGHTDISPLAY: NOP
- MOV P1 ,#0FFH
- MOV A , HBUFF2
- MOVC A , @A+DPTR
- SETB ACC.7
- MOV P1 , A
- CLR P3.0
- ACALL DL1MS ;亮1ms
- SETB P3.0
- ACALL DL1MS
- ACALL DL1MS ;暗2ms
- MOV A , HBUFF1
- MOVC A , @A+DPTR
- MOV C , DP
- MOV ACC.7 , C
- MOV P1 , A
- CLR P3.1
- ACALL DL1MS
- SETB P3.1
- ACALL DL1MS
- ACALL DL1MS
- MOV A ,MBUFF2
- MOVC A , @A+DPTR
- MOV C , DP
- MOV ACC.7 , C
- MOV P1 , A
- CLR P3.4
- ACALL DL1MS
- SETB P3.4
- ACALL DL1MS
- ACALL DL1MS
- MOV A , MBUFF1
- MOVC A , @A+DPTR
- SETB ACC.7
- MOV P1,A
- CLR P3.5
- ACALL DL1MS
- SETB P3.5
- ACALL DL1MS
- ACALL DL1MS
- RET
- ;**************
- ;**顯示子程序**
- ;**************
- DISPLAY:MOV P1 ,#0FFH
- MOV A , HBUFF2
- MOVC A , @A+DPTR
- SETB ACC.7
- MOV P1 , A
- CLR P3.0
- ACALL DL1MS
- SETB P3.0
- MOV A , HBUFF1
- MOVC A , @A+DPTR
- MOV C , DP
- MOV ACC.7 , C
- MOV P1 , A
- CLR P3.1
- ACALL DL1MS
- SETB P3.1
- MOV A ,MBUFF2
- MOVC A , @A+DPTR
- MOV C , DP
- MOV ACC.7 , C
- MOV P1 , A
- CLR P3.4
- ACALL DL1MS
- SETB P3.4
- MOV A , MBUFF1
- MOVC A , @A+DPTR
- SETB ACC.7
- MOV P1,A
- CLR P3.5
- ACALL DL1MS
- SETB P3.5
- RET
- TAB: DB 88H,0BBH,94H,91H,0A3H ; 0 1 2 3 4
- DB 0C1H,0C0H,9BH,80H,81H ; 5 6 7 8 9
- ;**************
- ;***延時(shí)程序***
- ;**************
- DL1MS: MOV R6 , #20 ;延時(shí)1ms
- DL11: MOV R7 , #25
- DL12: DJNZ R7 , DL12
- DJNZ R6 , DL11
- RET
- DL100MS:MOV R6 , #200 ;延時(shí)100ms
- DL100MS1:MOV R7 , #250
- DL100MS2:DJNZ R7 , DL100MS2
- DJNZ R6 , DL100MS1
- RET
- DL11S: MOV R5 , #10
- DL1S0: MOV R6 , #200 ;延時(shí)1s 10*250*200
- DL1S1: MOV R7 , #250
- DL1S2: DJNZ R7 , DL1S2
- DJNZ R6 , DL1S1
- DJNZ R5 , DL1S0
- RET
- DL0FIVE:MOV R5 , #5
- DL0: MOV R6 , #100 ;延時(shí)0.5s
- DL1: MOV R7 , #250
- DL2: DJNZ R7 , DL2
- DJNZ R6 , DL1
- DJNZ R5 , DL0
- RET
- ;**************
- ;*T0中斷子程序*
- ;**************
- INTERT0:PUSH ACC
- PUSH PSW
- CLR ET0 ;關(guān)T0中斷
- MOV A , SBUFF
- CJNE A ,#028H, SET1
- MOV R4 , #0DCH ;后四十秒的初值
- SET1: DJNZ NUM , ENDINTT0 ;若還沒(méi)到1s,則退出該次中斷
- MOV NUM , #8 ;設(shè)置NUM初值
- CPL DP
- DJNZ SBUFF , ENDINTT0 ; 若還沒(méi)到60s,則退出該次中斷
- MOV SBUFF , #03CH
- MOV R4 , #0DBH ;前20秒的初值
- ACALL ADDBUFF0
- ENDINTT0:MOV A , NUM
- CJNE A , #04H , ENDT0OUT ;0.5秒的時(shí)候dp取反
- CPL DP
- ENDT0OUT:POP PSW
- POP ACC
- SETB ET0
- RETI
- END
復(fù)制代碼
|