该实验的目的在于让学生掌握8255A和微机接口的连接方法,了解8255A的基本的工作原理和编程方法。
PA口接8个拨动开关K1-K8,PB口接8个LED。初始由开关K1-K8设定8位不同的值,当执行程序后LED按K1-K8初始设定的值点亮,并向右流动(8255A工作在0方式)。选择完成在数码管上显示“8255-A”。
LED右流水仅仅取决于第1次开关的位置,一旦LED流水开始, LED流水的次序将不再理睬开关位置的重新变化。
提示:为了使流水显示明显,每个位置应加延时程序。
1、 根据原理图正确连接实验线路(需要连接红线)。
2、 正确理解实验原理。
3、 编写实验程序,并上机调试,观察实验结果。
实验程序及注释
DATA SEGMENT
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA
START:MOV AX,DATA
MOV DS,AX
MOV DX,283H ;命令口地址
MOV AL,98H ;10011000(0方式,输入,输入,0方式,输出,输出)
OUT DX,AL ;送到命令口
MOV DX,281H ;CLEAR PORT B
MOV AL,00H ;清空B口
OUT DX,AL ;送到命令口
WAIT1:MOV DX,280H ;A口
IN AL,DX ;获取当前命令行情况
AND AL, 11111111B ;判断是否有开关已经打开
JZ WAIT1 ;如果没有,继续循环等待
;将获取的A口信息进行调整,因为可能有多个开关被打开之后再运行的程序
MOV CX,08H ;设置最大循环量
MOV BL,01H ;判断开关位置的条件
LP1:MOV DL,AL ;将获取的A口进行调整
AND DL,BL ;判断BL中为1的位置的开关是否打开
JNZ OT ;JNZ说明打开的开关就是当前BL对应的那个,可以跳出循环,开始点亮
SHL BL,1H ;如果不是,将BL逻辑左移一位
LOOP LP1 ;再次循环
OT:MOV AL,DL ;找到对应的
;跑马灯的具体实现部分
LP2:MOV DX,281H ;B口地址
OUT DX,AL ;将命令送到B口
CALL DELAY ;调用延时,放置跑马灯太快观察不到
ROR AL,01H ;循环右移一位,完成跑马灯的要求
JMP LP2 ;继续循环,一直进行上述步骤
;时延部分
DELAY PROC
PUSH BX
PUSH CX
MOV BX,0FFFFH
DL1:MOV CX,0FH ;外层循环
DL2:DEC CX ;内层循环,两层循环的目的是延长时延时间
JNZ DL2
DEC BX
JNZ DL1
POP CX
POP BX
RET
DELAY ENDP
CODE ENDS
END START
实现结果为:如果先打开开关再运行程序,实验箱会自动的从打开开关位置开始,LED依次闪亮,如果没有打开开关运行程序,LED不闪亮,只有打开开关后才会正常进行跑马灯。
在本次的程序中,我们在跑马灯开始进行之后再对开关进行操作的时候是不会对LED的闪亮造成影响,因为程序中关于点亮LED灯的部分是一个无限的循环。
老师在实验的时候提出的思考为,在跑马灯的过程中,再打开一个开关,让下一个时间的跑马灯从这个开关对应的LED灯开始。
我的解决思路是:要实现这个要求,只需要在点亮LED的死循环中添加一个判定条件即可。在死循环中,设置变量始终记录开关情况,同时在之前开始跑马灯时候的A口数据也通过变量保存下来,在每一次循环中都进行一次比较,如果相等,说明没有发生变化,正常进行循环,如果不相等,说明发生变化,直接跳转到之前程序中的LP1即可。
补充实验 在数码管上显示“8255-A”
实验程序及注释:
code segment ;初始化代码段
assume cs:code
start: ;初始化,设置A口B口工作方式
mov dx,293h ;送入命令口地址
mov al,10001001b ;传入命令字
out dx,al
;显示A口输入的数并循环移位
xor ax,ax
mov bl,0
lop:
mov dx,292h
in al,dx
cmp al,ah
jz next
mov ah,al
mov bl,ah
rol bl,1
next:
ror bl,1
mov al,bl
mov dx,291h
out dx,al
mov cx,3fffh
;显示8255-A
doit:
;显示8
mov dx,291h
mov al,00000000b
out dx,al
mov dx,290h
mov al,7fh;数字8所对应的段码
out dx,al
mov dx,291h
mov al,00100000b
out dx,al
call DELAY ;延时程序,防止数字跳转过快,便于观察
;显示2
mov dx,291h
mov al,00000000b
out dx,al
mov dx,290h
mov al,5bh;数字2所对应的段码
out dx,al
mov dx,291h
mov al,00010000b
out dx,al
call DELAY
;显示5
mov dx,291h
mov al,00000000b
out dx,al
mov dx,290h
mov al,6dh;数字5所对应的段码
out dx,al
mov dx,291h
mov al,00001000b
out dx,al
call DELAY
;显示5
mov dx,291h
mov al,00000000b
out dx,al
mov dx,290h
mov al,6dh;数字5所对应的段码
out dx,al
mov dx,291h
mov al,00000100b
out dx,al
call DELAY
;显示-
mov dx,291h
mov al,00000000b
out dx,al
mov dx,290h
mov al,40h;数字-所对应的段码
out dx,al
mov dx,291h
mov al,00000010b
out dx,al
call DELAY
;显示A
mov dx,291h
mov al,00000000b
out dx,al
mov dx,290h
mov al,77h;数字A所对应的段码
out dx,al
mov dx,291h
mov al,00000001b
out dx,al
call DELAY
loop doit
jmp lop
;延时程序
DELAY PROC
PUSH BX
PUSH CX
MOV BX,0FFFFH
DL1:MOV CX,06FH
DL2:DEC CX
JNZ DL2
DEC BX
JNZ DL1
POP CX
POP BX
RET
DELAY ENDP
code ends
end start
实验结果:
程序开始后,LED数码管上流水线式循环显示8255-A,每一位显示延时较长,确保能够看清。已经给老师检查过
思考题:
本实验也可以使用C口,将我原本的程序中的291H改为292H并将相关连线改到C口即可。或者通过复位/置位命令字对C端口的每一位进行置位。