用汇编实现矩阵键盘编程设计

用汇编实现矩阵键盘编程设计

目的

1.掌握I/O芯片编程应用
2.掌握矩阵键盘编码设计技术

要求

  1. 用扫描法读取键值显示。
  2. 用反转法读取键值显示。

代码

这里用了三种方法,其实大同小异可以读一下程序作为参考

第一种

DOUT			EQU		0A000H  	; 数码管控制口
KEY_RAS	EQU		8000H 		; 行线控制口
KEY_CAS	EQU		9000H  	; 列线控制口

data   segment
LEDMAP		db    3fh, 06h, 5bh, 4fh, 66h, 6dh, 7dh, 07h ; 八段管显示码
					db    7fh, 6fh, 77h, 7ch, 39h, 5eh, 79h, 71h

KeyTable		db    0ch, 0dh, 0eh, 0fh ; 键码定义
					db    08h, 09h, 0ah, 0bh
					db    04h, 05h, 06h, 07h
					db    00h, 01h, 02h, 03h
data   ends

code   segment
       assume cs:code, ds:data
Start  proc near
				MOV	AX, data
				MOV	DS, AX
				MOV	DX,DOUT		
				MOV	AL, 0
				OUT		DX, AL
MLoop:	  	CALL  	TestKey         ; 检查有键入?
				CMP	AL, 0
				JZ		MLoop 			; 无键入, 继续查询
 				CALL	Delay			; 消抖动
				CALL	GetKey        ; 读入键码 修改设置
				CMP	AL, 0FFH
				JZ		MLoop
				MOV	BX, offset LEDMAP
				XLAT
				MOV	DX, DOUT
				OUT		DX, AL
				JMP  	MLoop

TestKey proc near					;无键按下,返回为0
				MOV	DX, KEY_RAS
				MOV	AL, 0
				OUT		DX, AL     ; 输出线置为0
				MOV	DX, KEY_CAS
				IN			AL, DX      ; 读入键状态
				NOT		AL
				AND		AL, 0FH     ; 高四位不用
				RET
TestKey endp

GetKey proc near
				PUSH	BX
				PUSH	CX
				PUSH	DX
				MOV	CH, 00000001B	;  R3R2R1R0
				MOV	BH, 0					; 列计数
				MOV	BL, 0					; 行计数
KLoop:		MOV	DX, KEY_RAS		; 行线
				MOV	AL, CH        			; 找出键所在行
				NOT		AL
				OUT		DX, AL
				SHL		CH, 1
				MOV	DX, KEY_CAS		; 列线
				IN			AL, DX
				NOT		AL
				AND		AL, 0FH				; 取低4位
				JNE		KNEXT      			; 该列有键入
				INC		BL
				CMP	BL, 4
				JNZ		KLoop
				MOV	AL,0FFH				; 没有键按下, 返回 0ffh
				JMP		Exit2
KNEXT:	TEST	AL, 1
				JNZ		Exit1
				SHR		AL, 1
				INC		BH
				CMP	BH, 4
				JNZ		KNEXT
				JMP		Exit2
Exit1:		MOV	CL, 2
				SHL		BL, CL  
				ADD		BL, BH ;键值 = 行X 4 +列  
				MOV	AL, BL
				;MOV	BX, offset KeyTable
				;XLAT
Exit2:		POP		DX
				POP		CX
				POP		BX
				RET
GetKey endp

Delay  proc  near
				PUSH	AX            ; 延时子程序
				PUSH	CX
				MOV	AL, 10H
				MOV	CX, AX
				LOOP  $
				POP		CX
				POP		AX
				RET
Delay  endp
	
Start  endp
code   ends
       end Start

第二种

DOUT			EQU		0A000H  	; 数码管控制口
KEY_RAS	EQU		8000H 		; 行线控制口
KEY_CAS	EQU		9000H  	; 列线控制口

data   segment
LEDMAP		db    3fh, 06h, 5bh, 4fh, 66h, 6dh, 7dh, 07h ; 八段管显示码
					db    7fh, 6fh, 77h, 7ch, 39h, 5eh, 79h, 71h

KeyTable		db    0ch, 0dh, 0eh, 0fh ; 键码定义
					db    08h, 09h, 0ah, 0bh
					db    04h, 05h, 06h, 07h
					db    00h, 01h, 02h, 03h
data   ends

code   segment
       assume cs:code, ds:data
Start  proc near
				MOV	AX, data
				MOV	DS, AX
				MOV	DX,DOUT		
				MOV	AL, 0
				OUT		DX, AL
MLoop:	  	CALL  	TestKey         ; 检查有键入?
				CMP	AL, 0
				JZ		MLoop 			; 无键入, 继续查询
 				CALL	Delay			; 消抖动
				CALL	GetKey        ; 读入键码 修改设置
				CMP	AL, 0FFH
				JZ		MLoop
				MOV	BX, offset LEDMAP
				XLAT
				MOV	DX, DOUT
				OUT		DX, AL
				JMP  	MLoop

TestKey proc near					;无键按下,返回为0
				MOV	DX, KEY_RAS
				MOV	AL, 0
				OUT		DX, AL     ; 输出线置为0
				MOV	DX, KEY_CAS
				IN			AL, DX      ; 读入键状态
				NOT		AL
				AND		AL, 0FH     ; 高四位不用
				RET
TestKey endp

GetKey proc near
				PUSH	BX
				PUSH	CX
				PUSH	DX
				MOV	CH, 00000001B	;  C3C2C1C0
				MOV	BH, 0					; 列计数
				MOV	BL, 0					; 行计数
KLoop:			MOV	DX, KEY_CAS		; 列线
				MOV	AL, CH        			; 找出键所在列
				NOT		AL
				OUT		DX, AL
				SHL		CH, 1
				MOV	DX, KEY_RAS		; 行线
				IN		AL, DX
				NOT		AL
				AND	AL, 0FH				; 取低4位
				JNE		KNEXT      			; 该列有键入
				INC		BH
				CMP		BH, 4
				JNZ		KLoop
				MOV	AL,0FFH				; 没有键按下, 返回 0ffh
				JMP		Exit2
KNEXT:
				 MOV	CH, 00000001B	;  R3R2R1R0
				 JNE		KLoop1
KLoop1:			
				 MOV	DX, KEY_RAS		; 行线
				MOV	AL, CH        			; 找出键所在行
				NOT		AL
				OUT		DX, AL
				SHL		CH, 1
				MOV	DX, KEY_CAS		; 列线
				IN			AL, DX
				NOT		AL
				AND		AL, 0FH				; 取低4位
				JNE		Exit1      			; 该列有键入
				INC		BL
				CMP	BL, 4
				JNZ		KLoop1
				MOV	AL,0FFH				; 没有键按下, 返回 0ffh
				JMP		Exit2

Exit1:			MOV	CL, 2
				SHL		BL, CL  
				ADD	BL, BH ;键值 = 行X 4 +列  
				MOV	AL, BL
				;MOV	BX, offset KeyTable
				;XLAT
Exit2:			POP		DX
				POP		CX
				POP		BX
				RET
GetKey endp

Delay  proc  near
				PUSH	AX            ; 延时子程序
				PUSH	CX
				MOV	AL, 10H
				MOV	CX, AX
				LOOP  $
				POP		CX
				POP		AX
				RET
Delay  endp
	
Start  endp
code   ends
       end Start

第三种

DOUT			EQU		0A000H  	; 数码管控制口
KEY_RAS	EQU		8000H 		; 行线控制口
KEY_CAS	EQU		9000H  	; 列线控制口

data   segment
LEDMAP		db    3fh, 06h, 5bh, 4fh, 66h, 6dh, 7dh, 07h ; 八段管显示码
					db    7fh, 6fh, 77h, 7ch, 39h, 5eh, 79h, 71h

KeyTable		db    0ch, 0dh, 0eh, 0fh ; 键码定义
					db    08h, 09h, 0ah, 0bh
					db    04h, 05h, 06h, 07h
					db    00h, 01h, 02h, 03h
data   ends

code   segment
       assume cs:code, ds:data
Start  proc near
				MOV	AX, data
				MOV	DS, AX
				MOV	DX,DOUT		
				MOV	AL, 0
				OUT		DX, AL
MLoop:	  	CALL  	TestKey         ; 检查有键入?
				CMP	AL, 0
				JZ		MLoop 			; 无键入, 继续查询
 				CALL	Delay			; 消抖动
				CALL	GetKey        ; 读入键码 修改设置
				CMP	AL, 0FFH
				JZ		MLoop
				MOV	BX, offset LEDMAP
				XLAT
				MOV	DX, DOUT
				OUT		DX, AL
				JMP  	MLoop

TestKey proc near					;无键按下,返回为0
				MOV	DX, KEY_RAS
				MOV	AL, 0
				OUT		DX, AL     ; 输出线置为0
				MOV	DX, KEY_CAS
				IN			AL, DX      ; 读入键状态
				NOT		AL
				AND		AL, 0FH     ; 高四位不用
				RET
TestKey endp

GetKey proc near
				PUSH	BX
				PUSH	CX
				PUSH	DX
				MOV	BH, 0					; 列计数
				MOV	BL, 0					; 行计数
loop1:
				MOV	DX, KEY_RAS
				MOV	AL, 0
				OUT		DX, AL     ; 输出线置为0
				MOV	DX, KEY_CAS
				IN			AL, DX      ; 读入键状态
				NOT		AL
				AND		AL, 0FH     ; 高四位不用
				cmp         AL,0
				 jnz 		test1
				 MOV	AL,0FFH
				 jmp   	exit2
test1:
				SHR al,1
				inc BH
				cmp al,0
				jnz test1
				dec BH
loop2:
				MOV	DX, KEY_CAS
				MOV	AL, 0
				OUT		DX, AL     ; 输出线置为0
				MOV	DX, KEY_RAS
				IN			AL, DX      ; 读入键状态
				NOT		AL
				AND		AL, 0FH     ; 高四位不用
test2:
				SHR al,1
				INC BL
				cmp al,0
				jnz test2
				dec BL
Exit1:			MOV	CL, 2
				SHL		BL, CL  
				ADD	BL, BH ;键值 = 行X 4 +列  
				MOV	AL, BL
				;MOV	BX, offset KeyTable
				;XLAT
Exit2:			POP		DX
				POP		CX
				POP		BX
				RET
GetKey endp

Delay  proc  near
				PUSH	AX            ; 延时子程序
				PUSH	CX
				MOV	AL, 10H
				MOV	CX, AX
				LOOP  $
				POP		CX
				POP		AX
				RET
Delay  endp
	
Start  endp
code   ends
       end Start

小结

这里面的第一种其实只是要求一,但是可以理解一下思路,第二种呢就是第一种的叠加,但是效率很低,要扫描16次,第三种方法是从同学那里学到的,确实简单只需要扫描一次,之后自己写了一下,也不难,现在越来越发现算法的重要性,害
本文章6.10前不允许抄袭转载,不允许当做接口作业使用

  • 5
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值