一个完整的中断过程由中断请求、中断判优及屏蔽、中断响应、中断处理及中断返回五个部分组成。
在8086/8088微机系统中,中断源的优先权由高到低的顺序依次为:除零数、INT n、INT o、NMI(非屏蔽中断)、INTR、单步执行中断.
8259A芯片的外部特征:
(1)片选取信号(CS)
(2)写信号(WR)
(3)读信号(RD)
(4)D0~D7:8条数据总线
(5)GND:地信号
(6)Vcc:+5V电源
(7)INT:中断请求信号
(8)中断响应信号
(9)IR0~IR7:8个中断请求输入信号
(10)A0:地址选择信号
(11)SP/EN:从片编程/允许缓冲器信号
(12)CAS0~CAS2:这三条信号是8259A级连时构成8259A的主从式级连结构
当CPU完成对8259A的初始化操作后,8259A即进入操作状态,通过INT端口向CPU提出中断申请,8259A从数据总线D7~D0输出当前服务对象的中断类型号N,CPU截获该中断向量并响应该中断,完成一次中断操作。
在IBM PC及其兼容机中,通过CPU的NMI(非屏蔽中断)和两个8259A可编程中断控制器芯片为系统提供了16级中断,硬件中断结构如图1所示1,两片8259A构成主从式级联控制结构,与CPU相连的称为主片,下一层的称为从片,从片中断请求信号INT与主片的IRQ2相连。IBM PC机中保留给用户可随意编程的中断号有IRQ10、IRQ11、IRQ12和IRQ15,这些中断信号都在8259A从片上。
IBM PC机中由8259A管理的16级中断均有规定的中断向量存储地址,主片中IRQ0-IRQ7分别对应08H-0FH,从片中IRQ8-IRQ15分别对应70H-77H(如串口1 对应为0CH(12),用oldvect=getvect(0x0B)保存原来的中断向量)。主片的中断控制寄存器ICR和中断屏蔽寄存器IMR的口地址分别为20H和21H,从片的相应寄存器口地址分别为A0H和A1H。
中断初始化编程时,当用主片中IRQ0-IRQ7时,只须在屏蔽寄存器中打开相应中断,在中断服务程序中,中断结束后,向中断控制寄存器ICR发一次中断结束命令EOI。
普通中断程序
void interrupt(*vect_com)(...);//设置原中断向量保存指针
void interrupt receiver(...)
{
{ch=inportb(0x3f8)};//接收数据语句
outportb(0x21,0x20);//向主片中断屏蔽寄存器0x21发送中断结束命令EOI(0x21);
}
串口1中断初始化时要先保存串口1对应的IRQ4的地址(0x0C)存储的原中断向量,然后将自己的中断服务程序入口地址装入
void SerOpen(void)
{
vect_com=getvect(portf+8);//中断初始化,得到旧的中断向量
disable();
inportb(portaddr+RXD);
inportb(portaddr+MSR);
inportb(portaddr+LSR);
inportb(portaddr+IIR);
outportb(portaddr+IER,IERV);
outportb(portaddr+MCR,OUT2|ERTS|EDTR);
outportb(IMASKREG,inportb(IMASKREG)&(~(1<<portf)));//0x21是主片中断屏蔽寄存器入口地址//作用:打开
/*also
temp=inport(IMASKREG)&(~(1<<portf));//打开主片IRQ4;
outportb(IMASKREG,temp);
*/
setvect(portf+8,receiver);
enable();
};
最后,不要忘记在程序关闭前关中断和恢复原中断向量。
void SerClose(void)
{
disable();
outportb(portaddr+IER,0);//关中断起用寄存器
outportb(portaddr+MCR,0);//关调制解调器控制寄存器
outportb(IMASKREG,inportb(IMASKREG)|(1<<portf));//关主片IRQ4
enable();
setvect(portf+8,vect_com);
};