强烈推荐:感谢b站一位上传教学视频的老师
1实验目的
- 学习使用Proteus仿真接口实验;
- 掌握CPU、接口芯片和外设的连接;
- 掌握汇编语言的编写和调试方法。
2实验内容
- PA口接8个拨动开关K1-K8,PB口接8个LED。初始由开关K1-K8设定8位不同的值,当执行程序后LED按K1-K8初始设定的值点亮,并向右流动。8255工作在0方式。
- 手动产生单脉冲作为中断请求信号连接到MIRQ3上和SIRT10上。每按一次开关产生一次中断,使LED交替点亮和熄灭。
- 8255的PC6作为中断源连接到MIRQ3上,每向8259A发出中断请求,使LED指示等交替点亮和熄灭。中断5次后程序退出。
3实验过程及结果
3.1 8255实验
- 选择元器件
CPU:8086
接口芯片:8255A
译码电路:74LS138 用于选择接口芯片端口
由于proteus中有AD0–AD15部分总线是地址/数据分时复用的,因此需要使用74LS373地址锁存,74LS138作数据驱动,进行地址/数据线的分割。
另外还需要LED灯(LED-YELLOW)、开关(SWITCH)、电阻(RES) - 连线
a) 8086相关连线
8086总线标号;将两片74LS373和两片74LS245连接到总线;转换为16位地址线和16位数据线;使能端连线.
b)连接片选线和8255面向8086的连线
c) 连接开关
8个开关连接到A口,同时连接电阻和电源。注意接线美观。
d) 连接LED灯
注意接线美观;
注意电阻值不宜太大。
e) 完成接线;电路图见附录。
3. 写源程序
右击 8086 芯片,点击EDIT SOURSE CODE,粘贴常规实验中完成的实验源代码。
4. 运行程序,发现达到预期效果。
3.2 8259 主片/从片控制中断
由于Proteus不具备dos中断功能,因此无法完成“在屏幕上显示字符”的任务。因此我将实验内容改为:由单脉冲控制中断,每中断一次,LED灯改变状态。
- 连线
a) 连接CPU。连线方式与8255相同。
b) 连接片选线,需要连接三片芯片。不能漏接。
端口地址分别为:PORTA -0F0H ;PORTB EQU 0F2H;PORTC EQU 0F4H;CTRL EQU 0F6H ;主片0E0H、0E2H;从片: 0E8H、0EAH
c) 连接8255,用于LED灯的显示。其中PA0,PA1由主片IRQ3控制,PB0,PB1由从片IRQ3控制
d)连接8259,分为主片和从片,主片IRQ3控制中断,IRQ2连接从片,从片的IRQ3也连接到一个脉冲信号产生装置button。
2. 编写源程序
最关键的地方在于,Proteus仿真需要编写中断初始化程序:
; 8259 初始化
CLI
; icw1 边缘,多片使用
MOV AL, 00010001B
MOV DX,ICW1
OUT DX,AL
MOV AL, 00010001B ;从片要定义多片?
MOV DX,ICWF1
OUT DX,AL
; ICW2 中断号
MOV AL, 50H
MOV DX,ICW2
OUT DX,AL
MOV AL, 40H
MOV DX,ICWF2
OUT DX,AL
;ICW3
MOV AL,00000100B
MOV DX,ICW3
OUT DX,AL
MOV AL,00000010B
MOV DX,ICWF3
OUT DX,AL
; ICW4
MOV AL, 00000001B
MOV DX,ICW4
OUT DX,AL
MOV AL, 00000101B
MOV DX,ICWF4
OUT DX,AL
; OCW1
MOV AL,11110011B
MOV DX,OCW1
OUT DX,AL
MOV AL,11110111B
MOV DX,OCWF1
OUT DX,AL
这其实是实验中最关键的部分,特别注意从片的定义方法。 在定义中断向量表时,需要注意到第三位为IRQi。在书写中断服务程序时,需要注意关闭中断的方式。
- 调试修改
代码通常需要经过很多次调试才能不出错。 - 实验结果
观察输出信息和LED状态,发现达到了预期效果。
3.3 8255控制8259
这个实验应当在上个实验的基础上进行。通过8255的PC6输出高低电平控制中断,每中断一次LED灯变换一次。
- 连线
8086、片选、LED接法不再赘述,只要将8259的IR3接到PC6即可。
- 编码
编码关键仍是初始化和一些细节。详细代码和注释见附录 - 运行结果
可以观察到小灯闪烁5次。
实验中碰到的问题
- 如何装载程序?
一开始采用的是先用dosbox编译生成.exe文件再装载到8086中,这种方法比较繁琐,我不知道编译了多少exe…;
也可以直接载Proteus中编写程序,但是要安装编译器(系统-编译设置-安装) - 如何连接CPU和8255完成片选?
应用74LS138完成片选。经过多次实验发现,如果选择0FFH以上的端口,即便采用与非门也始终无法成功片选,不知何故。同时如果采用连续端口,流水灯不会流动,不知何故。 - 为什么“流水灯”胡乱点亮,一点都不流水?
因为延时时间设置得比较短(200),所以视觉上流水灯没有按顺序点亮。一开始还以为程序写错了。 - 为什么会出现如下报错?
延时时间设置得太大。
- 为什么出现了这种报错?
可能是堆栈段定义错误,也可能是没能编译执行程序。
在8259第一个实验中,碰到的主要问题有: - 从片的ICW1如何设置?
应设置为00010001B。表示边沿出发,多片使用,要写ICW4。 - 结束中断顺序对运行结果有影响吗?
有影响。应该先结束主片再结束从片。 - 为什么8259的A0要连接A1地址线?
否则就是无法片选成功。似乎和奇偶有关。 - 报错后如何排查错误?
首先检查电路图,确保没有问题之后,大多数报错都是由于代码有问题。比如:[GENERAL] CAS[0…2] disabled [U11] 这个报错,看似是CAS没有连接正确,实则为从片初始化有问题。
其次可以通过运行程序,观察运行信息的办法排错。Proteus运行信息界面忠实记录操作的内容和时间,可以排查程序错误出现在哪个部分。
最后需要注意一些细节错误。比如,子程序要push 和pop用到的寄存器,屏蔽字的定义,数据段定义类型,函数结尾应当RET,正确定义延时函数等等。
在8259-8255实验中,碰到的主要问题有: - 中断正常,但是灯泡不亮。
原因是没有进行第二次初始化!注意8255控制端口既要负责给出PC6信号,也要对PB控制,因此点亮灯泡前必须再次初始化。被这个问题困扰了几个小时。
由此总结另一种排错技巧:可以将点亮LED的代码插入代码段的不同位置,如果运行程序成功点亮,那么点亮之前的代码基本正确。 - 为什么主程序最后必须写上一个无穷循环?
无解,否则程序会出错
5 主要参考资料
- 《微型计算机接口技术及应用》 刘乐善
- 课程ppt
- https://www.bilibili.com/video/BV1fu411r7x1/?spm_id_from=333.788&vd_source=8f5b28d9992a394432507eea910b9456
6 源码和电路图
8255实验
ICW1 EQU 0E0H
ICW2 EQU 0E2H
ICW3 EQU 0E2H
ICW4 EQU 0E2H
OCW1 EQU 0E2H
OCW2 EQU 0E0H
OCW3 EQU 0E0H
LED DB 01011010B
T DW 0AH
DATAS ENDS
EXTRA SEGMENT ; ;附加段
EXTRA ENDS
STACK SEGMENT PARA STACK 'STACK' ;堆栈段
STAPN DB 800H DUP (00H) ;定义100字节空间
TOP EQU LENGTH STAPN
STACK ENDS
CODE SEGMENT
MAIN PROC FAR ;过程定义语句
;说明4个段寄存器分别与哪些段有关
ASSUME CS:CODE, DS:DATAS,ES:EXTRA,SS:STACK
START:MOV AX,DATAS
MOV DS,AX
MOV AX, EXTRA
MOV ES,AX
MOV AX,STACK
MOV SS,AX
; 8255 初始化===========================================
MOV DX,CTRL
MOV AL,90H
OUT DX,AL
; 8259 初始化===========================================
CLI
; icw1
MOV AL, 00010011B
MOV DX,ICW1
OUT DX,AL
; ICW2 中断号
MOV AL, 40H
MOV DX,ICW2
OUT DX,AL
; ICW4
MOV AL, 00000001B
MOV DX,ICW4
OUT DX,AL
; OCW1
MOV AL,11110111B
MOV DX,OCW1
OUT DX,AL
; 设置中断向量表========================================
; IR0
MOV AX,0000H
MOV ES,AX
MOV BX,43H*4
MOV AX,OFFSET IR0
MOV ES:[BX],AX
MOV AX,CS
MOV ES:[BX+2],AX
; 置PC6低位===============================================
MOV DX,CTRL
MOV AL,00001100B
OUT DX,AL
CALL DELAY
MOV CX,T ;中断次数
LLL: STI
MOV DX,CTRL
MOV AL,00001101B ;高电平,触发中断
OUT DX,AL
CALL DELAY
;此处应有中断
MOV DX,CTRL
MOV AL,00001100B
OUT DX,AL
CALL DELAY
DEC CX
CMP CX,0
JNZ LLL
L1:
JMP L1 ;咱也不知道为啥,反正不加就报错
RET
MAIN ENDP ;MAIN过程结束
;延时子程序===================================
DELAY PROC
PUSH CX
MOV CX,5555H
LP: DEC CX
CMP CX,0
JNZ LP
POP CX
RET
DELAY ENDP
;中断服务程序=================================================
IR0 PROC
CLI
PUSH DX
PUSH AX
;重要,,重新给命令字点亮灯泡
MOV DX,CTRL
MOV AL,90H
OUT DX,AL
MOV AL,LED
NOT AL
MOV LED,AL
MOV DX,PORTB
OUT DX,AL
CALL DELAY
; 写OCW2 结束中断
MOV DX,OCW2
MOV AL, 00100000B
OUT DX,AL
POP AX
POP DX
STI
IRET
IR0 ENDP
CODE ENDS ;代码段结束
END MAIN ;整个源代码结束