文章目录
- 前言
- 一、按键子程序
- 二、完整项目代码
- 总结(相关资源)
前言
分享一个自己写的汇编矩阵键盘,如有错误和不足欢迎批评指正。
关于数码管显示,使用的是查表的方式。
一、按键子程序
线反转法csdn上的讲解已相当丰富,这里不多做解释。
按键检测函数,影响A,R0,R1寄存器,A为出口,返回值为0至16的数字(0为无按键按下)。
ARRAY_TEST:
;第一次按键检测,无按下直接结束
MOV ARRAY,#0FH
MOV A,ARRAY
CJNE A,#0FH,ARRAY_TEST1
CLR A
RET
ARRAY_TEST1:
;第二次按键检测,等待5ms进行再次检测,防止误入
ACALL DELAY5MS
MOV ARRAY,#0FH
MOV A,ARRAY
CPL A
ANL A,#0FH
JNZ SCAN ;确认有按键按下,开始扫描
RET
SCAN:
;录入按下按键的行位置
MOV R1,A
MOV R0,#5H
;由于51单片机IO口为强下拉,当有按键按下时,特定的引脚会无法变为高位
MOV ARRAY,#0F0H
MOV A,ARRAY
SCAN1:
RLC A
DEC R0
JC SCAN1
SCAN2:
MOV A,R1 ;取回行位置
;计算行地址
CJNE A,#1000B,SCAN3
RR A
AJMP SCAN4
SCAN3:
CJNE A,#100B,SCAN4
DEC A
SCAN4:
;计算按键位置
DEC A
RL A
RL A
ADD A,R0
RET
两次按键检测采用了不同的方法,第一次的检测更简单更快(快2个机器周期),第二次检测完会直接把行位置计算出来放在a寄存器。
二、完整项目代码
;定义矩阵键盘所在端口,低位为行按键,高位为列按键
ARRAY DATA P3
ORG 00H
AJMP START
ORG 100H
START:
;初始化
MOV DPTR,#TAB ;初始化要显示的内容
MOV P0,#0FFH ;初始化显示端口
MOV SP,#30H ;初始化堆栈地址
MAIN:
ACALL ARRAY_TEST ;调用矩阵键盘检测
JZ MAIN ;当无键盘按下跳转到main
DEC A ;若需要第3个数据只需将指针位移2位,故自减一
;输出
MOVC A,@A+DPTR
MOV P0,A
CLR A
AJMP MAIN
;按键检测函数,影响A,R0,R1寄存器,
;A为出口,返回值为0至16的数字(0为无按键按下)
ARRAY_TEST:
;第一次按键检测,无按下直接结束
MOV ARRAY,#0FH
MOV A,ARRAY
CJNE A,#0FH,ARRAY_TEST1
CLR A
RET
ARRAY_TEST1:
;第二次按键检测,等待5ms进行再次检测,防止误入
ACALL DELAY5MS
MOV ARRAY,#0FH
MOV A,ARRAY
CPL A
ANL A,#0FH
JNZ SCAN ;确认有按键按下,开始扫描
RET
SCAN:
;录入按下按键的行位置
MOV R1,A
MOV R0,#5H
;由于51单片机IO口为强下拉,当有按键按下时,特定的引脚会无法变为高位
MOV ARRAY,#0F0H
MOV A,ARRAY
SCAN1:
RLC A
DEC R0
JC SCAN1
SCAN2:
MOV A,R1 ;取回行位置
;计算行地址
CJNE A,#1000B,SCAN3
RR A
AJMP SCAN4
SCAN3:
CJNE A,#100B,SCAN4
DEC A
SCAN4:
;计算按键位置
DEC A
RL A
RL A
ADD A,R0
RET
TAB:
DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H,88H,83H,0C6H,0A1H,86H,8EH
DELAY5MS: ;@11.0592MHz
PUSH 30H
PUSH 31H
MOV 30H,#9
MOV 31H,#239
NEXT:
DJNZ 31H,NEXT
DJNZ 30H,NEXT
POP 31H
POP 30H
RET
END
总结(相关资源)
工程文件+仿真图
相关资源我会放到资源绑定里。(我不设置积分下载的话应该是免费下载的吧?)