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