博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
用汇编实现矩阵键盘编程设计
阅读量:613 次
发布时间:2019-03-13

本文共 5983 字,大约阅读时间需要 19 分钟。

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

目的

1.掌握I/O芯片编程应用

2.掌握矩阵键盘编码设计技术

要求

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

代码

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

第一种

DOUT			EQU		0A000H  	; 数码管控制口KEY_RAS	EQU		8000H 		; 行线控制口KEY_CAS	EQU		9000H  	; 列线控制口data   segmentLEDMAP		db    3fh, 06h, 5bh, 4fh, 66h, 6dh, 7dh, 07h ; 八段管显示码					db    7fh, 6fh, 77h, 7ch, 39h, 5eh, 79h, 71hKeyTable		db    0ch, 0dh, 0eh, 0fh ; 键码定义					db    08h, 09h, 0ah, 0bh					db    04h, 05h, 06h, 07h					db    00h, 01h, 02h, 03hdata   endscode   segment       assume cs:code, ds:dataStart  proc near				MOV	AX, data				MOV	DS, AX				MOV	DX,DOUT						MOV	AL, 0				OUT		DX, ALMLoop:	  	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  	MLoopTestKey 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     ; 高四位不用				RETTestKey endpGetKey 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		Exit2KNEXT:	TEST	AL, 1				JNZ		Exit1				SHR		AL, 1				INC		BH				CMP	BH, 4				JNZ		KNEXT				JMP		Exit2Exit1:		MOV	CL, 2				SHL		BL, CL  				ADD		BL, BH ;键值 = 行X 4 +列  				MOV	AL, BL				;MOV	BX, offset KeyTable				;XLATExit2:		POP		DX				POP		CX				POP		BX				RETGetKey endpDelay  proc  near				PUSH	AX            ; 延时子程序				PUSH	CX				MOV	AL, 10H				MOV	CX, AX				LOOP  $				POP		CX				POP		AX				RETDelay  endp	Start  endpcode   ends       end Start

第二种

DOUT			EQU		0A000H  	; 数码管控制口KEY_RAS	EQU		8000H 		; 行线控制口KEY_CAS	EQU		9000H  	; 列线控制口data   segmentLEDMAP		db    3fh, 06h, 5bh, 4fh, 66h, 6dh, 7dh, 07h ; 八段管显示码					db    7fh, 6fh, 77h, 7ch, 39h, 5eh, 79h, 71hKeyTable		db    0ch, 0dh, 0eh, 0fh ; 键码定义					db    08h, 09h, 0ah, 0bh					db    04h, 05h, 06h, 07h					db    00h, 01h, 02h, 03hdata   endscode   segment       assume cs:code, ds:dataStart  proc near				MOV	AX, data				MOV	DS, AX				MOV	DX,DOUT						MOV	AL, 0				OUT		DX, ALMLoop:	  	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  	MLoopTestKey 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     ; 高四位不用				RETTestKey endpGetKey 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		Exit2KNEXT:				 MOV	CH, 00000001B	;  R3R2R1R0				 JNE		KLoop1KLoop1:							 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		Exit2Exit1:			MOV	CL, 2				SHL		BL, CL  				ADD	BL, BH ;键值 = 行X 4 +列  				MOV	AL, BL				;MOV	BX, offset KeyTable				;XLATExit2:			POP		DX				POP		CX				POP		BX				RETGetKey endpDelay  proc  near				PUSH	AX            ; 延时子程序				PUSH	CX				MOV	AL, 10H				MOV	CX, AX				LOOP  $				POP		CX				POP		AX				RETDelay  endp	Start  endpcode   ends       end Start

第三种

DOUT			EQU		0A000H  	; 数码管控制口KEY_RAS	EQU		8000H 		; 行线控制口KEY_CAS	EQU		9000H  	; 列线控制口data   segmentLEDMAP		db    3fh, 06h, 5bh, 4fh, 66h, 6dh, 7dh, 07h ; 八段管显示码					db    7fh, 6fh, 77h, 7ch, 39h, 5eh, 79h, 71hKeyTable		db    0ch, 0dh, 0eh, 0fh ; 键码定义					db    08h, 09h, 0ah, 0bh					db    04h, 05h, 06h, 07h					db    00h, 01h, 02h, 03hdata   endscode   segment       assume cs:code, ds:dataStart  proc near				MOV	AX, data				MOV	DS, AX				MOV	DX,DOUT						MOV	AL, 0				OUT		DX, ALMLoop:	  	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  	MLoopTestKey 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     ; 高四位不用				RETTestKey endpGetKey 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   	exit2test1:				SHR al,1				inc BH				cmp al,0				jnz test1				dec BHloop2:				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 BLExit1:			MOV	CL, 2				SHL		BL, CL  				ADD	BL, BH ;键值 = 行X 4 +列  				MOV	AL, BL				;MOV	BX, offset KeyTable				;XLATExit2:			POP		DX				POP		CX				POP		BX				RETGetKey endpDelay  proc  near				PUSH	AX            ; 延时子程序				PUSH	CX				MOV	AL, 10H				MOV	CX, AX				LOOP  $				POP		CX				POP		AX				RETDelay  endp	Start  endpcode   ends       end Start

小结

这里面的第一种其实只是要求一,但是可以理解一下思路,第二种呢就是第一种的叠加,但是效率很低,要扫描16次,第三种方法是从同学那里学到的,确实简单只需要扫描一次,之后自己写了一下,也不难,现在越来越发现算法的重要性,害

本文章6.10前不允许抄袭转载,不允许当做接口作业使用

你可能感兴趣的文章