實驗題目
將8255單元與鍵盤及數碼管顯示單元連接,編寫實驗程序,掃描鍵盤輸入,並將掃描結果送數碼管顯示。鍵盤採用4X4鍵盤,每個數碼管顯示值可爲0-F共16個數。
實驗具體內容如下:
將鍵盤進行編號,記作0~F,當按下其中一一個按鍵時,將該按鍵對應的編號在一一個數碼管上顯示出來,當再按下一個按鍵時,便將這個按鍵的編號在下-一個數碼管上顯示出來,數碼管上可以顯示最近4次按下的按鍵編號。
電路圖
實驗代碼
;=======================================================
; 文件名: Keyscan.asm
; 功能描述: 鍵盤及數碼管顯示實驗,通過8255控制。
; 8255的 B口控制數碼管的段顯示,
; A口控制鍵盤列掃描及數碼管的位驅動,
; C口控制鍵盤的行掃描。
; 按下按鍵,該按鍵對應的位置將按順序顯示在數碼管上。
;=======================================================
IOY0 EQU 0600H ;片選IOY0對應的端口始地址
MY8255_A EQU IOY0+00H*2 ;8255的A口地址
MY8255_B EQU IOY0+01H*2 ;8255的B口地址
MY8255_C EQU IOY0+02H*2 ;8255的C口地址
MY8255_CON EQU IOY0+03H*2 ;8255的控制寄存器地址
SSTACK SEGMENT STACK
DW 16 DUP(?)
SSTACK ENDS
DATA SEGMENT
; DATBLE是 將需要輸入按鍵的值對應需要給的顯示器的值
; 比如按鍵1表示的值是1 但是我們送給顯示器的是06H
; 該程序是通過判斷按鍵按下 獲取其代表的偏移量(相對於DTABLE)
; 比如按鍵1的偏移量是1 我們掃描按鍵 得出一個值 1
; 然後利用該值在DTABLE中找到需要輸出值的對應顯示代碼值
; 從B口送出去即可
DTABLE DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H
DB 7FH,6FH,77H,7CH,39H,5EH,79H,71H
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA
START:
MOV AX,DATA
MOV DS,AX
; 把3000H--3005H中的值全部初始化爲00H
; 說明初始偏移量全爲0(3000H--3005H)
MOV SI,3000H
MOV AL,00H
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_CON ;8255控制字初始化
MOV AL,81H ;1000 0001 A、B口輸出 C口輸入
OUT DX,AL
BEGIN:
; 調用顯示子程序
CALL DIS
;清屏
CALL CLEAR
;掃描 看是否有鍵按下
CALL CCSCAN
;有鍵按下 跳INK1
JNZ INK1
JMP BEGIN
INK1:
CALL DIS
CALL DALLY
CALL DALLY
CALL CLEAR
CALL CCSCAN
; 若結果不爲0 ZF=0 則說明一定有鍵按下 則跳轉 判斷哪個鍵按下
JNZ INK2
JMP BEGIN
;確定按下鍵的位置
INK2:
MOV CH,0FEH ; FEH=1111 1110(對應關係:PA7 PA6..PA1 PA0 )
; PA5-PA0=1111 10 (這裏對應關係要弄明白)
;PA0對應的按鍵則是 從左到右第一列(這裏不會暈哦)
MOV CL,00H ; 初始對於行的偏移量 爲0
;列循環 即掃描列 從第一列開始
COLUM:
MOV AL,CH
MOV DX,MY8255_A
OUT DX,AL
MOV DX,MY8255_C
IN AL,DX
L1: TEST AL,01H ;is L1?
JNZ L2
MOV AL,00H ;L1
JMP KCODE
L2: TEST AL,02H ;is L2?
JNZ L3
MOV AL,04H ;L2
JMP KCODE
L3: TEST AL,04H ;is L3?
JNZ L4
MOV AL,08H ;L3
JMP KCODE
L4: TEST AL,08H ;is L4?
JNZ NEXT
MOV AL,0CH ;L4
; 找到按鍵後 此時AL存的的第一列每一行的初始值 0 4 8 C
; CL 存的是對應行的偏移量
; 假設 AL爲08H CL爲2 則表示的總偏移量爲 8+2=10H
; 說明在table中該數字的偏移量爲10H
; 輸出該數字 利用偏移量就行 因爲數字其實是存在table中的
KCODE: ADD AL,CL
CALL PUTBUF
PUSH AX
KON: CALL DIS
CALL CLEAR
CALL CCSCAN
JNZ KON
POP AX
NEXT: INC CL ; CL相當於 行偏移量
MOV AL,CH
TEST AL,08H ; 08H=0000 1000 當AL爲1111 0111 && 0000 1000 結果爲0
; ZF=1 說明行偏移量達到最大值 3
JZ KERR ; 4次列循環結束 跳KERR
ROL AL,1
MOV CH,AL
JMP COLUM
KERR: JMP BEGIN
; 鍵盤掃描子程序
; 原理是 先向全部列輸出低電平
; 然後從C口讀入 行電平
; 如果沒有按鍵按下 所有行應該均爲高電平
; 反之 若有按鍵按下 則開始仔細判斷出到底是哪個按鍵按下 具體判斷方法是:
; 先向第一列輸出低電平(從左到右)
; 然後從C口讀入行電平 利用 AND
; 判斷哪一行是否爲低電平即可(後面爲了計算方便取反了行電平)
; 若行全爲高 爲開始向下一列輸出低電平 循環4次即可
CCSCAN: MOV AL,00H
MOV DX,MY8255_A
OUT DX,AL ; 向所有列輸出 低電平
MOV DX,MY8255_C
IN AL,DX ;讀所有行電平
;原來沒有任何鍵按下 4行全爲1
;這裏取反 變成 0000 便於後面的判斷
NOT AL
; 假設沒有按鍵按下
; 0000&1111=0
; 結果爲0 ZF=1
AND AL,0FH
RET
;清屏子程序
;就是使得所有的燈熄滅 00H表示全不亮 瞬間 很快
CLEAR: MOV DX,MY8255_B
MOV AL,00H
OUT DX,AL
RET
; 顯示子程序 (這裏稍微有點繞)
DIS: PUSH AX
MOV SI,3000H
; 0DFH=1101 1111 對應PA7 PA6 PA5...PA1 PA0
; 由電路圖 得出 X1-PA0 X2-PA1.....
; 6個顯示器 從左到右依次是 X1 X2 X3... X5 X6
; 所以 對應的PA: PA0 PA1 PA2...PA4 PA5
; 這裏初始是0DFH 代表 1 1 1 1 1 0
; 意思是 第六個顯示 開始顯示數字
; 哈哈 這裏其實是從X6到X1依次顯示的
; 每個數字顯示間隔很快 我們會認爲是6個數字一起顯示 其實是逐個顯示
MOV DL,0DFH
MOV AL,DL
AGAIN: PUSH DX
; 把AL送給A口 覺得開放哪個燈 (這裏要看電路圖 A口也控制燈的開放)
MOV DX,MY8255_A
OUT DX,AL
MOV AL,[SI] ; 把3000H--3005H中存的偏移量(相對)取出
MOV BX,OFFSET DTABLE ; 獲取DTABLE的首地址
AND AX,00FFH ;因爲後面會有加法運算 先把ah清0 這樣ax就是
; al的值,防止出錯
ADD BX,AX ; 獲取需要的值的偏移量(這個是絕對偏移量)
MOV AL,[BX] ; 獲取顯示數字需要的值 例 顯示0需要3FH
MOV DX,MY8255_B ; 送往B口 顯示數字
OUT DX,AL
CALL DALLY ;延時
INC SI ;移動SI 讀取下一個偏移量
POP DX
MOV AL,DL ; DL: 控制哪個燈的開放 開始是0DF 1101 1111
; 取後6位(看電路圖 只連了6根線)即01 1111
; 賦值給AL
TEST AL,01H ; 測試AL 看是否爲11 1110
; 6個燈 一次顯示需要循環6次
; 這裏第六次結束是 AL=11 1110
; 對於燈 就是x1燈顯示完(燈:X6->X1)
JZ OUT1 ; 6次循環完成後 跳出
ROR AL,1 ; 循環右移
; 例 第一個燈亮 AL=01 1111
; 則 第二個燈亮 爲 10 1111
; 所以需要循環右移
; 反映在燈上 則是左移(不要繞進去了哦)
MOV DL,AL
JMP AGAIN ; 跳回 繼續顯示 需循環6次
OUT1: POP AX
RET
; 子程序 延時作用 RET爲子程序結束標記
DALLY: PUSH CX
MOV CX,0006H
T1: MOV AX,009FH
T2: DEC AX
JNZ T2
LOOP T1
POP CX
RET
; 將獲得的偏移量存入3000H--30005H中
; 便於後面的顯示
; 顯示其實就是從3000H--3005H中讀取偏移量
; 然後在table中找到真正的值即可
PUTBUF: MOV SI,DI ;存鍵盤值到相應位的緩衝中
MOV [SI],AL ;先存入地址3005H 再遞減 也就是下一個存入偏移量的是3004H
DEC DI
CMP DI,2FFFH
JNZ GOBACK
MOV DI,3005H
GOBACK: RET
CODE ENDS
END START
更多
獲取更多資料、代碼,微信公衆號:海轟Pro
回覆 海轟 即可