微机实验二之 8259中断控制实验

实验内容

 

1、利用系统总线上中断请求信号MIR7 ,设计一个单一中断请求实验。
2、利用系统总线上中断请求信号MIR6和MIR7,设计一个双中断优先级应用实验,观察8259对中        断优先级的控制。
3、利用系统总线上中断请求信号MIR7和SIR1,设计一个级连中断应用实验。

中断控制器8259简介

        在Intel 386EX芯片中集成有中断控制单元,该单元包含有两个级联中断控制器,一个为主控制器,一个为从控制器。该中断控制单元就功能而言与工业上标准的82C59A是一致的,操作方法也相同。从片的INT连接到主片的IR2信号上构成两片8259的级联。本实验中,将主控制器的IR6、IR7以及从控制器的IR1开放出来供实验使用,主片8259的IR4供系统串口使用。8259的内部连接及外部管脚引出如下图:

微机实验二之 8259中断控制实验_第1张图片

8259A工作逻辑

在总线控制器控制下,8259A芯片可以处于编程状态和操作状态。编程状态通过CPU的IN或OUT指令对8259A芯片进行初始化编程。完成初始化编程后,芯片即可进入操作状态,此时芯片即可随时响应外部设备提出的中断请求(IRQ0 -IRQ15),同时系统还可以使用操作命令字随时修改其中断处理方式。通过中断判优选择,芯片将选中当前最高优先级的中断请求作为中断服务对象,并通过CPU引脚INT通知CPU中断请求的到来,CPU响应后,芯片从数据总线D7-D0将编程设定的当前服务对象的中断号送出,CPU由此获取对应的中断向量值,并执行中断服务程序。逻辑图如下:

微机实验二之 8259中断控制实验_第2张图片

(图有亿点点丑,别介意,只要能看清就ok)

下面列出本实验会用到的中断控制单元寄存器列表(它们都是8位的)

寄存器 口地址 功能描述

ICW1(主)

ICW1(从)

(只写)

0020H

00A0H

初始化命令字1
决定中断请求信号为电平触发还是边沿触发。

ICW2(主)

ICW2(从)

(只写)

0021H

00A1H

初始化命令字2
包含了8259的基址中断向量号,基址中断向量是IRO的向量号,基址加1就是
IR1的向量号,依此类推。

ICW3(主)

(只写)

0021H

初始化命令字3:
用于识别从8259设备连接到主控制器的IR信号,内部的从8259连接到主8259
的IR2信号上。

ICW3(从)

(只写)

00A1H 初始化命令字3
表明内部从控制器级联到主片的IR2信号上。

ICW4(主)

ICW4(从)

(只写)

0021H

00A1H

初始化命令字4
选择特殊全嵌套或全嵌套模式,使能中断自动结束方式。

OCW1(主)

OCW1(从)

(只写)

0021H

00A1H

操作命令字1
中断屏蔽操作寄存器,可屏蔽相应的中断信号。

OCW2(主)

OCW2(从)

(只写)

0020H

00A0H

操作命令字2
改变中断优先级和发送中断结束命令。

想问下,一路看下来的你,头大没有qwq

在这里插入图片描述

其实不用挨着看完,看完然后,就会忘了前面是啥。我们用到哪个寄存器就去查看它的作用。

到这里,或许你会问,这些寄存器咋个赋值,如何才能使用中断,我们下面继续。

初始化命令字

在8259A工作之前,首先设置初始化命令字 ICW 寄存器组。而工作中,可以使用写入操作命令字 OCW 寄存器组来随时设置和管理8259A的工作方式。

1、ICW1设置(对于本实验,都设置为11H,即0001 0001)

微机实验二之 8259中断控制实验_第3张图片

2、ICW2设置

这里先需要一张中断矢量地址与中断号的对应表

主片中断序号 0 1 2 3 4 5 6 7
矢量地址 20H - 23H 24H - 27H 28H - 2BH 2CH - 2FH 30H - 33H 34H - 37H 38H - 3BH 3CH -3FH
从片中断序号 0 1 2 3 4 5 6 7
矢量地址 C0H - C3H C4H - C7H C8H - CBH CCH - CFH D0H - D3H D4H - D7H D8H - DBH DCH - DFH

此处引出一个公式:中断向量地址 = 中断向量类型号*4。这个中断向量类型号就是要设置的ICW2,但不完全是。下图是ICW2的格式,后三位一般设置为0,会由8259自动按照IRQ0-IRQ7填入。

微机实验二之 8259中断控制实验_第4张图片

好了,那么该如何设置ICW2捏,那么根据上面的红色公式和矢量地址与中断号表格,先算出中断向量号类型码,即中断向量地址除以4,即右移两位,然后把后三位置0就好了。

3、ICW3设置

  下图是主片的ICW3设置(本实验设置为0000 0100)

微机实验二之 8259中断控制实验_第5张图片

  下图是从片的ICW3设置(本实验这样设置)

4、ICW4设置(下图是ICW4格式,本实验直接设置为0000 0001)

这里写图片描述

5、OCW1设置

      OCW18位,为1则表示相应的位对应的IRi中断被屏蔽,为0则不屏蔽。

6、ICW2设置(本实验设置为0010 0000)

      这里写图片描述

终于介绍完相关寄存器的配置了,下面上代码,qwq

第一个小实验,外部会给主片的IR7脉冲信号,产生中断,由于各个学校实验不同,本实验是按下按键,给主片的IR7一个脉冲,然后产生中断,显示字符“7”。代码步骤,先把服务中断程序的入口地址填入中断矢量表,然后配置8259A的相关寄存器,最后编写显示字符7的程序。

SSTACK	SEGMENT STACK
		DW 32 DUP(?)
SSTACK	ENDS

CODE   	SEGMENT
	   	ASSUME CS:CODE

START: 	PUSH DS
		MOV AX, 0000H
		MOV DS, AX
		MOV AX, OFFSET MIR7		; 取中断程序入口地址
		MOV SI, 003CH			; 中断矢量地址
		MOV [SI], AX			; 填IRQ7的偏移矢量
		MOV AX, CS			    ; 段地址
		MOV SI, 003EH
		MOV [SI], AX			; 填IRQ7的段地址矢量
		CLI                     ; 配置好相关寄存器之前,先禁止中断发生
		POP DS
		; 上面这段,是往中断向量表填入中断服务程序的入口地址,先取我们自己编写的中断服务程序的偏            
        ; 移地址,填到AX,然后再把AX里的值写入DS:SI对应地址里,因为第1个实验利用MIR7,所以查表            
        ; 对应主片中断序号7所对应的矢量地址为3CH-3FH。这里写了两次,一次往3CH,一次往3EH,下面 
        ; 会详细介绍,为什么这样写。

		; 初始化主片8259相关寄存器
		MOV AL, 11H
		OUT 20H, AL				; ICW1,边沿触发 
		MOV AL, 08H
		OUT 21H, AL				; ICW2,低三位根据设置的IR自动填入 0000 1000
		MOV AL, 04H
		OUT 21H, AL				; ICW3,从芯片连接到主芯片的IR2信号上

		MOV AL, 01H
		OUT 21H, AL				; ICW4

		MOV AL, 6FH				; OCW 10110 1111 开放4号中断串口用,7号中断实验用
		OUT 21H, AL
		STI                     ; 允许中断发生

AA1:	NOP                                                                       
		JMP AA1		            ; 等待中断信号

MIR7:	STI
		CALL DELAY              ; 延时
		MOV AX, 0137H
		INT 10H					; 显示字符7,ASCII为56 = 7 + 3*16 ->al
		MOV AX, 0120H           ; 空格,ASCII为32 = 16*2
		INT 10H                 ; 调用8086系统10号中断显示字符,把AL的值对应的ASCII显示出来
		MOV AL, 20H
		OUT 20H, AL				; OCW2,发送中断结束命令
		IRET					; iret  interrupt return中断返回指令	         
	
DELAY:	PUSH CX
		MOV CX, 0F00H
AA0:	PUSH  AX
		POP   AX
		LOOP AA0                ; 循环0F00H次,相当于延时
		POP  CX
		RET	                    ; 函数返回
CODE	ENDS
		END  START

  小实验1的代码给出来了,下面对一些问题做解释。先给一些概念作解释。

中断向量:即中断服务子程序的入口逻辑地址,由两部分组成:服务程序的段基址CS(2字节)和服务程序的偏移地址IP(2字节)。

中断向量表:存放中断向量的一个特定的内存区域,位于整个内存区域的最低端,物理地址范围从00000H~003FFH(一个中断向量占4字节的空间,因此256个中断一共需要1K字节的空间)。共256个中断,中断类型号从0~255。

中断向量地址 = 中断类型号*4(即可找到中断向量地址,前两位送给偏移量后两位送给段基址)

把服务中断程序的入口地址填入中断矢量表这里,为什么填两次。首先,8086是16位的,那么寄存器就是16位的,包括CS和IP,机器执行程序时,会把段地址给CS,偏移地址给IP,所以,想要让机器停下来它正在做的事,执行我们写好的中断服务程序,就必须把中断服务程序的段地址和偏移地址放到一个地方(中断矢量表),机器会自动去取,所以要填两次,而且是填偶地址。如下图。

微机实验二之 8259中断控制实验_第6张图片

对于显示程序就简单了,调用系统自带的10号中断,提前把字符7的ASCII码填入AL就可以了。

第二个小实验,外部会给主片的IR6、主片的IR7脉冲信号,产生中断,由于各个学校实验不同,本实验是按下按键,给主片的IR6或主片的IR7一个脉冲,然后产生中断,显示字符“6”或“7”。代码步骤,和第一个小实验相同,只是配置中断矢量表多了一个,其余就是OCW2发生相应的变化。直接给出代码。

SSTACK	SEGMENT STACK
		DW 32 DUP(?)
SSTACK	ENDS

CODE   	SEGMENT
	   	ASSUME CS:CODE

START: 	PUSH DS
		MOV AX, 0000H
		MOV DS, AX
		MOV AX, OFFSET MIR7		; 取中断服务程序显示字符7的入口地址
		MOV SI, 003CH			
		MOV [SI], AX			; 填IRQ7的偏移矢量
		MOV AX, CS			    ; 段地址
		MOV SI, 003EH
		MOV [SI], AX			; 填IRQ7的段地址矢量

		MOV AX, OFFSET MIR6     ; 取中断服务程序显示字符6的入口地址
		MOV SI, 0038H
		MOV [SI], AX            ; 填IRQ6的偏移矢量
		MOV AX, CS
		MOV SI, 003AH
		MOV [SI], AX
		CLI
		POP DS

		;初始化主片8259
		MOV AL, 11H
		OUT 20H, AL				; ICW1,边沿触发
		MOV AL, 08H
		OUT 21H, AL				; ICW2
		MOV AL, 04H
		OUT 21H, AL				; ICW3,从芯片连接到主芯片的IR2信号上
		MOV AL, 01H
		OUT 21H, AL				; ICW4
		MOV AL, 2FH
		OUT 21H, AL				; OCW1  0010 1111   开放4号中断串口用,6、7号中断实验用
		STI					    ; 允许中断发生

AA1:	NOP
		JMP AA1                 ; 一直等待中断信号

MIR7:	STI					    ; 允许中断发生
		CALL DELAY
		MOV AX, 0137H
		INT 10H					; 显示字符7
		MOV AX, 0120H
		INT 10H
		MOV AL, 20H
		OUT 20H, AL				; 中断结束命令
		IRET                    ; iret  interrupt return中断返回指令

MIR6:	STI					    ; 允许中断发生
		CALL DELAY
		MOV AX, 0136H
		INT 10H					; 显示字符6
		MOV AX, 0120H
		INT 10H
		MOV AL, 20H
		OUT 20H, AL
		IRET					; iret  interrupt return中断返回指令

DELAY:	PUSH CX
		MOV CX, 0F000H
AA0:	PUSH AX
		POP  AX
		LOOP AA0                ; 循环0F00H次,延时
		POP CX
		RET					    ; 函数返回

CODE	ENDS
		END  START

第三个小实验,外部会给从片的IR6、主片的IR7脉冲信号,且产生中断,从片连接到主片的IR2上。由于各个学校实验不同,本实验是按下按键,给IR6或IR7一个脉冲,然后产生中断,显示字符“S1”或“M7”。代码步骤,和第二个小实验相同,只是配置中断矢量表多了一个,其余就是OCW2发生相应的变化。直接给出代码。

SSTACK	SEGMENT STACK
		DW 32 DUP(?)
SSTACK	ENDS

CODE   	SEGMENT
	   	ASSUME CS:CODE

START: 	PUSH DS
		MOV AX, 0000H
		MOV DS, AX
		MOV AX, OFFSET MIR7		; 取中断入口地址
		MOV SI, 003CH			; 中断矢量地址
		MOV [SI], AX			; 填IRQ7的偏移矢量
		MOV AX, CS			    ; 段地址
		MOV SI, 003EH
		MOV [SI], AX			; 填IRQ7的段地址矢量
		
		MOV AX, OFFSET SIR1
		MOV SI, 00C4H
		MOV [SI], AX			; 从芯片偏移地址送入中断矢量地址
		MOV AX, CS
		MOV SI, 00C6H
		MOV [SI], AX            ; 从芯片的基地址
		CLI
		POP DS

		;初始化主片8259
		MOV AL, 11H
		OUT 20H, AL				; ICW1

		MOV AL, 08H				; ICW2,低三位根据设置的IR自动填入
		OUT 21H, AL				; ICW2

		MOV AL, 04H
		OUT 21H, AL				; ICW3,从芯片连接到主芯片的IR2信号上

		MOV AL, 01H
		OUT 21H, AL				; ICW4,设置嵌套方式为默认

		;初始化从片8259
		MOV AL, 11H
		OUT 0A0H, AL			; ICW1,边沿触发

		MOV AL, 30H                               
		OUT 0A1H, AL			; ICW2,低三位根据设置的IR自动填入 矢量地址=类型码*4

		MOV AL, 02H				
		OUT 0A1H, AL			; ICW3,从芯片选择的是IR1,即0010

		MOV AL, 01H
		OUT 0A1H, AL			; ICW4,设置嵌套方式为默认

		MOV AL, 0FDH
		OUT 0A1H,AL			    ; OCW1 = 1111 1101	,从芯片的1号不屏蔽,其余屏蔽	

		MOV AL, 6BH
		OUT 21H, AL			    ; 主8259 OCW1  01101011  IR2、IR7不屏蔽,IR4用于串口
		STI				        ; 允许中断发生

AA1:	NOP
		JMP AA1

MIR7:	STI
		CALL DELAY
		MOV AX, 014DH
		INT 10H					; 显示字符M
		MOV AX, 0137H
		INT 10H					; 显示字符7
		MOV AX, 0120H
		INT 10H                 ; 空格
		MOV AL, 20H
		OUT 20H, AL				; OCW2,中断结束命令
		IRET

SIR1:	STI
		CALL DELAY
		MOV AX, 0153H
		INT 10H					; 显示字符S
		MOV AX, 0131H
		INT 10H					; 显示字符1
		MOV AX, 0120H
		INT 10H                 ; 空格
		MOV AL, 20H
		OUT 0A0H, AL
		OUT 20H, AL             ; OCW2, 中断结束命令
		IRET

DELAY:	PUSH CX
		MOV CX, 0F00H
AA0:	PUSH AX
		POP  AX
		LOOP AA0
		POP CX
		RET

CODE	ENDS
		END  START

最后,附上我学习中遇到的问题,不知道看完的你有没有这样的困惑。就是在对8259A进行编程时,如何识别4条ICW命令和3条0CW命令。

(1)首先看命令是被送入奇地址端口还是偶地址端口,若被送入偶地址端口可能是命令
字ICW、0CW或0CW2;若被送入奇地址端口可能是命令字ICW2、 ICWs、 ICW.或 OCW.。
(2)当端口地址为偶地址时,命令字ICW.、0CW2、 0CW 的区分方法如下:
A、当命令字的D4=1时,为ICW1
B、当命令字的D4D3=00时,为0CW2
C、当命令字的D4D3=01时,为0CWs
(3)当端口地址为奇地址时,命令字ICW2、 ICW3、 ICW4、0CW1的区分方法如下:
A、若前一个命令字为ICW1, 则该命令字必为ICW2, 因为初始化命令字必须按照一定的
顺序输入,并且ICW1、ICW2 是必须输入的。
B、ICW2后的命令字是否为ICW3,由ICW1的D1位决定。若D1=0,则此后必为ICW2; 否则
没有ICW3。
C、此后是否为ICW4, 由ICW1的D0位决定。若D0=1, 则此后必为ICW4; 否则没有ICW4。
D、若不是以上三者,则必为0CW1。

好了,估计你也看累了,感谢阅读,若有错误或疑问,请欢迎评论私信,最后附上参考的一个博客,总结非常详细,关于8259A的相关寄存器配置。同时,感谢该博主的分享。详解8259A_车子(chezi)-CSDN博客_8259

你可能感兴趣的:(微机原理实验,其他)