本文共 5983 字,大约阅读时间需要 19 分钟。
1.掌握I/O芯片编程应用
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前不允许抄袭转载,不允许当做接口作业使用