?? keyscan.asm
字號:
;Keyscan.asm
;鍵盤掃描及數(shù)碼管顯示實驗
;****************根據(jù)查看端口資源修改下列符號值*******************
IOY0 EQU 9C00H ;片選IOY0對應的端口始地址
;*****************************************************************
MY8255_A EQU IOY0+00H*4 ;8255的A口地址
MY8255_B EQU IOY0+01H*4 ;8255的B口地址
MY8255_C EQU IOY0+02H*4 ;8255的C口地址
MY8255_MODE EQU IOY0+03H*4 ;8255的控制寄存器地址
STACK1 SEGMENT STACK
DW 256 DUP(?)
STACK1 ENDS
DATA SEGMENT
DTABLE DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH,77H,7CH,39H,5EH,79H,71H
DATA ENDS ;鍵值表,0~F對應的7段數(shù)碼管的段位值
CODE SEGMENT
ASSUME CS:CODE,DS:DATA
START: MOV AX,DATA
MOV DS,AX
MOV SI,3000H ;建立緩沖區(qū),存放要顯示的鍵值
MOV AL,00H ;先初始化鍵值為0
MOV [SI],AL
MOV [SI+1],AL
MOV [SI+2],AL
MOV [SI+3],AL
MOV [SI+4],AL
MOV [SI+5],AL
MOV DI,3005H
MOV DX,MY8255_MODE ;初始化8255工作方式
MOV AL,81H ;方式0,A口、B口輸出,C口低4位輸入
OUT DX,AL
BEGIN: CALL DIS ;顯示刷新
CALL CLEAR ;清屏
CALL CCSCAN ;掃描按鍵
JNZ GETKEY1 ;有鍵按下則跳置GETKEY1
MOV AH,1 ;判斷PC鍵盤是否有按鍵按下
INT 16H
JZ BEGIN ;無按鍵則跳回繼續(xù)循環(huán),有則退出
QUIT: MOV AX,4C00H ;返回到DOS
INT 21H
GETKEY1:CALL DIS ;顯示刷新
CALL DALLY
CALL DALLY
CALL CLEAR ;清屏
CALL CCSCAN ;再次掃描按鍵
JNZ GETKEY2 ;有鍵按下則跳置GETKEY2
JMP BEGIN ;否則跳回開始繼續(xù)循環(huán)
GETKEY2:MOV CH,0FEH
MOV CL,00H ;設置當前檢測的是第幾列
COLUM: MOV AL,CH ;選取一列,將X1~X4中一個置0
MOV DX,MY8255_A
OUT DX,AL
MOV DX,MY8255_C ;讀Y1~Y4,用于判斷是哪一行按鍵閉合
IN AL,DX
L1: TEST AL,01H ;是否為第1行
JNZ L2 ;不是則繼續(xù)判斷
MOV AL,00H ;設置第1行第1列的對應的鍵值
JMP KCODE
L2: TEST AL,02H ;是否為第2行
JNZ L3 ;不是則繼續(xù)判斷
MOV AL,04H ;設置第2行第1列的對應的鍵值
JMP KCODE
L3: TEST AL,04H ;是否為第3行
JNZ L4 ;不是則繼續(xù)判斷
MOV AL,08H ;設置第3行第1列的對應的鍵值
JMP KCODE
L4: TEST AL,08H ;是否為第4行
JNZ NEXT ;不是則繼續(xù)判斷
MOV AL,0CH ;設置第4行第1列的對應的鍵值
KCODE: ADD AL,CL ;將第1列的值加上當前列數(shù),確定按鍵值
CALL PUTBUF ;保存按鍵值
PUSH AX
KON: CALL DIS ;顯示刷新
CALL CLEAR ;清屏
CALL CCSCAN ;掃描按鍵,判斷按鍵是否彈起
JNZ KON ;未彈起則繼續(xù)循環(huán)等待彈起
POP AX
NEXT: INC CL ;當前檢測的列數(shù)遞增
MOV AL,CH
TEST AL,08H ;檢測是否掃描到第4列
JZ KERR ;是則跳回到開始處
ROL AL,1 ;沒檢測到第4列則準備檢測下一列
MOV CH,AL
JMP COLUM
KERR: JMP BEGIN
CCSCAN PROC NEAR ;掃描是否有按鍵閉合子程序
MOV AL,00H
MOV DX,MY8255_A ;將4列全選通,X1~X4置0
OUT DX,AL
MOV DX,MY8255_C
IN AL,DX ;讀Y1~Y4
NOT AL
AND AL,0FH ;取出Y1~Y4的反值
RET
CCSCAN ENDP
CLEAR PROC NEAR ;清除數(shù)碼管顯示子程序
MOV DX,MY8255_B ;段位置0即可清除數(shù)碼管顯示
MOV AL,00H
OUT DX,AL
RET
CLEAR ENDP
DIS PROC NEAR ;顯示鍵值子程序
PUSH AX ;以緩沖區(qū)存放的鍵值為鍵值表偏移找到鍵值并顯示
MOV SI,3000H
MOV DL,0DFH
MOV AL,DL
AGAIN: PUSH DX
MOV DX,MY8255_A
OUT DX,AL ;設置X1~X4,選通一個數(shù)碼管
MOV AL,[SI] ;取出緩沖區(qū)中存放鍵值
MOV BX,OFFSET DTABLE
AND AX,00FFH
ADD BX,AX
MOV AL,[BX] ;將鍵值作為偏移和鍵值基地址相加得到相應的鍵值
MOV DX,MY8255_B
OUT DX,AL ;寫入數(shù)碼管A~Dp
CALL DALLY
INC SI ;取下一個鍵值
POP DX
MOV AL,DL
TEST AL,01H ;判斷是否顯示完?
JZ OUT1 ;顯示完,返回
ROR AL,1
MOV DL,AL
JMP AGAIN ;未顯示完,跳回繼續(xù)
OUT1: POP AX
RET
DIS ENDP
PUTBUF PROC NEAR ;保存鍵值子程序
MOV SI,DI
MOV [SI],AL
DEC DI
CMP DI,2FFFH
JNZ GOBACK
MOV DI,3005H
GOBACK: RET
PUTBUF ENDP
DALLY PROC NEAR ;軟件延時子程序
PUSH CX
MOV CX,00FFH
D1: MOV AX,00FFH
D2: DEC AX
JNZ D2
LOOP D1
POP CX
RET
DALLY ENDP
CODE ENDS
END START
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -