实验九 键盘扫描及数码管显示实验
1. 实验内容
基础部分
编写程序,实现如下功能:初始时数码管无显示;第一次按下键盘时,在最右侧数码管显示对应的十六进制数字;以后每次按下键盘,则将当前显示的数字全部向左移动一位(最左侧的数字移出数码管),并将刚刚键入的数字显示在数码管的最右侧。
扩展部分
编写程序,将所按键对应的数字(0~E)按要求显示在指定的数码管上:
- 初始时,6 位 LED 数码管上无显示;
- 第一次键入的数字显示在最右端的数码管上;之后每次键入新数字,其显示位置向左移动一位;(只显示最后键入的数字)
- 若当前显示的数字已处于数码管的最左端,此时再键入数字,则将其显示在最左端的数码管上;之后键入数字的显示位置逐次向右移动;
- 如此往复,直至按下数字键 F,程序退出
2. 实验原理
3. 连线
4. 实验代码
基础部分:
P8255A EQU 0600H
P8255B EQU 0602H
P8255C EQU 0604H
P8255MODE EQU 0606H
DATA SEGMENT
TAB DB 3FH,06H,5BH,4FH ; 共阴极数码管0~F
DB 66H,6DH,7DH,07H
DB 7FH,6FH,77H,7CH
DB 39H,5EH,79H,71H
T1 DB 00H ; T1~T6 对应从右到左六个数码管
T2 DB 00H
T3 DB 00H
T4 DB 00H
T5 DB 00H
T6 DB 00H
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE, DS:DATA
START:
MOV AX, DATA
MOV DS, AX
MOV AX, 00H
LEA BX, TAB
MOV DX, P8255MODE
MOV AL, 81H
OUT DX, AL
MAIN:
MOV AL, 11110111B ; 从X4到X1判断是否有按键按下
MOV CX, 4
CHECK_ROW:
MOV DX, P8255A ; 选列
OUT DX, AL
SHR AL, 1
PUSH AX
PUSH CX
MOV DX, P8255C
IN AL, DX ; 读Y口
AND AL, 0FH ; 屏蔽高四位
CMP AL, 0FH ; 判断是否有按键按下(若无则为FF)
JZ NEXT ; 无按键按下
CALL CHANGE ; 有按键按下,更改显示
NEXT:
CALL SHOW ; 数码管显示
POP CX
POP AX
LOOP CHECK_ROW
JMP MAIN
CHANGE:
OR AX, 0F0H ; 屏蔽高4位
CMP AL, 11111110B ; Y1有按键按下?
JZ D1
CMP AL, 11111101B ; Y2有按键按下?
JZ D2
CMP AL, 11111011B ; Y3有按键按下?
JZ D3
CMP AL, 11110111B ; Y4有按键按下?
JZ D4
D1: MOV AL, 04H ; Y1有按键按下
JMP CALC
D2: MOV AL, 08H ; Y2有按键按下
JMP CALC
D3: MOV AL, 0CH ; Y3有按键按下
JMP CALC
D4: MOV AL, 10H ; Y4有按键按下
JMP CALC
CALC:
ADD AL, CL ; 计算(Xi, Yj)对应数字
SUB AL, 05H ; 对应i+4*j-5
AND AH, 00H ; AX高8位清零
MOV SI, AX ; 至此,AX的值为按键对应的数字
LEA BX, TAB ; 更改数码管内容
MOV AL, T5
MOV T6, AL
MOV AL, T4
MOV T5, AL
MOV AL, T3
MOV T4, AL
MOV AL, T2
MOV T3, AL
MOV AL, T1
MOV T2, AL
MOV AX, [BX+SI]
MOV T1, AL
CALL LDELAY
DFI:
RET
SHOW:
LEA BX, T1
MOV AL, 11011111B
MOV SI, 00H
MOV CX, 06H
MC:
MOV DX, P8255A
OUT DX, AL
ROR AL, 1
PUSH AX
MOV DX, P8255B
MOV AL, [BX+SI]
OUT DX, AL
POP AX
INC SI
CALL DELAY
LOOP MC
RET
DELAY:
PUSH CX
MOV CX, 05FFH
LOOP $
POP CX
RET
LDELAY:
PUSH CX
MOV CX, 0FFFFH
LOOP $
POP CX
RET
CODE ENDS
END START
扩展部分:
P8255A EQU 0600H
P8255B EQU 0602H
P8255C EQU 0604H
P8255MODE EQU 0606H
DATA SEGMENT
TAB DB 3FH,06H,5BH,4FH
DB 66H,6DH,7DH,07H
DB 7FH,6FH,77H,7CH
DB 39H,5EH,79H,71H
POS DB 01H
NUM DB 00H
TURN DB 01H
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE, DS:DATA
START:
MOV AX, DATA
MOV DS, AX
MOV AX, 00H
LEA BX, TAB
MOV DX, P8255MODE
MOV AL, 81H
OUT DX, AL
MAIN:
MOV AL, 11110111B
MOV CX, 4
S1:
MOV DX, P8255A
OUT DX, AL
SHR AL, 1
PUSH AX
PUSH CX
MOV DX, P8255C
IN AL, DX
AND AL, 0FH
CMP AL, 0FH
JZ S2
CALL CHANGE
JZ S3
S3:
CALL SHOW
POP CX
POP AX
CALL DELAY
LOOP S1
JMP MAIN
CHANGE:
OR AX, 0F0H
CMP AL, 11111110B
JZ D1
CMP AL, 11111101B
JZ D2
CMP AL, 11111011B
JZ D3
CMP AL, 11110111B
JZ D4
D1: MOV AL, 04H
JMP D5
D2: MOV AL, 08H
JMP D5
D3: MOV AL, 0CH
JMP D5
D4: MOV AL, 10H
JMP D5
D5: ADD AL, CL
SUB AL, 05H
CMP AL, 0FH ; 按F键退出
JNZ CONTI
MOV AH, 4CH
INT 21H
CONTI:
MOV SI, AX
LEA BX, TAB
MOV AL, [BX+SI]
MOV NUM, AL
CMP TURN, 00H
JZ LEFT
CMP POS, 00000001B ; 已移至最右端
JZ TURNLEFT ; 转向
ROR POS, 1 ; 否则向右移动一步
JMP DFI
TURNLEFT:
MOV TURN, 0 ; 方向改为向左
JMP DFI
LEFT:
CMP POS, 00100000B ; 已移至最左端
JZ TURNRIGHT ; 转向
ROL POS, 1 ; 否则向左移动一步
JMP DFI
TURNRIGHT:
MOV TURN, 1 ; 方向改为向右
DFI:
RET
SHOW:
MOV BL, 01H
MOV AL, 11011111B
MOV SI, 00H
MOV CX, 06H
MC:
MOV DX, P8255A
OUT DX, AL
ROR AL, 1
PUSH AX
MOV DX, P8255B
MOV AL, 00H
CMP BL, POS
JNZ DIS
MOV AL, NUM
DIS:
OUT DX, AL
ROL BL, 1
POP AX
INC SI
CALL DELAY
LOOP MC
RET
DELAY:
PUSH CX
MOV CX, 08FFH
LOOP $
POP CX
RET
CODE ENDS
END START