按key0后启动,要求精确显示到百分之一秒。
发挥部分:
1:定时结束后有提示音报警,并可重新定时
2:定时时间可设置,最多30s
3:定时过程中可暂停
4:按下key1暂停计时,并记下此刻数值
5:按下key2显示第一次按下key1的数值(按下第一次有效,其它均无效)
3:本程序版权所有: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 //检查是否松手,没有则继续循环,别忘了要显示
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 //此处写的是一个通用形式,只暂存一个数值
LEP2: CJNE A,#01,HERE //此语句大可不写
MOV 34H,30H
MOV 35H,31H //保存码表当时的数值,便于回复到原值
MOV 36H,32H
MOV 37H,33H
MOV 30H,40H //保存key1第一次按下的数值
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后,驱动蜂鸣器
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 //没有按下,调用显示,防止掉显
SJMP LP1
LOOP2: NOP //空指令
RET //返回
//显示子程序
DISPLAY: MOV DPTR,#TAB //赋表首地址
MOV A,#0FBH
MOV P2,A //亮最左边的数码管
XCH A,R0 //暂存A的值
MOV A,33H
MOVC A,@A+DPTR //根据表值查找所需的值
MOV P0,A //显示值
LCALL DELAY //延时
XCH A,R0 //恢复原值
RL A //循环左移,为下次做准备
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 ;数码管显示的数值
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 //结束