📄 timer.asm
字号:
ORG 0000H
LJMP START
ORG 000BH
LJMP TIMER0
ORG 0100H
KEY_TAB:DB 0AH,09H,06H,05H ;矩阵键盘键值表,表中分别对应K1,K2,K3,K4的键值
; READ READ WRITE WRITE
; P2.1 P2.0 P1.1 P1.0
;K1 1 0 1 0 0AH
;K2 1 0 0 1 09H
;K3 0 1 1 0 06H
;K4 0 1 0 1 05H
ORG 0110H
START:
TIME_05 EQU 30H ;0.5S的定时记数器
TIME_10 EQU 31H ;1S 的定时记数器
TIME_15 EQU 32H ;1.5S的定时记数器
TIME_100 EQU 33H ;10S的定时记数器
LED_STATE EQU 34H ;LED显示状态变量
LED_TIME_SEL EQU 35H ;LED显示状态变化时间选择变量
;LED_TIME_SEL=1 LED的刷新时间为0.5S
;LED_TIME_SEL=2 LED的刷新时间为1S
;LED_TIME_SEL=3 LED的刷新时间为1.5S
LED_MODE_SEL EQU 36H ;LED显示模式选择变量
;LED_MODE_SEL=1 LED的显示方式为拉屏显示,即LED_DISPLAY1
;LED_MODE_SEL=2 LED的显示方式为正向流水灯,即LED_DISPLAY2,且FOLLOW_BACK=0
;LED_MODE_SEL=3 LED的显示方式为反向流水灯,即LED_DISPLAY2,且FOLLOW_BACK=1
KEY_VALUE EQU 37H ;键盘键值寄存器
KEY_PUSH_TIME EQU 38H ;键盘被按下的次数,即按键码时间=10ms*次数
KEY_STATE EQU 39H ;键盘状态寄存器
KEY_NAME EQU 40H ;键盘键名寄存器
KEY_NAME_OUT EQU 41H ;键盘键名输出寄存器
T05flag BIT 00H ;0.5S的定时时标位
T10flag BIT 01H ;1S 的定时时标位
T15flag BIT 02H ;1.5S的定时时标位
T100flag BIT 03H ;10S的定时时标位
FOLLOW_BACK BIT 04H ;流水灯正反显示标志位,0为正向显示/即P1.0-P1.7
; 1为反向显示/即P1.7-P1.0
T10MSflag BIT 05H ;10mS的定时时标位
PLUS BIT P2.2 ;脉冲输出口
MOV SP,#60H
MOV TIME_05,#10 ;初始化 50mS*10=0.5S
MOV TIME_10,#20 ;初始化 50mS*20=1.0S
MOV TIME_15,#30 ;初始化 50mS*30=1.5S
MOV TIME_100,#200 ;初始化 50mS*20=10.0S
MOV LED_STATE,#02 ;初始化 LED显示状态变量
MOV LED_TIME_SEL,#1 ;初始化 LED显示时间选择变量
MOV LED_MODE_SEL,#1 ;初始化 LED显示模式选择变量
MOV KEY_VALUE,#00H ;初始化 键盘键值寄存器
MOV KEY_PUSH_TIME,#00H ;初始化 按键次数寄存器
MOV KEY_STATE,#00H ;初始化 按键状态寄存器
MOV KEY_NAME,#00H ;初始化 键盘键名寄存器
MOV KEY_NAME_OUT,#00H ;初始化 键盘键名输出寄存器
CLR T05flag
CLR T10flag
CLR T15flag
CLR T100flag
CLR T10MSflag
CLR FOLLOW_BACK ;初始化 将流水灯显示设定为正向
MOV TH0,#0D8H ;设计数初值,定时时间为10mS
MOV TL0,#0F0H
MOV TMOD,#01H ;定时器0工作于方式2,为16位的定时器
SETB ET0
SETB TR0
SETB EA
MOV PSW,#00H
MOV A,#127
INC A
MAIN_LOOP: ;主程序入口
TEST_POINT1:
JNB T10MSflag,MAIN2 ;判断10MS是否时间到
CLR T10MSflag ;清10MS时标标志位
LCALL KEY_MATRIX ;调键盘扫描程序
MAIN2:
LJMP MAIN_LOOP ;主程式序循环扫描
;***************************************************************
;定时10S到执行输出程序
;***************************************************************
JNB T100flag,T100_DO_OUT
CLR T100flag ;复位10S的定时时标位
CPL PLUS ;输出脉冲取反,构成脉宽为10S的方波
T100_DO_OUT:
;***************************************************************
;***************************************************************
;LED显示输出程序
;***************************************************************
TIME_MODE_SEL:
TIME_SEL:
MOV A,LED_TIME_SEL ;时间选择
CJNE A,#1,TIME_SEL_T10 ;判断LED_TIME=0.5S
JNB T05flag,SEL_OUT ;判断TIME=0.5的时间标志位,是否时间到
CLR T05flag ;清时标
SJMP MODE_SEL ;跳转至模式选择
TIME_SEL_T10:
CJNE A,#2,TIME_SEL_T15 ;判断LED_TIME=1.0S
JNB T10flag,SEL_OUT ;判断TIME=1.0的时间标志位,是否时间到
CLR T10flag ;清时标
SJMP MODE_SEL ;跳转至模式选择
TIME_SEL_T15:
CJNE A,#3,SEL_OUT ;判断LED_TIME=1.5S
JNB T15flag,SEL_OUT ;判断TIME=1.5的时间标志位,是否时间到
CLR T15flag ;清时标
SJMP MODE_SEL ;跳转至模式选择
MODE_SEL:
MOV A,LED_MODE_SEL ;模式选择
CJNE A,#1,MODE_SEL_M2 ;判断是否为拉屏显示
LCALL LED_DISPLAY1 ;调用拉屏显示子程序
SJMP SEL_OUT
MODE_SEL_M2:
CJNE A,#2,MODE_SEL_M3 ;判断是否为正向流水灯显示
CLR FOLLOW_BACK ;将流水灯正反向显示标志设为正向
LCALL LED_DISPLAY2 ;调用流水灯显示子程序
SJMP SEL_OUT
MODE_SEL_M3:
CJNE A,#3,SEL_OUT ;判断是否为反向流水灯显示
SETB FOLLOW_BACK ;将流水灯正反向显示标志设为反向
LCALL LED_DISPLAY2 ;调用流水灯显示子程序
SJMP SEL_OUT
SEL_OUT:
RET
;***************************************************************
;***************************************************************
;流水灯状态寄存器改变子程序
;***************************************************************
LED_STATE_CHANGE:
CLR C
MOV A,LED_STATE
RLC A
CJNE A,#00H,LED_STATE_OUT
MOV A,#01H
LED_STATE_OUT:
MOV LED_STATE,A
RET
;***************************************************************
;***************************************************************
;流水灯执行子程序1---拉屏程序
;P1.0-P1.7以一定的时间间隔TIME_LED来逐个点亮
;***************************************************************
LED_DISPLAY1:
LCALL LED_STATE_CHANGE ;调用流水灯状态寄存器改变子程序
MOV A,LED_STATE
MOV R2,A
CLR C
LED_DISP1_LOOP:
RRC A
MOV R3,A
ADD A,R2
MOV R2,A
MOV A,R3
CJNE A,#00H,LED_DISP1_LOOP
MOV P1,R2
RET
;***************************************************************
;***************************************************************
;流水灯执行子程序2
;P1.0-P1.7以一定的时间间隔TIME_LED来流水点亮
;入口参数
;流水灯正反流动显示标志位:FOLLOW_BACK
;LED状态:LED_STATE
;***************************************************************
LED_DISPLAY2:
LCALL LED_STATE_CHANGE ;调用流水灯状态寄存器改变子程序
JB FOLLOW_BACK,LED_RUN_WATER_BACK
MOV P1,LED_STATE ;流水灯正向显示输出
LJMP LED_DISP2_OUT
LED_RUN_WATER_BACK: ;流水灯反向显示输出
MOV R2,#08H ;移位次数8次
MOV R3,LED_STATE
SHIFT_LOOP:
MOV A,R3
RLC A
MOV R3,A
MOV A,R4 ;结果中间暂存
RRC A
MOV R4,A
MOV P1,R4
DJNZ R2,SHIFT_LOOP
MOV P1,R4
LED_DISP2_OUT:
RET
;***************************************************************
;***************************************************************
;中断定时器0的中断子程序
;***************************************************************
TIMER0:
PUSH ACC
MOV TH0,#0D8H ;重装记数初数,定时时间为10mS
MOV TL0,#0F0H
SETB T10MSflag ;置位10MS的定时时标位
DEC TIME_05 ;0.5S记数器减1
DEC TIME_10 ;1.0S记数器减1
DEC TIME_15 ;1.5S记数器减1
DEC TIME_100 ;10S 记数器减1
MOV A,#00H ;定时0.5S记数器记数程序
CJNE A,TIME_05,T05_OUT
MOV TIME_05,#10 ;0.5S记数器重装记数值
SETB T05flag ;置位0.5S的定时时标位
T05_OUT:
;定时1.0S记数器记数程序
CJNE A,TIME_10,T10_OUT
MOV TIME_10,#20 ;1.0S记数器重装记数值
SETB T10flag ;置位1.0S的定时时标位
T10_OUT:
;定时1.5S记数器记数程序
CJNE A,TIME_15,T15_OUT
MOV TIME_15,#30 ;1.0S记数器重装记数值
SETB T15flag ;置位1.0S的定时时标位
T15_OUT:
;定时10S记数器记数程序
CJNE A,TIME_100,T100_OUT
MOV TIME_100,#200 ;10S记数器重装记数值
SETB T100flag ;置位10S的定时时标位
T100_OUT:
POP ACC
RETI
;***************************************************************
;***************************************************************
;独立键盘处理程序
;P1.0输入
;***************************************************************
KEY:
MOV P1,#0FFH
MOV A,P1
JNB ACC.0,KEY0
MOV KEY_PUSH_TIME,#00H ;没键按下时,则将次数寄存清零
MOV KEY_VALUE,#00H ;没有键按下,则送键值为00H
MOV KEY_STATE,#00H ;没有键按下,则按键状态寄存器清零
RET
KEY0:
LCALL KEY_WENDING;
RET
;***************************************************************
;***************************************************************
;矩阵键盘处理程序
; READ READ WRITE WRITE
; P2.1 P2.0 P1.1 P1.0
;K1 1 0 1 0 0AH
;K2 1 0 0 1 09H
;K3 0 1 1 0 06H
;K4 0 1 0 1 05H
;***************************************************************
KEY_MATRIX:
MOV P2,#0FFH ;读准备
MOV A,P1
ANL A,#0FCH ;屏蔽不用位#1111 1100
MOV P1,A ;写P1
MOV A,P2 ;读键盘
ORL A,#0FCH ;屏蔽不用位#1111 1100
CJNE A,#0FFH,GET_KEY_VALUE ;判断是否有键按,没有退出,有进入其应的程序
MOV KEY_PUSH_TIME,#00H ;没键按下时,则将次数寄存清零
MOV KEY_VALUE,#00H ;没有键按下,则送键值为00H
MOV KEY_STATE,#00H ;没有键按下,则按键状态寄存器清零
RET
GET_KEY_VALUE:
MOV A,P1 ;
ANL A,#0FEH ;屏蔽不用位#1111 1110
MOV P1,A ;写P1.0置0,判K1,K3
NOP
MOV A,P2
ORL A,#0FCH
CJNE A,#0FFH,GET_KEY_NAME ;判到有键按下,则跳转至取键名
MOV A,P1 ;
ANL A,#0FDH ;屏蔽不用位#1111 1101
ORL A,#01H ;将P1。0置1
MOV P1,A ;写P1.1置0,判K2,K4
NOP
MOV A,P2
ORL A,#0FCH
CJNE A,#0FFH,GET_KEY_NAME ;判到有键按下,则跳转至取键名
MOV KEY_PUSH_TIME,#00H ;没键按下时,则将次数寄存清零
MOV KEY_VALUE,#00H ;没有键按下,则送键值为00H
MOV KEY_STATE,#00H ;没有键按下,则按键状态寄存器清零
RET
GET_KEY_NAME:
RL A
RL A
ANL A,#0CH
MOV R2,A
MOV A,P1
ANL A,#03H
ORL A,R2
MOV KEY_VALUE,A
MOV R0,#01H
MOV DPTR,#KEY_TAB ;取键值表的首地址
KEY_GET_LOOP:
MOV A,#00H
MOVC A,@A+DPTR
CJNE A,KEY_VALUE,KEY_NEXT
MOV KEY_NAME,R0 ;送键名
LCALL KEY_WENDING ;
RET
KEY_NEXT:
INC DPTR
INC R0
CJNE R0,#05H,KEY_GET_LOOP
MOV KEY_NAME,#00H
RET
;***************************************************************
;***************************************************************
;按键稳定程序:去抖动,并且确认有键按下
;***************************************************************
KEY_WENDING:
MOV A,KEY_STATE
KSR0:
CJNE A,#00H,KSR1
MOV KEY_STATE,#01H ;将按键状态寄存器转为1
RET
KSR1:
CJNE A,#01H,KSR2
MOV KEY_STATE,#02H ;将按键状态寄存器转为2
RET
KSR2:
CJNE A,#02H,KSR3
INC KEY_PUSH_TIME
MOV A,KEY_PUSH_TIME
CJNE A,#35,KSR_OUT ;键按下未到350MS,则跳出
MOV KEY_NAME_OUT,KEY_NAME ;检测时间到,将键值输出
MOV KEY_PUSH_TIME,#00H ;将按键次数记数器清
MOV KEY_STATE,#00H ;将按键状态寄存器设为0
KSR3:
KSR_OUT:
RET
;***************************************************************
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -