汇编与接口课程实验3——利用8255A实现LED的流水点亮实验

一、 实验目的

该实验的目的在于让学生掌握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     ;100110000方式,输入,输入,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端口的每一位进行置位。

  • 31
    点赞
  • 204
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
以下是利用汇编语言和接口程序实现8255A的C口连接8只发光二极管,并通过置位控制字循环点亮发光二极管的代码: ```assembly ; 8255A端口定义 port_a equ 0 ; A端口 port_b equ 1 ; B端口 port_c equ 2 ; C端口 ; 控制字定义 mode_reg equ 0 ; 模式寄存器 port_a_ctrl equ 1 ; A端口控制字 port_b_ctrl equ 2 ; B端口控制字 port_c_ctrl equ 3 ; C端口控制字 ; 发光二极管连接的端口 led_port equ port_c ; 控制字循环变量 ctrl_word dw 0x01 ; 初始置位A0 dw 0x02 ; 置位A1 dw 0x04 ; 置位A2 dw 0x08 ; 置位A3 dw 0x10 ; 置位A4 dw 0x20 ; 置位A5 dw 0x40 ; 置位A6 dw 0x80 ; 置位A7 ; 数据段定义 data_seg segment msg db 'Hello, world!', 0 data_seg ends ; 代码段定义 code_seg segment start: ; 初始化8255A mov al, 0b00100010 ; 将控制字写入模式寄存器 out mode_reg, al mov al, 0 ; 将控制字写入A端口控制字 out port_a_ctrl, al mov al, 0 ; 将控制字写入B端口控制字 out port_b_ctrl, al mov al, 0b00001000 ; 将控制字写入C端口控制字 out port_c_ctrl, al ; 点亮发光二极管 mov cx, 8 ; 控制字循环次数 mov si, offset ctrl_word ; 控制字循环变量地址 mov di, led_port ; 发光二极管连接的端口地址 loop1: mov ax, [si] ; 读取控制字 out di, al ; 将控制字写入端口 call delay ; 延时 mov al, 0 ; 将0写入端口 out di, al ; 将0写入端口 add si, 2 ; 控制字循环变量地址加2 loop loop1 ; 循环 ; 程序结束 mov ah, 4ch int 21h ; 延时函数 delay proc push ax push cx mov cx, 0ffffh delay1: loop delay1 pop cx pop ax ret delay endp code_seg ends end start ``` 以上代码实现了将控制字循环写入C口,点亮8只发光二极管,并且通过延时函数来控制发光二极管的闪烁。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值