📄 timer.rar.txt
字号:
CODE_SEG SEGMENT CODE
DATA_SEG SEGMENT DATA
STACK_SEG SEGMENT IDATA
RSEG DATA_SEG
KEY_S: DS 1
KEY_V: DS 1
KEY_S1: DS 1
KEY_V1: DS 1
DIS_DIGIT: DS 1
DIS_INDEX: DS 1
SEC_BCD: DS 8 ; 秒计数值, BCD码
KEY_TIMES: DS 1 ; K1 按下次数
DIS_BUF: DS 8 ; 显示缓冲区
RSEG STACK_SEG
STACK: DS 20
K1 BIT P3.2
K2 BIT P3.3
;===============================================================================
CSEG AT 0000H
LJMP MAIN
CSEG AT 0000BH
LJMP TIMER0
CSEG AT 0001BH
LJMP TIMER1
CSEG AT 0013H
LJMP MAIN_LP2
;===============================================================================
RSEG CODE_SEG
MAIN:
USING 0
MOV SP,#(STACK-1)
MOV P0,#0FFH ; 初始化端口
MOV P2,#0FFH
MOV TMOD,#011H ;
MOV TH1,#0DCH
CLR A
MOV TL1,A
MOV TH0,#0FEH
MOV TL0,#0BH
LCALL CLR_TIME ; 清零计时值
MOV DIS_DIGIT,#07FH ; 上电时选通P27数码管
CLR A
MOV DIS_INDEX,A
MOV KEY_TIMES,A
MOV KEY_V,#01H
MOV KEY_V1,#01H
MOV IE,#08EH ; 使能timer0, timer1中断
SETB TR0
CLR TR1
MAIN_LP:
LCALL SCAN_KEY ; 键扫描
JZ MAIN_LP ; 无键返回
MOV R7,#10 ; 延时10ms
LCALL DELAYMS ; 延时去抖动
LCALL SCAN_KEY ; 再次扫描
JZ MAIN_LP ; 无键返回
MOV KEY_V,KEY_S ; 保存键值
LCALL PROC_KEY ; 键处理
SJMP MAIN_LP
MAIN_LP2:
LCALL SCAN_KEY1 ; 键扫描
JZ MAIN_LP2 ; 无键返回
MOV R7,#10 ; 延时10ms
LCALL DELAYMS ; 延时去抖动
LCALL SCAN_KEY1 ; 再次扫描
JZ MAIN_LP2 ; 无键返回
MOV KEY_V1,KEY_S1 ; 保存键值
LCALL PROC_KEY3 ; 键处理
RETI
;===============================================================================
CLR_TIME:
CLR A
MOV SEC_BCD,A ; 清零所有计时值
MOV SEC_BCD+01H,A
MOV SEC_BCD+02H,A
MOV SEC_BCD+03H,A
MOV SEC_BCD+04H,A
MOV SEC_BCD+05H,A
MOV SEC_BCD+06H,A
MOV SEC_BCD+07H,A
LJMP UPDATE_DISBUF ; 更新显示缓冲区
;===============================================================================
SCAN_KEY:
CLR A
MOV KEY_S,A
MOV C,K1 ; 读按键状态
RLC A
ORL KEY_S,A
MOV A,KEY_S
XRL A,KEY_V ;
RET
SCAN_KEY1:
CLR A
MOV KEY_S1,A
MOV C,K2 ; 读按键状态
RLC A
ORL KEY_S1,A
MOV A,KEY_S1
XRL A,KEY_V1 ;
RET
;===============================================================================
PROC_KEY:
MOV A,KEY_V
JB ACC.0,END_PROC_KEY
INC KEY_TIMES
MOV A,KEY_TIMES
CJNE A,#01H,PROC_KEY1
SETB TR1 ; KEY_TIMES = 1,第一次按下K1, 启动开始计时
RET
PROC_KEY1:
CLR A
; KEY_TIMES = 2, 第二次按下K1, 停止计时
MOV KEY_TIMES ,A
CLR TR1
RET
END_PROC_KEY:
RET
PROC_KEY3:
LCALL CLR_TIME ; 第三次按下K1, 清零计时值
CLR A
MOV KEY_TIMES,A ; 清零KEY_TIMES
RETI
;===============================================================================
TIMER0:
; 定时器0中断服程序, 用于数码管的动态扫描
; DIS_INDEX --- 显示索引, 用于标识当前显示的数码管和缓冲区的偏移量
; DIS_DIGIT --- 位选通值, 传送到P2口用于选通当前数码管的数值, 如等于0xfe时,
; 选通P2.0口数码管
; DIS_BUF --- 显于缓冲区基地址
PUSH ACC
PUSH PSW
PUSH AR0
MOV TH0,#0FCH
MOV TL0,#017H
MOV P2,#0FFH ; 先关闭所有数码管
MOV A,#DIS_BUF ; 获得显示缓冲区基地址
ADD A,DIS_INDEX ; 获得偏移量
MOV R0,A ; R0 = 基地址 + 偏移量
MOV A,@R0 ; 获得显示代码
MOV P0,A ; 显示代码传送到P0口
MOV P2,DIS_DIGIT ;
MOV A,DIS_DIGIT ; 位选通值右移(P20<-P27), 下次中断时选通下一位数码管
RR A
MOV DIS_DIGIT,A
INC DIS_INDEX ; DIS_INDEX加1, 下次中断时显示下一位
ANL DIS_INDEX,#0x07 ; 当DIS_INDEX等于8(0000 1000)时, 清0
POP AR0
POP PSW
POP ACC
RETI
;===============================================================================
TIMER1:
PUSH ACC
PUSH B
PUSH DPH
PUSH DPL
PUSH PSW
PUSH AR7
ORL TH1,#0DCH ; 恢复定时器初值
CLR A
MOV R7,A
MOV A,#LOW (SEC_BCD)
MOV R0,A ; 计时值寄存器地址到R0
TIMER_INC: ;
INC @R0 ; 计时值加1
MOV A,@R0
CLR C
SUBB A,#10 ;
JC END_INC ; 如果低位不满10, 则结束
MOV @R0,#00H ; 低位满10, 清零低位
INC R0 ; 指向高位
INC R7 ;
CJNE R7,#08H,TIMER_INC ; 如果达到最高位, 则结束
END_INC:
LCALL UPDATE_DISBUF
POP AR7
POP PSW
POP DPL
POP DPH
POP B
POP ACC
RETI
;===============================================================================
UPDATE_DISBUF:
; 根据计时寄存器的值更新显示缓冲区
MOV DPTR,#DIS_CODE ; 保存表格地址
MOV A,sec_bcd
MOV DPTR,#dis_code
MOVC A,@A+DPTR ; 获得显示代码
MOV dis_buf,A ; 更新显示缓冲区
MOV A,sec_bcd+01H
MOVC A,@A+DPTR
MOV dis_buf+01H,A
MOV A,sec_bcd+02H
MOVC A,@A+DPTR
ANL A,#07FH ; 显示小数点
MOV dis_buf+02H,A
MOV A,sec_bcd+03H
MOVC A,@A+DPTR
MOV dis_buf+03H,A
MOV A,sec_bcd+04H
MOVC A,@A+DPTR
MOV dis_buf+04H,A
MOV A,sec_bcd+05H
MOVC A,@A+DPTR
MOV dis_buf+05H,A
MOV A,sec_bcd+06H
MOVC A,@A+DPTR
MOV dis_buf+06H,A
MOV A,sec_bcd+07H
MOVC A,@A+DPTR
MOV dis_buf+07H,A
RET
; END OF UPDATE_DISBUF
;===============================================================================
DELAYMS:
; 延时子程序
; 传入参数:R7 --- 延时值(MS)
; 返回值:无
MOV A,R7
JZ END_DLYMS
DLY_LP1:
MOV R6,#185
DLY_LP2:
NOP
NOP
NOP
DJNZ R6,DLY_LP2
DJNZ R7,DLY_LP1
END_DLYMS:
RET
;===============================================================================
DIS_CODE:
db 0c0h,0f9h,0a4h,0b0h,99h,92h,82h,0f8h,80h,90h
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -