中断系统是计算机或者单片机的主要功能部件。
有了中断系统,便可以使微处理器具备对外部的异步事件进行处理的能力。
当微处理器的CPU正在执行程序的过程中,如果外部硬件或者内部组件有紧急的请求(如通信,断点,发生重大故障等),中断系统就可以将当前的程序暂停,优先处理这些中断请求。
这种处理方式,对整个系统的稳定性,健壮性至关重要,同时也能大大提高处理器的效率,使得系统的应用更加灵活多变。
中断的概念
中断是指单片机在执行程序的过程中,当出现异常情况或特殊请求时,单片机停止当前程序的运行,转向对这些异常情况或特殊请求进行处理,当处理结束后再返回原程序的间断处,继续执行原程序,这一现象称为中断。
中断是单片机实时处理内部或外部事件的一种内部机制。
原来正在执行的程序称为主程序;用来处理突变事件或故障的程序称为中断服务子程序;导致中断产生的原因称为中断源;主程序被中断源打断,转去执行中断服务子程序的位置称为断点。
中断的作用
中断不只是51系列单片机所特有的,目前基本所有的微处理器均具备完善的中断系统。
中断系统是一个非常实用的微处理器组件,合理地使用中断技术,可以极大地提高单片机的工作效率和实时性。其主要作用体现在下面两个方面。
1)对外部信号的实时处理
在基于单片机的应用系统中,单片机作为整个系统的控制和处理中心,它和外围设备的信息交换非常频繁,这种信息交换一般采用两种工作方式,一种是查询方式,另外一种为中断方式。
2)故障处理
在单片机系统运行过程中,会有很多无法预测的故障或错误产生,例如掉电,计算溢出等。
在产生掉电故障时,会立即执行相应的中断处理,保护重要的系统参数,以便后续的系统恢复。
当发生错误时,也会有相应的中断处理子程序运行,自动修改算法参数并发出警告。这些都采用的是中断处理方式。
中断源的分类
从中断执行的角度来看,可以分为两类。
1)处理器预先考虑的中断
这些中断的处理是处理器在设计之初就进行考虑了的。如除零中断,溢出中断,掉电中断,集成的接口电路中断。
这类中断是我们常见的一类中断,几乎所有的微处理器都预先定义了这类中断。此类中断发生之后,硬件可以快速地找到相应的中断服务子程序去执行相应的处理。
2)处理器没有预先考虑而需要扩展的中断
这里中断通常与实际的应用有关,同时,微处理器的中断资源也是有限的,当中断资源不够用时,就需要扩展不同的中断。
简单中断的处理过程
当有中断产生时,处理器在执行完当前的指令后,如果允许响应中断的条件满足,处理器就会转向中断服务子程序,中断系统会自动保存断点,当执行完中断服务子程序后,再返回断点处继续执行原程序。
为了更好了解这个过程,把这个过程分成如下几个步骤。
1)中断源识别和中断入口地址查找
当处理器收到中断请求,并允许响应时,首先要做的就是识别中断源,判断是哪个中断源发出的中断请求,然后根据中断源找到相应的中断入口地址。
如何找到中断入口地址,不同的处理器有不同的处理方法,如在80X86系列处理器中,中断源的识别和中断入口地址查找是按中断源的类别分别处理的,过程较为复杂。
但51单片机这个过程被大大简化了,51系列基本型单片机只有5个中断源,这5个中断源的中断程序入口地址是固定的。
2)断点保护
在处理器找到中断程序的入口地址后,就会暂停主程序的执行,转去执行终端服务子程序。
为了在执行完成中断服务子程序后,能够返回原程序断点处接着执行,就需要记忆断点的位置。
断点就是中断返回后将要执行的指令的地址,保护断点就是保护断点地址,中断发生时,CPU硬件自动把这个地址值压入堆栈,当执行完成中断子程序后,通过RETI指令,再把这个地址值从堆栈中弹出送给PC,从而实现中断返回。
3)执行中断服务子程序
中断服务子程序是中断的主题。程序的具体内容由用户编程决定,不同的中断在不同的应用场合下,子程序的内容是不同的。
中断发生后,在主程序执行时,很多计算的中间结果都是使用内部寄存器来保存的,在主程序和中断服务子程序中很可能会用到同一个寄存器,比如我们最常用的累加器ACC等。
因此在中断子程序开始之前,需要把这些公用寄存器的内容进行保护,这就是保护现场。保护现场和保护断点十分类似,所不同的是,保护断点是硬件自动完成的,而保护现场则需要用户编写程序实现。
其中保护现场除了利用堆栈来进行保护外,还有一种比较有效的方法就是切换工作寄存器组。
我们已经知道80C51有4组工作寄存器组,当中断发生后,在执行子程序之前,可以先切换到同主程序不同的工作寄存器组,在中断子程序执行完成之后,再切换主程序使用的工作寄存器组。
4)中断返回
执行完成中断服务子程序之后,返回断点处继续执行主程序。在80C51单片机中,就是执行RETI指令,这时,前面保护的断点就会从堆栈中弹出,送入程序计数器PC,继续主程序的执行。
复杂中断的执行
在实际的应用系统中,往往有多个中断源同时向处理器申请中断,也有可能中断产生时,处理器正在执行的就是某个其他中断服务子程序,那么在这些情况下CPU该如何处理呢?
1)中断优先级
当多个中断源同时提出中断申请时,处理器先处理哪个?
为此提出了中断优先级的概念,给每个中断源赋予不同的优先级,在同一时刻,有多个中断请求时,中断系统按照中断源优先级的高低逐次响应,即优先级高的中断优先处理,处理完毕后,再处理优先级低的中断。
2)中断嵌套
如果处理器正在处理一个中断,这时又有一个中断产生了,那么,处理器是否响应新的中断?
这时有两种处理方法。一种方法是处理器不响应新的中断,这种中断管理机制比较简单。
这种中断处理可以保证中断处理的实时性。但是有时会导致比较严重的后果,比如一些重要的中断(如断电)得不到及时处理,造成硬件损坏。
另一种处理方法是处理器响应新的中断,这时就会出现中断嵌套。
中断嵌套提高了处理器的处理能力,理论上,中断嵌套的层数可以很多,但是嵌套层数太多,由于每次嵌套都需要保护断点和现场,从而导致堆栈生长得太大,这对资源有限的单片机会造成比较大的负担。
另外,会导致最早响应的中断服务子程序可能要等待很久,才能执行完本身的中断任务,这明显降低了中断处理的及时性。
因此在微机系统,允许中断嵌套层数最好要根据系统的实时性和资源来综合考虑,在80C51单片机中,允许最大的层数为2。
80C51的中断系统结构及中断源
在基本型80C51单片机中,共有5个中断源,即外部中断0/1,定时/计数器0中断T0,定时/计数器1中断T1,串行通信接口中断RX,TX。中断系统结构如下图。
从结构图可以看出,中断控制系统是由相应的寄存器所控制的,并不是一有中断,CPU就会响应这个中断请求。
从左往右看,可以发现外部中断0和1比较特殊,控制位IT0和IT1控制外部中断的触发方式(下降沿触发或者低电平触发)。
每个中断源都有相应的中断请求标志位(IE0,TF0,IE1,TF1,TI,RI)与其对应,其中串行通信的发送和接收分别对应有两个中断请求标志位(TI和RI),但是他们公用一个中断号,即处理器识别为一个中断源,具体区分二者需要软件查询这两个中断标志位。
每个中断源都有相应的中断子开关(EX0,ET0,EX1,ET1,ES),只有这个控制位为1时,并且总开关EA为1时,才可能产生中断。
最右边的优先级选择开关(PX0,PT0,PX1,PT1,PS)用于确定每个中断源的优先级。
操作80C51的中断系统,实际上也就是操作80C51内部的特殊功能寄存器。
中断请求标志
80C51系列单片机共有6个中断申请标志位,分布在TCON和SCON寄存器中。
其中外部中断和定时器溢出中断由TCON控制,串行口中断由SCON控制。
单片机复位后所有中断请求标志位清0,表示没有中断请求,为1时,表示有相应的中断请求。
1)TCON中的请求标志
TF1:定时/计数器1中断请求标志位,当计数器计数溢出时,中断被响应后,转向相应的中断服务程序,由硬件自动置TF1=0,在查询方式下由软件清除。
TF0:定时/计数器0中断请求标志位,功能与TF1相同。
IE1:外部中断1请求标志位。在外部中断设置为下降沿触发时,INT1脚的下降沿置该位为1,中断被响应后,该位由硬件自动清0;在外部中断设为低电平触发时,当INT1为低电平时,该位置1,此时,撤销中断的办法只有把外部输入的低电平变为高电平。
IT1:外部中断1触发方式选择位。为1表示下降沿触发,为0表示低电平触发。
IE0:外部中断0请求标志位,功能与IE1相同。
IT0:外部中断0触发方式选择位。功能与IT1相同。
定时/计数器中断:当定时/计数器溢出时,在最近机器周期的S5P2期间设置TCON的TF0或TF1为1.中断请求标志置1后,会一直保持到中断被响应,然后由单片机的内部硬件自动对它清0。在查询方式下只能软件清0。
外部中断:80C51单片机在每个机器周期的S5P2期间扫描外部中断输入引脚的电平状态。当外部中断设置为下降沿触发时,若处理器在连续两个机器周期扫描到INT0引脚的电平先后为高电平和低电平时,就会置IE0位1,表示有外部中断申请,该中断申请信号会一直保持,一直到中断被响应,后硬件清0。
2)SCON中的请求标志
TI为串口发送数据的中断请求位,RI为串口接收数据的中断请求位。
在结构图中,可以知道,TI和RI通过与门后输出,只要有一个为1,就可以向CPU申请中断,其中断入口地址是相同的,被认为是一个中断源。
由此可知,在每个机器周期的S5P2期间,中断请求标志位会因为中断源申请中断而设置成1,如果有1位或者多位为1,则表示有多个中断源同时向处理器申请中断。
中断允许控制
IE寄存器内容包含各个中断源使能控制位和全局中断使能控制位。
EA:全局中断使能控制位;
ES:串口中断使能控制位;
ET1:定时/计数器1中断使能控制位;
EX1:外部中断1使能控制位;
ET0:定时/计数器0中断使能控制位;
EX0:外部中断0使能控制位。
中断优先权管理和中断嵌套原则
某个机器周期的S5P2期间,若有中断请求标志位有效时,处理器会在下一个机器周期的S6期间就会根据设置的中断优先等级响应中断,并在再下一个机器周期的S1期间开始执行中断服务子程序。
80C51单片机支持两级中断优先级,允许用户设置每个中断源为高级或低级中断。由中断优先级标志位来设置。对应位为1则设置为高优先级中断,反之为低优先级。这些设置位分布在IP寄存器中。
其中断裁决的原则是:高级中断和低级中断同时申请中断时,优先响应高级中断;当同级有多个中断同时发生时,则有中断优先权排队问题,这时,按由中断系统硬件决定的自然优先级顺序来处理。
MCU100.png">
80C51单片机的中断嵌套原则是:高级中断可以打断低级中断,低级中断不能打断高级中断,同级中断不能打断同级中断。
IP寄存器如下。
PS:串口中断优先级设置位;
PT1:定时/计数器1中断优先级设置位;
PX1:外部中断1优先级设置位;
PT0:定时/计数器0中断优先级设置位;
PX0:外部中断0优先级设置位;
中断响应的条件
当中断源发出中断请求信号时,单片机并不总能对该中断进行响应,一般来说,单片机能响应中断应注意以下几个方面:
1)首先,全局中断使能控制位EA=1;
2)对应中断使能控制位有效;
3)如果程序正在执行读/写寄存器IE或IP指令,则执行完该指令后,需要再执行一条其他指令才可以响应中断;
4)如果程序正在执行返回指令,则执行完该指令后,需要再执行一条其他指令才可以响应中断,这个特性常用来实现硬件单步执行;
5)任何正在执行的指令在未完成前,中断请求都不会响应;
6)考虑中断优先级或者中断嵌套时带来的延时。
中断服务程序的执行
当前面所有的中断响应条件都满足时,处理器在当前指令执行完成的下一个机器周期内,由硬件自动执行一条LCALL执行,跳转到相应的中断服务子程序入口地址去执行中断程序。
在80C51中,中断程序入口地址是固定的。两个相邻的中断入口地址很接近,只有8字节,根本放置不了几个代码。
在实际应用中,一般都将一个跳转指令(LJMP,AJMP)放置在入口地址处,从而跳转到其他程序空间去执行较长的中断服务子程序。
中断服务子程序的编写
当80C51单片机响应中断请求,跳转到相应的中断处理子程序时,除了断点保护由硬件自动完成外,保护现场,恢复现场,中断返回等都需要用户自己编写。
另外,还要考虑是否支持中断嵌套,在中断服务子程序设置EA=1,则允许中断嵌套,反之不允许。注意在保护现场和恢复现场过程中需要关闭全局中断。
中断撤销
中断请求撤销的目的是保证对于一次中断请求标志只执行一次中断响应。
CPU响应中断后,需要及时将中断请求标志清除,否则将引起一个中断信号多次触发中断响应。中断撤销一般分为硬件自动处理和软件清除。
对于外部中断0/1,定时/计数器0/1中断,在中断响应后,由硬件自动清除该中断的请求标志位,无须软件处理。
对于串行接口的中断请求,当CPU响应中断后,硬件不会自动清除中断标志位,因此需要在中断服务程序中软件清除。
中断响应时间
从中断源发出中断请求到处理器执行该中断服务子程序的这一段时间称为中断响应时间。
80C51中断响应时间的最短时间是3个机器周期(优先权扫描1个周期,LCALL指令2个周期)。
最长的响应时间为8个机器周期,除了必要的3个周期外,考虑最坏的情况,比如当前正在执行RETI的第一个机器周期,那么等RETI执行完成之后,还需再等待执行一条指令,假设这条指令最长是4个机器周期,那么就是3+1+4=8个机器周期。