AVR有不同的中断源。每个中断和复位在程序空间都有独立的中断向量。所有的中断事件都有自己的使能位。当使能位置位,且状态寄存器的全局中断使能位I也置位时,中断可以发生。根据程序计数器PC的不同,在引导锁定位BLB02或BLB12被编程的情况下,中断可能被自动禁止。这个特性提高了软件的安全性。
程序存储区的最低地址默认为复位向量和中断向量。完整的向量列表如表8-1所示。列表也决定了不同中断的优先级。向量所在的地址越低,优先级越高。RESET具有最高的优先级,第二个为INT0——外部中断请求0。通过置位MCU控制寄存器(MCUCR)的IVSEL,中断向量可以移至引导Flash的起始处。编程熔丝位BOOTRST也可以将复位向量移至引导Flash的起始处。
任一中断发生时全局中断使能位I被清零,从而禁止了所有其他的中断。用户软件可以在中断程序里置位I来实现中断嵌套。此时所有的中断都可以中断当前的中断服务程序。执行RETI指令后I自动置位。
ATmega16共有21个中断源,由于ATmega16片内的Flash为8K字,因此每个中断向量占据了两个字(4个字节),默认状态下ATmega16的中断向量如表8-1所示。
表8-1 ATmega16的中断向量区

从根本上说有两种类型的中断。第一种由事件触发并置位中断标志。对于这些中断,程序计数器跳转到实际的中断向量以执行中断处理程序,同时硬件将清除相应的中断标志。中断标志也可以通过对其写“1”的方式来清除。当中断发生后,如果相应的中断使能位为“0”,则中断标志位置位,并一直保持到中断执行,或者被软件清除。类似地,如果全局中断标志被清零,则所有已发生的中断都不会被执行,直到I置位。然后挂起的各个中断按中断优先级依次执行。
第二种类型的中断则是只要中断条件满足,就会一直触发。这些中断不需要中断标志。若中断条件在中断使能之前就消失了,中断不会被触发。(https://www.xing528.com)
AVR退出中断后总是回到主程序并至少执行一条指令才可以去执行其他被挂起的中断。要注意的是,进入中断服务程序时状态寄存器不会自动保存,中断返回时也不会自动恢复。这些工作必须由用户通过软件来完成。
使用CLI指令来禁止中断时,中断禁止立即生效。没有中断可以在执行CLI指令后发生,即使它是在执行CLI指令的同时发生的。下面的例子说明了如何在写EEPROM时使用这个指令来防止中断发生以避免对EEPROM内容的可能破坏。相应的基于C语言的程序示例如下:

使用SEI指令使能中断时,紧跟其后的第一条指令在执行任何中断之前一定会首先得到执行。相应的基于C语言的程序示例如下:

AVR中断响应时间最少为4个时钟周期。4个时钟周期后,程序跳转到实际的中断处理例程。在这4个时钟期期间PC自动入栈。在通常情况下,中断向量为一个跳转指令,此跳转需要3个时钟周期。如果中断在一个多时钟周期指令执行期间发生,则在此多周期指令执行完毕后MCU才会执行中断程序。若中断发生时MCU处于休眠模式,中断响应时间还需增加4个时钟周期。此外还要考虑到不同的休眠模式所需要的启动时间。这个时间不包括在前面提到的时钟周期里。
中断返回需要4个时钟。在此期间PC(两个字节)将被弹出栈,堆栈指针加2,状态寄存器SREG的I置位。
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。
