/*
程序效果:利用單片機的定時/計數(shù)器設計一個計時器,
按key0后啟動,要求精確顯示到百分之一秒。
發(fā)揮部分:
1:定時結(jié)束后有提示音報警,并可重新定時
2:定時時間可設置,最多30s
3:定時過程中可暫停
4:按下key1暫停計時,并記下此刻數(shù)值
5:按下key2顯示第一次按下key1的數(shù)值(按下第一次有效,其它均無效)
3:本程序版權(quán)所有:51hei.com.
*/
ORG 0000H
LJMP START //主程序必須避開地址000BH
ORG 000BH //定時器0的中段服務程序,起始地址為000BH
LJMP IT00
ORG 0030H
START: MOV TH0,#0EBH //裝入初始值,定時時間為10ms
MOV TL0,#64H
MOV TMOD,#01H //工作方式1
MOV 40H,#00
MOV 41H,#00
MOV 42H,#00
MOV 43H,#00
MOV 33H,#00 //顯示初值為0
MOV 32H,#00
MOV 31H,#00
MOV 30H,#00
MOV R1,#00
MOV R2,#00
SETB ET0 //打開定時0
SETB EA //開總中斷
HERE: JNB P3.4,KEY0 //掃描是否有按鍵按下
JNB P3.5,KEY1
JNB P3.6,KEY2
LCALL DISPLAY //此處是為了防止掉顯
LJMP HERE
KEY0: LCALL DELAY1 //延時10ms
JB P3.4,HERE //判斷key0是否真的按下去了
LKOP: LCALL DISPLAY //真的按下去了
JNB P3.4, LKOP //檢查是否松手,沒有則繼續(xù)循環(huán),別忘了要顯示
MOV A,R2
CJNE A,#01,LSP //判斷key2 是否按下去過(只能按一次)
MOV R2,#00 //清零
MOV 30H,34H //真的按下去了
MOV 31H,35H //顯示key2按下前的值
MOV 32H,36H
MOV 33H,37H
LSP: SETB TR0 //啟動定時器
LJMP HERE
KEY1: LCALL DELAY1 //顯示消抖
JB P3.5,HERE
CLR TR0 //關閉定時器
LKOP1: LCALL DISPLAY
JNB P3.5,LKOP1
INC R1
MOV A,R1
LEP: CJNE A,#01,HERE //判斷key2是否按下(只能按一次)
MOV 40H,30H //暫存key2按下去前的值
MOV 41H,31H
MOV 42H,32H
MOV 43H,33H
LJMP HERE
KEY2: LCALL DELAY1
JB P3.6,HERE
CLR TR0
LKOP2: LCALL DISPLAY
JNB P3.6,LKOP2
INC R2 //加1,為標志,用于判斷key2是否按下去了
MOV A,R2 //此處寫的是一個通用形式,只暫存一個數(shù)值
LEP2: CJNE A,#01,HERE //此語句大可不寫
MOV 34H,30H
MOV 35H,31H //保存碼表當時的數(shù)值,便于回復到原值
MOV 36H,32H
MOV 37H,33H
MOV 30H,40H //保存key1第一次按下的數(shù)值
MOV 31H,41H
MOV 32H,42H
MOV 33H,43H
LJMP HERE
//每10ms加1子程序
ADD1: INC 30H //百分位減1
MOV A,30H
CJNE A,#00AH,LOOP2 //判斷百分位減到0之后是否再減1
MOV 30H,#00 //是,裝入初值9
INC 31H //十分位減1
MOV A,31H
CJNE A,#0AH,LOOP2 //判斷百分位減到0之后是否再減1
MOV 31H,#00
INC 32H
MOV A,32H
CJNE A,#0AH,LOOP2
MOV 32H,#00
INC 33H
MOV A,33H
CJNE A,#0AH,LOOP2
MOV 33H,#00
SETB P2.0 //關閉蜂鳴器
LCALL DELAY //延時
LCALL DELAY
CLR P2.0 //從15s減到0s后,驅(qū)動蜂鳴器
MOV 33H,#00 //裝入初值15s
MOV 32H,#00
MOV 31H,#00
MOV 30H,#00
CLR TR0 //關閉定時器,
LP1: JB P3.4,LP //判斷KEY0是否按下
SETB TR0 //按下,則啟動定時器 ,這里我沒有消抖
SJMP LOOP2
LP: LCALL DISPLAY //沒有按下,調(diào)用顯示,防止掉顯
SJMP LP1
LOOP2: NOP //空指令
RET //返回
//顯示子程序
DISPLAY: MOV DPTR,#TAB //賦表首地址
MOV A,#0FBH
MOV P2,A //亮最左邊的數(shù)碼管
XCH A,R0 //暫存A的值
MOV A,33H
MOVC A,@A+DPTR //根據(jù)表值查找所需的值
MOV P0,A //顯示值
LCALL DELAY //延時
XCH A,R0 //恢復原值
RL A //循環(huán)左移,為下次做準備
MOV P2,A
XCH A,R0
MOV A,32H
MOVC A,@A+DPTR
MOV P0,A
LCALL DELAY
XCH A,R0
RL A
MOV P2,A
XCH A,R0
MOV A,31H
MOVC A,@A+DPTR
MOV P0,A
LCALL DELAY
XCH A,R0
RL A
MOV P2,A
XCH A,R0
MOV A,30H
MOVC A,@A+DPTR
MOV P0,A
LCALL DELAY
RET
TAB: DB 3FH,06H,5BH,4FH,66H ;數(shù)碼管顯示的數(shù)值
DB 6DH,7DH,07H,7FH,6FH
IT00: MOV TH0,#0EBH //裝入初值,時間為10ms
MOV TL0,#64H
LCALL ADD1 //減10ms
RETI //返回
DELAY: MOV R7,#04 //延時子程序,時間大約為:2us*4*250
DEL2: MOV R6,#250
DEL1: DJNZ R6,DEL1
DJNZ R7,DEL2
RET
DELAY1: MOV R5,#20
DEL3: MOV R4,#250
DEL4: DJNZ R4,DEL4
DJNZ R5,DEL3
RET
END //結(jié)束