|
1.設(shè)計目的: (1)利用單片機(jī)定時器中斷和定時器計數(shù)方式實現(xiàn)秒、分定時。 (2)通過LED顯示程序的調(diào)整,熟悉8155與8051,8155與LED的接口技術(shù),熟悉LED動態(tài)顯示的控制過程。 (3)通過鍵盤程序的調(diào)整,熟悉8155與矩陣式鍵盤的接口技術(shù),熟悉鍵盤掃描原理。 (4)通過閱讀和調(diào)試簡易秒表整體程序,學(xué)會如何編制含LED動態(tài)顯示、鍵盤掃描和定時器中斷等多種功能的綜合程序,初步體會大型程序的編制和調(diào)試技巧。 2. 設(shè)計步驟與要求 (1)要求:以8位LED右邊2位顯示秒,左邊6位顯示0,實現(xiàn)秒表計時顯示。以4×4矩陣鍵盤的KE0、KE1、KE2等3鍵分別實現(xiàn)啟動、停止、清零等功能。 (2)方法:用單片機(jī)定時器T0中斷方式,實現(xiàn)1秒定時;利用單片機(jī)定時器1方式3計數(shù),實現(xiàn)60秒計數(shù)。用動態(tài)顯示方式實現(xiàn)秒表計時顯示,用鍵盤掃描方式取得KE0、KE1、KE2的鍵值,用鍵盤處理程序?qū)崿F(xiàn)秒表的啟動、停止、清零等功能。 (3)軟件設(shè)計:軟件整體設(shè)計思路是以鍵盤掃描和鍵盤處理作為主程序,LED動態(tài)顯示作為子程序。二者間的聯(lián)系是:主程序查詢有無按鍵,無按鍵時,調(diào)用二次LED動態(tài)顯示子程序(約延時8ms)后再回到按鍵查詢狀態(tài),不斷循環(huán);有按鍵時,LED動態(tài)顯示子程序作為按鍵防抖延時被連續(xù)調(diào)用二次(約延時16ms),待按鍵處理程序執(zhí)行完后,再回到按鍵查詢狀態(tài),同時兼顧了按鍵掃描取值的準(zhǔn)確性和LED動態(tài)顯示的穩(wěn)定性。秒定時采用定時器T0中斷方式進(jìn)行,60秒計數(shù)由定時器1采用方式3完成,中斷及計數(shù)的開啟與關(guān)閉受控于按鍵處理程序。由上述設(shè)計思路可設(shè)計出軟件流程圖如圖1.1所示。 (5)程序編制:編程時置KE0鍵為“啟動”,置KE1鍵為“停止”,置KE2鍵為“清零”,因按鍵較少,在處理按鍵值時未采用散轉(zhuǎn)指令“JMP”,而是采用條件轉(zhuǎn)移指令“CJNE”,每條指令后緊跟著一條無條件跳轉(zhuǎn)指令“AJMP”,轉(zhuǎn)至相應(yīng)的按鍵處理程序,如不是上述3個按鍵值則跳回按鍵查詢狀態(tài)。8位LED顯示的數(shù)據(jù)由顯示緩沖區(qū)30H~37H單元中的數(shù)據(jù)決定,順序是從左至右,動態(tài)顯示時,每位顯示持續(xù)時間為1ms,1ms延時由軟件實現(xiàn),8位顯示約耗時8ms。主程序、按鍵查詢子程序采用第0組工作寄存器,顯示子程序采用第1組工作寄存器。1秒定時采用定時器T0方式1中斷,每50ms中斷一次,用21H做50 ms計數(shù)單元,每20次為一個循環(huán),計滿20次,60秒計數(shù)單元(20H)計數(shù)1次。60秒計數(shù)采用定時器T1方式2計數(shù),計數(shù)脈沖采用軟件置位、復(fù)位P3.5口的方法實現(xiàn),用20H單元做60秒計數(shù)單元,如定時器T1溢出,則20H單元被清零,20H單元的數(shù)據(jù)采用十進(jìn)制計數(shù),該數(shù)據(jù)被拆成個位和十位兩個數(shù)據(jù)后分別送至顯示緩沖區(qū)的30H、31H單元。

按照上述思路可編制源程序如下: ORG 0000H AJMP MAIN ORG 000BH AJMP CONT ;主程序 ;――――――――――初始化程序――――――――――― MAIN: MOV TMOD,#61H ;置T0方式1定時,T1方式2計數(shù) MOV TH0,#3CH ;T0置初值 MOV TL0,#0B0H MOV TH1,#0C4H ;T1置初值 MOV TL1,#0C4H MOV DPTR,#4400H ;8155控制口地址送DPTR MOV A,#43H ;設(shè)置8155工作方式字 MOVX @DPTR,A ;設(shè)置PA、PB口輸出,PC口輸入 MOV 20H,#00H ;60秒計數(shù)單元置初值 MOV 21H,#14H ;50ms計數(shù)單元置初值 MOV SP,#3FH ;堆棧指針置初值 MOV R2,#08H ;LED待顯示位數(shù)送R2 MOV R0,#30H ;顯示緩沖區(qū)首址送R0 STAR: MOV @R0,#00H ;顯示緩沖區(qū)清零 INC R0 DJNZ R2,STAR CLR A ;累加器清零 ;―――――――――――鍵盤查詢程序―――――――――― KEY: ACALL KS ;調(diào)按鍵查詢子程序判是否有鍵按下 JNZ K1 ;有鍵按下轉(zhuǎn)移 ACALL DISP ;無鍵按下,調(diào)顯示子程序延時 AJMP KEY ;繼續(xù)查詢按鍵 ;―――――――――――鍵盤掃描程序―――――――――― K1: ACALL DISP ;鍵盤去抖延時 ACALL DISP ACALL KS ;再次判別是否有鍵按下 JNZ K2 ;有鍵按下轉(zhuǎn)移 AJMP KEY ;無按鍵,誤讀,繼續(xù)查詢按鍵 K2: MOV R3,#0FEH ;首列掃描字送R3 MOV R4,#00H ;首列號送R4 K3: MOV DPTR,#4401H ;PA口地址送DPTR,開始列掃描 MOV A,R3 MOVX @DPTR,A ;列掃描字送PA口 INC DPTR ;指向PC口 INC DPTR MOVX A,@DPTR ;讀取行掃描值 JB ACC.0,L1 ;第0行無鍵按下,轉(zhuǎn)查第1行 MOV A,#00H ;第0行有鍵按下,行首鍵號送A AJMP LK ;轉(zhuǎn)求鍵號 L1: JB ACC.1,L2 ;第1行無鍵按下,轉(zhuǎn)查第2行 MOV A,#08H ;第1行有鍵按下,行首鍵號送A AJMP LK ;轉(zhuǎn)求鍵號 L2: JB ACC.2,L3 ;第2行無鍵按下,轉(zhuǎn)查第3行 MOV A,#10H ;第2行有鍵按下,行首鍵號送A AJMP LK ;轉(zhuǎn)求鍵號 L3: JB ACC.3,NEXT ;第3行無鍵按下,轉(zhuǎn)查下一列
MOV A,#18H ;第3行有鍵按下,行首鍵號送A AJMP LK LK: ADD A,R4 ;形成鍵碼送A PUSH ACC ;鍵碼入棧保護(hù) K4: ACALL DISP ACALL KS ;等待鍵釋放 JNZ K4 ;未釋放,等待 POP ACC ;鍵釋放,彈棧送A AJMP PR ;轉(zhuǎn)鍵盤處理程序 NEXT: INC R4 ;修改列號 MOV A,R3 JNB ACC.3,KEY ;4列掃描完返回按鍵查詢狀態(tài) RL A ;未掃描完,改為下列掃描字 MOV R3,A ;掃描字暫存R3 AJMP K3 ;轉(zhuǎn)列掃描程序 ;―――――――――――鍵盤處理程序――――――――――――――― PR: CJNE A,#00H,PR01 ;不是KE0鍵碼,轉(zhuǎn)KE1鍵 AJMP KE0 ;轉(zhuǎn)KE0鍵處理程序 PR01: CJNE A,#01H,PR02 ;不是KE1鍵碼,轉(zhuǎn)KE2鍵 AJMP KE1 ;轉(zhuǎn)KE1鍵處理程序 PR02: CJNE A,#02H,PR03 ;不是KE2鍵碼,返回按鍵查詢 AJMP KE2 ;轉(zhuǎn)KE2鍵處理程序 PR03: AJMP KEY KE0: SETB TR0 ;啟動定時器T0 SETB TR1 ;啟動定時器T1 SETB ET0 ;允許定時器T0中斷 SETB EA ;開中斷 AJMP KEY ;返回鍵盤查詢狀態(tài) KE1: CLR EA ;關(guān)中斷 CLR ET0 ;禁止定時器T0中斷 CLR TR1 ;關(guān)定時器T1 CLR TR0 ;關(guān)定時器T0 AJMP KEY KE2: CLR EA ;關(guān)中斷 AJMP MAIN ;返回主程序進(jìn)行初始化 ;――――――――――按鍵查詢子程序―――――――――――――― KS: MOV DPTR,#4401H ;置8155PA口地址 MOV A,#00H MOVX @DPTR,A ;全掃描字#00H送PA口 INC DPTR ;指向PC口 INC DPTR MOVX A,@DPTR ;讀入PC口狀態(tài) CPL A ;變正邏輯,高電平表示有鍵按下 ANL A,#0FH ;屏蔽高4位 RET ;返回,A≠0表示有鍵按下 ;―――――――――LED動態(tài)顯示子程序――――――――――――― DISP: PUSH ACC ;A入棧保護(hù) SETB RS0 ;保護(hù)第0組工作寄存器,啟用第1組工作寄存器 MOV R2,#08H ;LED待顯示位數(shù)送R2 MOV R1,#00H ;設(shè)定顯示時間 MOV R3,#7FH ;選中最右端LED MOV R0,#30H ;顯示緩沖區(qū)首址送R0 MOV A,@R0 ;秒顯示個位送A
DISP1: MOV DPTR,#TAB ;指向字形表首址 MOVC A,@A+DPTR ;查表取得字形碼 MOV DPTR,#4402H ;指向8155PB口(段碼口) MOVX @DPTR,A ;字形碼送PB口 MOV A,R3 ;取位選字 MOV DPTR,#4401H ;指向8155PA口(位選口) MOVX @DPTR,A ;位碼送PA口 DJNZ R1,$ ;延時0.5ms DJNZ R1,$ ;延時0.5ms RR A ;位選字移位 MOV R3,A ;移位后的位選字送R3 INC R0 ;指向下一位緩沖區(qū)地址 MOV A,@R0 ;緩沖區(qū)數(shù)據(jù)送A
DJNZ R2,DISP1 ;未掃描完,繼續(xù)循環(huán) CLR RS0 ;恢復(fù)第0組工作寄存器 POP ACC ;A彈棧,恢復(fù)現(xiàn)場 RET TAB: DB 3FH,06H,5BH,4FH,66H ;共陰極LED字形表 DB 6DH,7DH,07H,7FH,6FH ;――――――――――定時器中斷服務(wù)程序――――――――――――― CONT: PUSH ACC ;保護(hù)現(xiàn)場 MOV TH0,#3CH ;定時器T1重置初值 , ; &, nbsp; &nbs, p; MOV TL0,#0B0H MOV A,20H ;秒計數(shù)器送A AJMP CONT1 REN: AJMP REN1 CONT1: DJNZ 21H,REN ;1秒定時未到,中斷返回 MOV 21H,#14H ;重置50ms計數(shù)初值 CLR P3.5 ;軟件產(chǎn)生定時器T1計數(shù)脈沖 NOP NOP SETB P3.5 INC A ;1秒計數(shù)值加1 DA A ;換算為10進(jìn)制計數(shù) JBC TF1,CONT2 ;60秒到,轉(zhuǎn)清零
CONT3: MOV 20H,A ;計數(shù)值送60秒計數(shù)單元20H ANL A,#0FH ;屏蔽高4位 MOV 30H,A ;秒表個位待顯示數(shù)據(jù)送顯示緩沖區(qū) MOV A,20H SWAP A ;60秒計數(shù)單元高、低4位數(shù)據(jù)互換 ANL A,#0FH ;屏蔽高4位 MOV 31H,A ;秒表十位待顯示數(shù)據(jù)送顯示緩沖區(qū) AJMP REN1 CONT2: MOV A,#00H AJMP CONT3 REN1: POP ACC ;恢復(fù)現(xiàn)場 RET ;中斷返回 END 3. 總結(jié)與分析 (1)實驗采用七段碼LED設(shè)計(數(shù)碼管),顯示直觀;采用定時器中斷,計時更準(zhǔn)確;功能齊全,可隨時啟動、停止、清零,后者智能化程度更高。 (2)設(shè)計、調(diào)試大型程序時,需先根據(jù)要求劃分模塊,優(yōu)化結(jié)構(gòu);再根據(jù)各模塊特點確定何為主程序,何為子程序,何為中斷服務(wù)程序,相互間如何調(diào)用;再根據(jù)各模塊性質(zhì)和功能將各模塊細(xì)化,設(shè)計出程序流程圖;最后才根據(jù)各模塊流程圖編制具體程序。調(diào)試時應(yīng)先調(diào)主程序,實現(xiàn)最基本最主要的功能,在此基礎(chǔ)上再將各模塊功能往主程序上堆砌,直至各模塊聯(lián)調(diào)、統(tǒng)調(diào),實現(xiàn)全部功能。本例子將整個程序劃分為鍵盤程序,動態(tài)顯示程序,秒計時程序三大模塊,根據(jù)各自的特點確定鍵盤程序為主程序,動態(tài)顯示程序為子程序,秒計時程序為定時器中斷服務(wù)程序。主程序又細(xì)分為初始化程序,鍵盤查詢程序,鍵盤掃描程序,鍵盤處理程序四大部分。三大模塊之間的關(guān)系是:鍵盤程序在無鍵按下時,不斷調(diào)用動態(tài)顯示子程序;在有鍵按下時,先調(diào)用動態(tài)顯示子程序消抖,再進(jìn)入鍵盤處理程序,控制中斷服務(wù)程序的運行;處理完畢后,再不斷調(diào)用動態(tài)顯示子程序。經(jīng)上述處理后,三大模塊運行協(xié)調(diào)一致,既保持了動態(tài)顯示的穩(wěn)定性,又保持了鍵盤的可靠性,還保持了秒計時的準(zhǔn)確性,較好地實現(xiàn)了全部功能。
(3)本例子只用到8位LED顯示中的兩位,只用到4×4鍵盤16個按鍵中的3個,因此,其功能還有較大的擴(kuò)展空間。只要將上述程序稍加改動即可實現(xiàn)秒、分、時、日顯示,并可作全方位修改的實時時鐘。如增加LED顯示位數(shù)或?qū)@示改為LCD顯示模塊,可實現(xiàn)年、月、周、日、時、分、秒顯示。 |