本帖最后由 2449748936 于 2021-12-13 16:52 编辑
ORG 00H ;主程序起始地址
JMP START ;跳至主程序
ORG 0BH ;T0中断起始地址
JMP TIM0 ;跳至T0中断子程序 设置初值
START: MOV TMOD,#00000001B ;设T0在MODE1
MOV IE,#10000010B ;开通中断
SETB TR0 ;启动定时器T0 启动定时器
L1: ACALL KEY ;调用KEY,判断是否有键按下 开始扫描
CLR EA ; 中断屏蔽
JB F0,L1 ;没按则F0=1,有按则F0=0
MOV A,22H ;将取码指针暂存地址载入A
RL A ;向左移1位乘
MOV DPTR,#TABLE ;存表
MOVC A,@A+DPTR ;至TABLE取码,取T的值
MOV TH0,A ;取到的高位字节存入TH0
MOV 21H,A ;取到的高位字节存入(21H)
MOV A,22H ;再载入取码指针值
RL A ;向左移1位
INC A ;加1
MOVC A,@A+DPTR ;至表取低位字节计数值
MOV TL0,A ;取到的低位字节存入TL0 取码装入定
MOV 20H,A ;取低位字节存入(20H) 时器初值
L2: ACALL KEY ;调用KEY判断有按否?
SETB EA ;开通中断
JB F0,L1 ;有按否?
JMP L2 ;有则跳至L2 再扫描确认
KEY: SETB F0 ;设F0=1
MOV R3,#0F7H ;扫描初值(P3.3=0)
MOV R1,#00H ;取码指针初值
L3: MOV A,R3 ;载入扫描指针
MOV P3,A ;输出至P3,开始扫描
MOV A,P3 ;读入P3
SETB C ;令C=1
MOV R5,#04H ;检测P3.7~P3.4
L4: RLC A ;左移一位
JNC KEYIN ;检测行C=0,表示被按
INC R1 ;没按则取码指针加1
DJNZ R5,L4 ;4列检测完毕了?
MOV A,R3 ;载入扫描指针
SETB C ;使C=1
RRC A ; 扫描下一行
MOV R3,A ;存回R3扫描指针寄存器
JC L3 ;C=0表示行扫描完毕
RET ;子程序返回 扫描子程序
KEYIN: MOV 22H,R1 ;取码指针存入22H地址
CLR F0 ;令F0=0 存指针并标出
RET ;子程序返回 有按键(F0=0)
TIM0: PUSH ACC ;将A的值暂存堆栈
PUSH PSW ;将PSW的值暂存于堆栈
MOV TL0,20H ;重设计数值
MOV TH0,21H ;
CPL P1.5 ;将P2.4位反相
POP PSW ;至堆栈取回PSW的值
POP ACC ;至堆栈取回A的值
RETI ;返回主程序 中断子程序
TABLE: DW 64021,64103,64260,64400 ;
DW 64524,64580,64684,64777 ;
DW 64820,64898,64968,65030 ;
DW 65058,65110,65157,65178 ; 编码表
END ; 程序结束
程序如上图所示,单片机下载后有四个按键按下后不会自动终止,需要再次点击第一个按键才能终止是为什么?
|