热度 16
2014-1-3 16:41
876 次阅读|
0 个评论
说最基本的,老的51单片机(80C51系列)有5个中断源,2个优先级,可以实现二级中断服务嵌套。现在很多扩展的51单片机已经有4个优先级(或更多)和更多的中断源了。更别说现在的AVR128 的35个中断源了。 在说到中断之前,我先来定义一下优先级,明白了什么是优先级,后面的阐述就容易明白了。实际上很多人都是混淆了优先级的含义,所以才觉得糊里糊涂。 优先级高的中断源可以中断优先级低的中断服务程序,这就形成了中断服务程序中套着中断服务程序的情况,即形成了所谓的中断嵌套。 MCU暂停现行程序而转去响应中断请求的过程称为中断响应;为使系统能及时响应并处理发生的所有中断,系统根据引起中断事件的重要性和紧迫程序,硬件将中断源分为若干个级别,称作中断优先级; 中断的优先级有两个:查询优先级和执行优先级。 什么是查询优级呢?我们从datasheet或书上看到的默认(IP寄存器不做设置,上电复位后为00H)的优先级: 外部中断0 定时/计数器0 外部中断1 定时/计数器1 串行中断 或 int0,timer0,int1,timer1,serial port 或 INT0、T0、INT1、T1、UART 或 PX0PT0PX1PT1PS...... 其实都是查询优级。首先查询优先级是不可以更改和设置的。这是一个中断优先权排队的问题。是指多个中断源同时产生中断信号时,中断仲裁器选择对哪个中断源优先处理的顺序。而这与是否发生中断服务程序的嵌套毫不相干。当CPU查询各个中断标志位的时候,会依照上述5个查询优先级顺序依次查询,当数个中断同时请求的时候,会优先查询到高优查询先级的中断标志位,但并不代表高查询优先级的中断可以打断已经并且正在执行的低查询优先级的中断服务。 例如:当计数器0中断和外部中断1(按查询优先级,计数器0中断外部中断1)同时到达时,会进入计时器0的中断服务函数;但是在外部中断1的中断服务函数正在服务的情况下,这时候任何中断都是打断不了它的,包括逻辑优先级比它高的外部中断0计数器0中断。 而中断的执行优先级就是你对IP寄存器的设置了。在2个优先级的情况下,某位为1,则相应的中断源为高优先级;为0,则为低优先级。 关于中断的优先级有三条原则: 1、CPU同时接收到几个中断时,首先响应优先级最高的中断请求; 2、正在进行的中断过程不能被新的同级或低行优优先级的中断请求所中断; 3、正在进行的低行优优先级中断服务,能被高行优优先级中断请求中断; 若:同一执行优先级中的中断申请不止一个时,则有一个中断优先权排队问题。同一执行优先级的中断优先权排队,由中断系统硬件确定的自然优先级形成,优先权自高到低的顺序即: 外部中断0定时/计数0外部中断1定时/计数1串行接口 例如:设置IP = 0x10,即设置串口中断为最高优先级,则串口中断可以打断任何其他的中断服务函数实现嵌套,且只有串口中断能打断其他中断的服务函数。若串口中断没有触发,则其他几个中断之间还是保持逻辑优先级,相互之间无法嵌套。 关于中断嵌套。可以这样说,当一个中断正在执行的时候,如果事先设置了中断优先级寄存器IP,那么当一个更高优先级的中断到来的时候会发生中断嵌套,如果没有设置则不会发生任何嵌套;如果有同一个优先级的中断触发,它并不是在“不断的申请”,而是将它相应的中断标志位置即IE寄存器的某位置位,当CPU执行完当前中断之后,按照查询优先级重新去查询各个中断标志位,进入相应中断。 要记住,没有设置IP时,单片机会按照查询优先级(或都说逻辑优先级)来排队进入服务。如果要想让某个中断优先响应, 则要设置IP,更改执行优先级(或者说物理优先级)。要注意的是,当设置了IP后,当低执行优先级中断在运行时,如果有高执行优先级的中断产生,则会嵌套调用进入高执行优先级的中断。如果你是用C语言写的程序,并在中断服务时 using 了寄存组,要注意,两个不同执行优先级的中断服务程序不要 using 同一组寄存器。 看两个问题,如下: 1 在各个中断都是低优先级的时候,如果定时器0的溢出进入中断。在这个中断处理的过程中,外部中断0也被触发了,那么是不是要发生中断嵌套? 2 如果定时器0发生中断的时候,进入中断处理程序,这个时候外部中断1条件触发条件满足了。因为定时器0自然优先级比外部中断1高,那么定时器0的中断处理程序继续执行。假设定时器中断处理程序执行的过程中,外部中断1的触发。条件消失了,那么等定时器0的中断处理完后,程序还是会进入外部中断1处理程序吗? 答案1:在IP事先设置了外部中断0的优先级的情况下,CUP会中止定时器0的中断服务,进入外部中断0服务程序,执行完以后再回到定时器0中断服务程序。否则不会。 答案2:肯定会进入中断的;外部中断1的触发条件满足后会置位外部1的中断标志,即使后来外部中断1的触发条件消失了,也不会清除已置位的中断标志,所以等定时器0的中断处理完后,程序判断外部中断的中断标志为1后依然会进入外部中断1处理程序的,只有在外部中断1处理程序中执行reti指令才会硬件清除外部中断1的中断标志(这也正是为什么中断返回使用reti指令而不可以用ret替换的原因)... 说到这里我们应该要知道MCU清除中断标志位的两种方式:一种是通过软件代码往这个中断标志位的寄存器里面写“1”来完成标志位的清零操作;第二种是当MCU响应中断,执行中断服务程序的时候(也就是程序计数器的指针跳转到了中断服务程序代码区),由硬件自动执行清零操作。 中断处理分为四个阶段: 1、保存被中断程序的现场,其目的是为了在中断处理完之后,可以返回到原来被中断的地方继续执行; 2、分析中断源,判断中断原因,当同时有多个中断同时请求的时候还要考虑中断的优先级; 3、转去执行相应的处理程序; 4、恢复被中断程序现场,继续执行被中断程序。 注意多级中断的特点: (1) 一个系统若有n级中断,在MCU中就有n个中断请求触发器,总称为中断请求寄存器 ;与之对应的有n个中断屏蔽触发器,总称为中断屏蔽寄存器。与单级中断不同,在多级中断中,中断屏蔽寄存器的内容是一个很重要的程序现场,因此在响应中断时,需要把中断屏蔽寄存器的内容保存起来,并设置新的中断屏蔽状态。一般在某一级中断被响应后,要置“1 ”(关闭)本级和优先权低于本级的中断屏蔽触发器,置“0”(开放)更高级的中断屏蔽触发器,以此来实现正常的中断嵌套。 (2) 多级中断中的每一级可以只有一个中断源,也可以有多个中断源。在多级中断之间可以实现中断嵌套,但是同一级内有不同中断源的中断是不能嵌套的,必须是处理完一个中断后再响应和处理同一级内其他中断源。