实验内容:
实现秒表功能,包括复位操作(时间清零)、启动/暂停/继续计时。由于开发板上只 有四个数码管,因此需求分析中可以规定计时的有效范围为 00.00 – 99.99 秒,计时精度为 0.01 秒。最简性原则要求按键只用两个:一个用于复位清零;另一个用于启动/暂停/继续 计时。特别注意如下业务逻辑:在计时的过程中不允许进行复位清零操作,只有当暂停计时 后才允许复位清零;另外,在启动计时之前也不允许复位清零;最后,一旦计时溢出时,秒 表停止工作,计时显示保持 99.99(秒)不变,禁用启动/暂停/继续按键,只有复位清零后 才能重新计时。
;*************************************************************************************
;
; Author: Gu Junwei(顾俊玮)
; Date: 2023/04/05
; Function: Control a display to show a timer and respond to two external interrupts
;
;*************************************************************************************
ORG 0000H
LJMP START
ORG 0003H
AJMP ISR0 ; 设置外部中断0的中断服务程序入口地址
ORG 0013H
AJMP ISR1 ; 设置外部中断1的中断服务程序入口地址
ORG 001BH
AJMP TIMER1_ISR ; 设置定时器1的中断服务程序入口地址
ORG 0030H
ISR0:
JB P3.2, DEBOUNCE_DONE_INT0 ; 判断按键是否被抬起
CJNE R7, #0, PAUSE ; 如果R7不为0则进入暂停状态
SETB TR1 ; 开启定时器
MOV R7, #1 ; 设置标志位为1
RETI ; 退出中断
DEBOUNCE_DONE_INT0:
CLR EX0 ; 关闭外部中断0
ACALL DELAY ; 延时消抖
SETB EX0 ; 重新使能外部中断0
RETI ; 返回中断
PAUSE:
MOV R7, #0 ; 设置标志位为0
CLR TR1 ; 关闭定时器
RETI ; 退出中断
ISR1:
JB P3.3, DEBOUNCE_DONE_INT1 ; 判断按键是否被抬起
CJNE R7, #0, EXIT ; 如果R7不为0则退出
CLR TR1 ; 关闭定时器
CALL INIT ; 初始化计数器
RETI ; 退出中断
DEBOUNCE_DONE_INT1:
CLR EX1 ; 关闭外部中断1
ACALL DELAY ; 延时消抖
SETB EX1 ; 重新使能外部中断1
RETI ; 返回中断
TIMER1_ISR:
PUSH ACC ; 保护寄存器
PUSH PSW
INC R4 ; 计数器加1
CJNE R4, #1, SKIP_SHI
MOV R4, #0
CALL UPDATE
SKIP_SHI:
CLR TF1
MOV TH1, #0D9H ; 设置高8位
MOV TL1, #00EH ; 设置低8位
POP PSW ; 恢复寄存器
POP ACC
RETI
UPDATE:
INC R0 ; R0加1
CJNE R0, #10, EXIT ; 如果R0不等于10则退出
MOV R0, #0 ; R0赋值为0
INC R1 ; R1加1
CJNE R1, #10, EXIT ; 如果R1不等于10则退出
MOV R1, #0 ; R1赋值为0
INC R2 ; R2加1
CJNE R2, #10, EXIT ; 如果R2不等于10则退出
MOV R2, #0 ; R2赋值为0
INC R3 ; R3加1
CJNE R3, #9, EXIT ; 如果R3不等于10则退出
MOV R0, #9
MOV R1, #9
MOV R2, #9
MOV R7, #0
CLR TR1
CLR EX0
RET
EXIT:
RETI ;
DISPLAY: ; 显示
MOV P2,#11110111B
MOV A,R0
MOVC A,@A+DPTR
MOV P0,A
ACALL DELAY
MOV P2,#11111011B
MOV A,R1
MOVC A,@A+DPTR
MOV P0,A
ACALL DELAY
MOV P2,#11111101B
MOV A,R2
MOVC A,@A+DPTR
SUBB A, #80H
MOV P0,A
ACALL DELAY
MOV P2,#11111110B
MOV A,R3
MOVC A,@A+DPTR
MOV P0,A
ACALL DELAY
LJMP DISPLAY ; 返回显示程序,重新进行显示
START:
MOV DPTR, #TAB
CALL INIT
MOV TMOD, #10H ; 设置定时器模式
SETB EA ; CPU开中断
SETB EX1 ; 开外部中断1
SETB IT0 ; 外部中断0位边沿触发方式
SETB IT1 ; 外部中断1位边沿触发方式
SETB ET1 ; 定时器0允许位
LJMP DISPLAY
INIT:
MOV R0, #0 ; 0.01
MOV R1, #0 ; 0.1
MOV R2, #0 ; 1
MOV R3, #0 ; 10
MOV R4, #0 ; 计数器置0
MOV R7, #0 ; 判断是否计数,0未计数,1计数中
SETB EX0 ; 开外部中断0
MOV TH1, #0D9H ; 设置高8位
MOV TL1, #00EH ; 设置低8位
RET
DELAY :
MOV R6, #40 ; 延时程序
DEL1:
MOV R5, #50
DEL2:
DJNZ R5, DEL2
DJNZ R6, DEL1
RET
TAB: DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H
END