10.1.5 中断的C51处理过程
51系列单片机对中断的处理分为4步:中断响应、中断处理、中断请求的撤离和中断返回。下面分别介绍这4个过程。
1.中断的响应
中断的响应是指在单片机主程序运行过程中,如果遇到中断请求,在满足中断响应条件的情况下,CPU对该中断做出的响应。一般来说,单片机对中断的响应遵循如下几个原则。
❑为了允许某个中断源的中断请求,应置相应的中断允许位(PX0、PX1、PT0、PT1、PS)为1。另外,在程序中应置中断允许总控制位EA=1,即允许所有中断源申请中断。这样8051 CPU才可以响应中断请求。
❑如果高优先级中断发生的时候,某个低优先级的中断请求正在执行处理程序,则需要中断该服务程序,然后执行本次高优先级中断请求。如果一个高优先级或同优先级的中断请求正在执行,则当前中断请求不会立即执行。
❑如果遇到多个同优先级的中断请求同时发出,则8051 CPU按照一定的查询次序来决定中断执行的顺序。查询次序为“外部中断0→定时器/计数器T0→外部中断1→定时器/计数器T1→串行接口中断”。该查询次序相当于中断源入口地址的顺序。
❑如果单片机CPU正在执行指令,在指令未完成前,任何中断请求都不会响应。
❑如果程序正在执行读写特殊功能寄存器IE和IP,则执行完该指令后,需要再执行一条其他指令才可以响应中断。
❑如果程序正在执行返回指令,则执行完该指令后,需要再执行一条其他指令才可以响应中断。
当一个中断请求满足中断响应条件后,8051 CPU便可以响应该中断请求。中断请求响应的执行,需要经过如下几个步骤。
(1)8051 CPU响应中断,硬件自动将当前的断点地址压入堆栈。
(2)8051 CPU将相应的中断入口地址装入程序计数器PC中。
(3)程序转向相应中断源的入口地址,开始执行中断服务例程。
(4)对于部分中断源,进入中断服务例程后,硬件将自动清零中断标志位,以便于响应下一次中断请求。
8051单片机为每个中断源分配一个入口地址,如下表所示。从表中可以看出,两个相邻的中断源入口地址很接近。实际程序设计中,一般都是将一个跳转指令放置在该处。当中断响应的时候,首先执行这个跳转指令,转向相应的中断服务子程序中处理。
单片机CPU对中断的响应是需要一定时间的,即不是立刻进入真正的中断服务例程。中断的响应时间,即C P U从检查中断请求标志位(TCON或SCON),到转向对应的中断入口地址所需的机器周期个数。对于实时性要求比较高的应用场合,需要严格考虑中断的响应时间。
8051单片机对一个中断请求的正确响应,首先需要查询标志位(占用1个机器周期),然后产生LCALL指令(两个机器周期),转向该中断源的入口地址。因此,一个中断的响应最少需要3个机器周期才能完成。在实际使用时,如果再加上其他用户程序处理或者中断响应条件不满足的场合,可能就需要更多时间。
2.中断的处理
8051单片机CPU对中断处理的过程可以分为两类,一个是单片机硬件自动完成的部分,另一个是C51软件处理的部分。整个中断处理的流程图,如图10.5所示。这里主要介绍的中断处理是指中断的C51软件处理过程。
中断的C51软件处理过程是整个中断服务例程,即从程序计数器PC指向中断源的入口地址开始,到中断结束并返回为止。这个中断服务例程一般需要完成如下4个部分的处理。
图 10.5 中断处理流程图
❑程序跳转
由中断源的入口地址表可以看出,相邻的两个中断源入口地址之间只相隔8个字节,不可能放置下一个完整的中断服务例程。因此,往往将中断服务例程放置在其他的地址空间,而在相应的中断入口地址处放置一个无条件转移指令,将程序转向对应的中断服务例程。在C51语言中更为简单,只需将中断服务例程封装为一个子函数,并用interrupt指名中断号即可,示例如下。
void ISR0(void)interrupt 0//外部中断0服务例程
{
//中断处理语句段
}
本例中,自定义函数ISR0用于处理外部中断0。其中,在函数声明时,用“interrupt 0”指明了为外部中断0。其他中断源的中断号可参阅中断源的入口地址表。
❑关闭中断与打开中断
当中断被正确响应后,如果中断服务例程在执行过程中,不想被更高级的中断打断。则可以在进入中断服务例程后置EA=0,关闭所有中断,或者关闭某些中断,这样可以保证中断服务例程的顺利执行。在中断服务例程结束时,可以将关闭的中断开启,以便于单片机能够接收新的中断请求。
void ISR0(void)interrupt 0//外部中断0服务例程
{
EA=0;//关闭中断
//中断处理语句段
EA=1;//打开中断
}
❑现场保护与恢复现场
一般来说,在主程序和中断服务程序中都会用到累加器和寄存器等。8051 CPU在中断服务例程中使用这些寄存器的时候将会改变其中的内容,再返回主程序的时候容易引起错误。因此,在进入中断服务程序后,应该首先将相应的寄存器保存起来,即保护现场;当中断服务例程结束时,应该将这些寄存器的内容恢复,即现场恢复。在C51语言中,这部分工作由编译环境自动完成。
❑处理中断源请求
中断服务例程主要是为了对特定的中断进行特定的处理。因此,用户还应根据需要编写相应的中断处理请求程序,从而完成特定的任务。
3.中断请求的撤离
中断请求的撤离主要保证对一次中断信号只执行一次中断响应。单片机响应某个中断后,应及时将中断请求标志TCON或SCON中对应的标志位清除,否则会导致一个中断信号触发多次中断响应。
对于外部中断0、外部中断1、定时器/计数器T0和T1来说,在8051 CPU正确响应中断后,将自动清除该中断请求的标志位,无需软件处理。另外,对于外部中断,一般推荐采用沿触发方式,而不采用电平触发方式。因为电平触发方式有可能触发的电平在很长一段时间内都保持,这样容易引起再次触发。如果必须使用电平触发,则应该在硬件或者软件上将输入的触发信号及时翻转过来,以防止同一个中断被响应多次。
对于串行接口的中断请求,当8051 CPU正确响应中断后,硬件不会自动清除中断标志位TI或RI,因此需要在中断服务例程中用软件来人工置零TI或RI。
4.中断的返回
中断的返回是指中断服务例程结束后,返回主程序的过程。在8051单片机中,中断服务例程的返回比较简单,直接在中断服务程序最后面加上一个中断返回指令RETI即可。而如果使用C51语言进行程序设计,则将由编译系统完成此工作。