PORT_A EQU 280H;A口地址 PORT_B EQU 281H;B口地址 PORT_C EQU 282H ;C口地址 PORT_CTL EQU 283H;控制字寄存器地址 DATA SEGMENT ;键盘扫描码表 TABLE DB 77H,7bH,7DH,7EH,0B7H,0BBH,0BDH,0BEH DB 0D7H,0DBH,0DDH,0DEH,0E7H,0EBH,0EDH,0EEH ;0~F的七段代码编码 TABLE1 DB 0BFH,86H,0dbH,0CFH,0E6H,0EdH,0FDH,87H DB 0FFH,0E7H,0F7H,0FCH,0B9H, 0DEH,0F9H,0F1H DATA ENDS ;堆栈段 STACK SEGMENT STACK DW 50 DUP(0) TOP_STACK LABEL WORD STACK ENDS ;代码段 CODE SEGMENT ASSUME CS:CODE,DS:DATA;SS:STACK START: MOV AX,STACK MOV SS,AX LEA SP,TOP_STACK MOV AX,DATA MOV DS,AX MOV DX,PORT_CTL MOV AL,10000010B;8255初始化,A口输出,B口和C口输入,方式0 OUT DX,AL ;向所有行送0 S: MOV DX,PORT_A MOV AL,0 OUT DX,AL ;读列,查看所有键是否松开 MOV DX,PORT_B WAIT_OPEN: IN AL,DX AND AL,0FH CMP AL,0FH JNE WAIT_OPEN ;各键均已松开,查列是否有键按下 WAIT_PRES: IN AL,DX AND AL,0FH CMP AL,0FH JE WAIT_PRES ;再查列,看键是否仍被压着 IN AL,DX AND AL,0FH CMP AL,0FH JE WAIT_PRES ;键仍被压着,确定哪一个键被压下 MOV AL,0FEH MOV CL,AL NEXT_ROW: MOV DX,PORT_A OUT DX,AL MOV DX,PORT_B IN AL,DX AND AL,0FH CMP AL,0FH JNE ENCODE;列值不全为1,表示有键按下,转去编码 ROL CL,01 MOV AL,CL JMP NEXT_ROW ;已找到某一列为0,对压键的行列值编码 ENCODE: MOV BX,000FH IN AL,DX NEXT_TRY: CMP AL,TABLE[BX];比较读出的行列值和表中是否一致 JE DONE DEC BX JNS NEXT_TRY MOV AH,01 JMP EXIT DONE: MOV DX,PORT_C;C口输出 MOV AL,TABLE1[BX];查0~F的七段代码编码 OUT DX,AL JMP S ;循环检测该程序 EXIT: HLT CODE ENDS END START
|