Skip to content

第八章:中断系统与可编程中断控制器芯片8259A ​

§ 8.1 中断概念 ​

中断 计算机运行过程中,出现某些意外情况需主机干预时,机器能自动停止正在运行的程序并转入处理新情况的程序,处理完毕后又返回原被暂停的程序继续运行,这一个过程被称为中断

中断源 分为外部中断源和内部中断源,谁向CPU提出中断请求,谁就是中断源。其中内部中断源CPU必须响应,NMI引脚提出的外部中断也必须响应,INTR提出的外部中断需要根据IF的值判断是否响应(IF为1响应中断,IF为0不响应中断)

中断类型号 由于外设有很多,中断源也有很多,为了让CPU把这些不同的中断源区分开,我们需要中断类型号用于识别中断源,用N表示,8086对每一个中断源都编了一个中断类型号,用8位2进制编码,所以8086一共可以管理256级中断 除法错中断:0号 单步中断:1号 NMI外部中断:2号 断点中断:3号 溢出中断:4号 INT N:N号 外设可以通过INTR引脚对CPU提出可屏蔽外部中断,该中断的中断类型号不固定,为了把中断类信号传给CPU,我们就需要在外部扩充一个8259芯片来管理这些外部可屏蔽中断源,在使用8259时,我们要把中断类信号通过OUT初始化到8259,当CPU收到中断后就会从8259获取中断类型号,有了中断号,CPU就可以找到中断向量在终端表里的位置,从而去为中断服务子程序服务

中断向量 中断服务子程序的入口地址,由4个字节组成,包含32个二进制位,高16位为16位段地址,低16位为16位偏移地址

中断向量表 为了方便管理这些中断向量方便查询,8086CPU把所有的中断向量放在一起编成了一个中断向量表,8086一共可以管理256个中断源,每一个中断源的中断向量占4个字节,一共就需要1k地址空间来存放这些中断向量,8086CPU把前1k字节设置为中断向量表,即0~1023,或0H~3FFH,这个中段向量表中存放的全是中断向量,我们以0为中断向量表的基地址,将中断类型号乘以4,就可以得到该中断的中断向量在中断向量表中的偏移地址,这里的中断向量的存放规则依然满足低地址存偏移地址,高地址存段地址

中断服务子程序 为中断源服务的程序称为中断服务子程序

中断现场 CPU在执行主程序时,收到必须响应的中断请求,执行完当前指令后,主程序的下一条指令就是中断现场, CPU在响应中断之前,要先把中断现场保护起来,会把PSW,CS,IP依次压栈,在执行完中断服务程序的IRET后(中断服务子程序的最后一条指令一定是IRET),再将IP,CS,PSW依次出栈

中断的响应过程

  • CPU在执行指令的最后一个周期才会去检测中断,所以CPU只会在当前指令执行完后响应
  • 保护现场,PSW,CS,IP依次入栈
  • (外部可屏蔽中断)从8259获取中断类型号N
  • 屏蔽中断,清除IF和TF,如果程序员需要程序在中断请求的途中响应外部可屏蔽中断,需要手动把IF置1
  • 将N乘以4,得到中断向量在中断向量表中的偏移地址,取一个字给IP,再取一个字给CS,转到中断服务子程序

如果允许CPU在执行中断的时候响应更高优先等级发中断,则称为允许中断嵌套

中断优先级:除法错中断 > INT N > INTO溢出中断 > NMI中断 > INTR中断 > 单步中断

§ 8.2 8259的内部结构和工作方式 ​

引脚及功能 ​

xbtc0a6e9d9cae6d36a66decd9a7ad1bb05c

8259采用双列直插式封装,一共有28个引脚

IR0~IR7:中断请求输入引脚 一片8259只有8个中断请求信号,所以一个8259只能管理8个中断源

D0~D7:双向数据引脚

为片选信号,无效时,数据引脚为高阻态,有效时,8个数据引脚处于2态,此时可以通过数据线往8259内部写命令,也可以把8259内部的数据读走

为写控制引脚

为读控制引脚

A0为片内寻址地址线,8259内部有两个端口地址,但并不代表8259内部就只有两个端口,8259内部不止两个端口,但所有端口共用两个IO地址,两个状态显然无法寻址到每一个IO端口,所以8259除了通过A0来寻址端口,还需要一些特征位来识别端口

INT连接INTR,用于发送中断信号 连接8086的,用于接收CPU传回的响应信号,若8086响应中断,会发回两个负脉冲,第一个负脉冲告诉8259可以响应中断,第二个总线周期再发送一个负脉冲,当8259收到第二个负脉冲时,就把对应的中断信号送到数据线

8259的数据线需要和8086的低8位数据线相连

8259可以工作在非缓冲和缓冲两种工作方式 缓冲工作方式:为了防止系统总线负载过重,我们可以在8259和系统总线之间设置一个双向数据缓冲器,例如74LS245,其中74LS245的片选信号需要由引脚来提供,此时为输出引脚 非缓冲工作方式:8259的数据引脚和系统总线低8位直连,此时变为输入引脚,如果该8259的INTR直接和CPU的INTR相连,接+5V,如果该8259为级联工作时的从片,那么应该接GND

xbtcc01bfbcd4dd23ae7669576e2402bdd18

CAS0~CAS2为级联线 主片的 CAS0~CAS2 应该连接从片的 CAS0~CAS2 ,主片做输出,从片做输入。从片连接主片的一个输入端,主片再向CPU请求中断,当CPU响应中断时,只会发送两个负脉冲,并不能识别是哪一个从片发出的中断,当主片收到这两个负脉冲时,通过这三个引脚向从片发出一个信号,告诉从片们是哪一个从片发出的中断被响应了,被响应的从片才能把终端类信号送到数据线上

xbtcdf369bd9a0b7412e6f0508fa70cd1ad3

内部结构 ​

xbtc41e822c3d1b43c9761fe88cd072085f8

中断请求寄存器IRR 直接和8个中断输入端相连,IRR也有8个请求输出,收到1个中断请求后可以锁存到输出端的对应位,输入数据的形式可以通过初始化手动设置,可以设置为高电平有效,也可以设置为上升沿有效,一般设置为上升沿有效

中断屏蔽寄存器IMR 八位寄存器,可以让IRR屏蔽掉某些位的中断请求,IMR的第n位写1,意味着8259屏蔽掉IRn输入的中断请求,当某一位被屏蔽了,IRR就不会接收这一位的数据

优先权分析器 8259一次只能输出一个中断,当同时有多个中断输入时,就要分析哪一个中断的优先级更高,优先权分析器就是用来实现这个功能的,它与IRR输出端相连,接收IRR发出的所有中断请求,并将优先权最高的中断请求输出到ISR

中断服务寄存器ISR 中断服务寄存器是一个8位寄存器,由优先权分析器控制,优先权分析器先把优先级最高的中断请求选出来,假设第n位的优先权最高,那么优先权分析器就把ISR的第n位置1。当ISR有一位置1,表明8259已经对外设服务了,但并不代表CPU也为外设服务,8259需要向CPU请求中断, CPU响应后开始执行中断服务子程序,此时才能说CPU已经对外设服务了,CPU是否可以响应外部可屏蔽中断,受IF控制

中断服务结束方式 中断服务结束方式分为两种,非机动结束和自动结束 自动结束方式中,当8259从#INTA中收到第2个负脉冲时,先把中断类型码输出到总线上,然后自动把ISR清零,结束对外设的中断服务,这种方式一般不用 非自动结束方式:8259不主动结束对外设的服务,需要程序员在IRET返回指令之前向8259发送一个EOI命令,手动将8259的ISR清零,这是常选用的一种

综上 我们知道,CPU是否响应外部可屏蔽中断受两个因素控制, CPU想要响应外部可屏蔽中断,必须保证8259的IMR没有对本位请求进行屏蔽,并且IF置1。

控制逻辑电路 在控制逻辑电路里,有四个ICW寄存器(初始化命令字)和3个OCW寄存器(操作命令字)

§ 8.2 8259的编程 ​

通过操作ICW和OCW,可以实现对8259的编程

初始化编程 ​

对ICW1~ICW4写命令,可以实现初始化编程

首先注意ICW和OCW是从1开始的,不是从0开始的

初始化编程流程: xbtcbca79832d81cc1d0481c41a4dac0104f

ICW1: 初始化ICW1,需要先把ICW选中,保证A0=0 ICW1有D0~D7一共8位,其中D5,D6,D7这三位没用 D4位为特征位,必须写1,当A0=0且D4位为1时,8259才知道这是在对ICW1操作 D3位控制中断请求的有效类型,如果写0,说明中断请求信号的有效类型为上升沿有效,如果写1,说明中断请求的有效类型为高电平有效,在IBMPC机中,此位为0 D2位在8086系统中没有用,这一位在8085系统中才有实际作用 D1位可以反映工作状态,D1为0表示级联工作,D1为1表示单片工作,如果是级联工作,初始化ICW1后还需要初始化ICW3。如果是单片工作,不用初始化ICW3 D0位固定为1,该位写1表示要初始化ICW4,如果写0就不用初始化ICW4,但我们都要初始化ICW4,所以本位固定写1

nasm
;主片
MOV AL,11H;级联工作,上升沿有效
OUT 20H,AL;20H没有超过255
;从片
MOV AL,11H
OUT 0A0H,AL

ICW2: 保证A0=1,并且要在初始化ICW1后立即初始化ICW2,才能选中本端口,在这里8259根据初始化顺序来识别本端口 向ICW2里写命令字,可以初始化主片8259的基地址(IR0的中断类型号),对IR0的中断类型号初始化之后,IR1~IR7的中断会递增自动设置 D3~D7位写中断类型码的高5位,D0~D2可以理解为全写0

nasm
;主片
MOV AL,08H
OUT 21H,AL;保证A0为1,由此可见,8259的A0需要和CPU的A0相连
;从片
MOV AL,70H
OUT A1H,AL

ICW3: A0=1,并且必须要在初始化ICW2后立即初始化,这里也是根据顺序来判断 在单片工作时不需要ICW3,只有在级联工作时才需要设置ICW3,8位寄存器,如果是主片,就通过ICW3告诉主片哪个输入端被级联了。如果是从片,就通过ICW3告诉从片他级联在主片的哪一个输入口了。对于主片而言,最多级联8个8259,所以主片的第n位被级联了,就对第n位写1,对于从片而言,只能级联在一个主片上,最多只有8个信号,所以从片ICW3的D3~D7是没有用的,通过D2~D0来识别从片被级联到主片的哪一个输入端

nasm
;主片
MOV AL,04H
OUT 21H,AL
;从片
MOV AL,02H
OUT 0A1H,AL

ICW4: 保证A0=1 A5,A6,A7是特征位,如果这三位都是0,且A0为1,选中ICW4 D4为设置嵌套方式,D4为0就是正常嵌套方式,即固定优先级。D4如果为1,就是特殊嵌套方式,。一般都用正常嵌套方式 D0位写1 D1位选择中断结束方式,写0表示非自动中断结束,写1表示自动中断结束,一般选用非自动的结束方式,需要在IRET前对OCW2写EOI中断结束命令 D3为设置缓冲方式,一般用非缓冲工作方式,写0 D2位只有在D3为1时有效,设置该8259是从片还是主片,主片写0,从片写1,一般来说这一位我们都填0

nasm
;主片
MOV AL,01H
OUT 21H,AL
;从片
MOV AL,01H
OUT 21H,AL

操作命令字 ​

初始化命令字是在8259工作前进行的,而操作命令字是可以在8259工作中进行操作的。

OCW1: 保证A0=1 给OCW1写命令,等价于给IMR(中断屏蔽寄存器)写命令 同样,也可以读出来,即IN AL,21H OCW1和IMR实际上是保持一种实时同步的关系

OCW2: 保证A0=0 向D5位写1,就是通知8259结束正在服务的中断,很显然,这个操作必须在非自动结束方式下才有意义,并且这个操作必须要在IRET指令之前完成,其他位的内容感兴趣自修

OCW3: OCW3可以改变8259的屏蔽方式,但在正常嵌套方式下没有用,所以不细说 A0=0

到这里可以看出8259内部的端口其实有很多,这么多的端口,共享了两个端口地址,8259需要把对这么多端口区分开,A0的状态可以区分一次,写入的8位数据的特征位可以区分一次,8259就可以把不同的端口区分开,所以8259是通过地址和特征位结合的方式来对内部端口寻址

主片8259分配的端口地址为20H和21H,从片8259分配的端口地址为A0H和A1H,系统初始化时,对主片8259中断类型号的基址默认初始化为08H,对从片8259的中断类型号的基址初始化为70H

image-20210406185751485image-20210406185816130image-20210406185825108image-20210406185837834image-20210406185849819image-20210406185900625

以笔记为镜,可以知得失