ORG 0000H
START: LJMP MAIN
ORG 000BH
LJMP PDJW ;****************************************************************;
;系統監控程序區
ORG 0030H
MAIN: MOV PSW, #00H
MOV SP, #7FH ;確立堆棧區
MOV R0, #20H ;RAM區首地址
MOV R7, #96 ;RAM區單元個數
MOV TMOD, #01H SETB EA SETB ET0
ML: MOV @R0, #00H
INC R0
DJNZ R7, ML
TSF: MOV DPTR, #DISBH ;系統初始化后提示符“P.”字符
代碼表首地址 MOV R5, #08H
MOV R0, #78H
DISPTSF:CLR A
MOVC A, @A+DPTR
MOV @R0, A
INC R0
INC DPTR
DJNZ R5, DISPTSF
KEY0: LCALL DISP
LCALL KEY
JB 20H.0, K1
JB 20H.1, K2
JB 20H.2, K3
LJMP KEY0
KEY00: LCALL KEY
LCALL DISP
JB 20H.2, K3
LJMP KEY00
K1: JB 22H.1, KEY0 ;如果此時為暫停狀態,本次按鍵K1無效
CPL 22H.0
JB 22H.0, K01 ;高電平則計時
CLR TR0 ;低電平則停止
LCALL DISP
LJMP KEY00
K01: MOV 7AH, #12H ;從零開始計時
MOV 7DH, #12H
MOV 7FH, #10H
MOV 78H, #00H
MOV 79H, #00H
MOV 7BH, #00H
MOV 7CH, #00H
MOV 7EH, #00H
MOV 7FH, #00H
LCALL DISP
MOV TH0, #0D8H
MOV TL0, #0F0H
SETB TR0 ;啟動定時器
LJMP KEY0
K2: JB 22H.0, K21 ;判斷秒表是否啟動,如不是啟動
狀態則此次按鍵無效
LJMP KEY0
K21: CPL 22H.1
JB 22H.1, K22
SETB TR0 ;繼續計時
LJMP KEY0
K22: CLR TR0 ;暫停秒表
LCALL DISP
LJMP KEY0
K3: JB 22H.0, KEY0 ;只有當停止是,清零鍵才有效
MOV R0, #79H ;秒表清零
LCALL CLR00
MOV R0, #7CH
LCALL CLR00
MOV R0, #7FH
LCALL CLR00
LJMP KEY0
PDJW: PUSH PSW
PUSH ACC
MOV TMOD, #01H ;定時器以工作方式1工作
SETB RS1 ;設定組號為2組
CLR RS0
MOV TH0, #0D8H
MOV TL0, #0F0H
MOV R0, #79H
LCALL ADD01
CJNE R2, #99, RETT ;判斷1秒到沒
MOV R0, #7CH
LCALL ADD01
CJNE R2, #60, RETT ;判斷60毫秒到沒
LCALL CLR00
MOV R0, #7FH
LCALL ADD01
CJNE R2, #60H, RETT ;判斷60分到沒
LCALL CLR00
RETT: POP ACC
POP PSW
RETI
;*****************************************************************;
;常數表格區
;系統初始化后提示符“P.”字符代碼表;
DISBH: DB 10H,10H,10H,10H,10H,10H,10H,11H ;提示符“P.”字符序號
;顯示字符段選碼表(共陽極代碼)
TAB: DB 0C0H, 0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H ;0-8
DB 90H, 88H,83H,0C6H,0A1H,86H,8EH,0FFH,0CH,0BFH ;9,A,B,C,D,E,F,
滅,p.,-
;*******************************************************************;
;子程序區;
ADD01: MOV A, @R0
DEC R0
SWAP A
ORL A, @R0
ADD A, #01H
DA A
MOV R2, A
ANL A, #0FH
MOV @R0, A
MOV A, R2
ANL A, #0F0H
SWAP A
INC R0
MOV @R0, A
RET
CLR00: MOV @R0, #00H
DEC R0
MOV @R0, #00H
RET
;鍵掃描子程序
KEY: LCALL KEYCHULI ;調P1口數據處理子程序
JZ EXIT ;沒有鍵按下,轉返回
LCALL DISP ;調顯示子程序去抖動
LCALL DISP
LCALL KEYCHULI ;調P1口數據處理子程序
JZ EXIT ;沒有鍵按下,轉返回
MOV B, 20H ;保存取反后的鍵值
KEYSF: LCALL KEYCHULI ;調P1口數據處理子程序
JZ KEY1 ;鍵釋放,轉恢復鍵值
LCALL DISP
LCALL DISP ;調顯示子程序延時
LJMP KEYSF ;等待釋放
KEY1: MOV 20H, B ; 鍵值送20H保存
EXIT: RET ;子程序返回
;P1口數據處理子程序
KEYCHULI:PUSH PSW ;保護現場
CLR RS1 ;改變當前寄存器組為組
SETB RS0
MOV P1, #0FFH ;先向P1口寫1
MOV A, P1 ;讀P1口數據
CPL A ;P1口數據取反
MOV 20H, A ;保存取反后的鍵值
CLR RS1 ;恢復當前寄存器組為組0
CLR RS0
POP PSW ;恢復現場
RET ;子程序返回
;顯示子程序
;入口: 78H,79H,7AH,7BH,7CH,7DH,7EH,7FH,
DISP: PUSH DPH
PUSH DPL
PUSH ACC
PUSH PSW
CLR RS1 ;改變當前寄存器組為組1
SETB RS0
MOV R1, #78H ;顯示緩沖存儲單元首地址
MOV R2, #0FEH ;從右至左顯示
MOV R5, #08H ;循環次數,即驅動數碼管的位數
DISP1: MOV A, @R1
MOV DPTR, #TAB
MOVC A, @A+DPTR
MOV P0, A ;送段控
MOV P2, R2 ;送位控
LCALL DL ;延時1毫秒
MOV A, R2 ;位控碼送A
RL A ;獲得新的位控碼
MOV R2, A ;保存新的位控碼
INC R1 ;獲得新的顯示緩沖單元地址
DJNZ R5, DISP1 ;循環沒有結束則繼續
DISP2: POP PSW ;恢復當前寄存器組的組號
POP ACC
POP DPL
POP DPH
RET
;延時1ms子程序(晶振頻率12MHz)DL
DL: MOV R7, #02H
DL1: MOV R6, #0FFH
DL2: DJNZ R6, DL2
DJNZ R7, DL1
RET
END
|