中断源和中断向量:
缺省状况下,AVR的程序存储区的最低端,即从Flash地址的0x0000开始用于放置中断向量,称作中断向量区。中断向量区大小 = 中断源个数 * 每一个中断向量占据字数。对于Flash比较小的AVR处理器,每一个中断向量占据一个字的空间,用于放置一条相对转移指令 rjmp(跳转范围-2K~+2K),而Flash较大的AVR,每一个中断向量占据两个字空间,用于放置一条绝对转移指令 jmp,用于跳转到相应中断的中断服务程序的起始地址。
在这21个中断中,包含1个非屏蔽中断(RESET)3个外部中断(INT0、INT一、INT2)和17个内部中断。
RESET $000 |
INT0 $002 |
INT1 $004 |
INT2 $024 |
INT0、INT1和INT2是3个外部中断源,它们是分别由芯片外部引脚PD二、PD三、PB2上的电平变化或状态触发的。经过对控制寄存器MCUCR和控制与状态寄存器MCUCSR的配置,外部中断能够定义为由PD二、PD三、PB2引脚上的电平的降低沿、上升沿、逻辑电平变化,或者低电平触发(INT2仅支持电平变化的边沿触发),这为外部硬件电路和设备向AVR申请中断服务提供了很大的方便。
**关于计数器的中断寄存器:TIMER2 COMP、TIMER2 OVF、TIMER1 CAPT、TIMER1 COMPA、TIMER1 COMPB、TIMER1 OVF、TIMER0 OVF、TIMER0 COMP这8个中断是来自于ATmega16内部的3个定时计数器触发的内部中断。定时器处在不一样的工做模式下时,这些中断的发生条件和具体意义是不一样的。
ATmega16的中断控制:
1)、中断优先级的肯定
AVR单片机中,一个中断在中断向量区中的位置决定了它的优先级,位于低地址的中断优先级高于位于高地址的中断。因此 RESET 具备最高优先级。
AVR单片机采用固定的硬件优先级方式,不支持经过软件对中断优先级的从新设定。当有多个中断源向MCU申请中断的状况中,MCU根据中断优先级的不一样,把低优先级的中断挂起,首先响应中断优先级最高的那个中断。待优先级最高的中断服务程序执行完成返回后,再顺序响应低优先级的中断。
2)、中断标志
AVR有两种机制不一样的中断:带有中断标志的中断(可挂起)和不带中断标志的中断(不能挂起)
。在 AVR 中,大多数的中断都属于带中断标志的中断。所谓的中断标志,是每一个中断源在
其 I/O 空间寄存器中具备本身的一个中断标志位。AVR 的硬件系统在每一个时钟周期内都会检
测(接受)外部(内部)中断源的中断条件。一旦中断条件知足,AVR 的硬件就会将置位相
应的中断标志位(置为“1”),表示向 MCU 提起中断请求。
3)、中断屏蔽与管理
AVR 对中断采用两级控制方式。两级控制是指 AVR 有一
个中断容许的总控制位 I(既 AVR 标志寄存器 SREG 中的 I 标志位“SREG.7”),一般称为全
局中断容许控制位。同时 AVR 为每个中断源都设置了独立的中断容许位,这些中断容许位
分散位于各中断源所属模块的控制寄存器中。
▋AVR响应一个可屏蔽中断源(假定为A中断)的中断的条件是: 响应A中断 = 全局中断容许标志 AND 中断A容许标志位 AND 中断A标志 当某个中断条件成立后,硬件会自动将该中断的标志位置"1",表示中断产生,同时也做为申请中断服务的请求信号。若是该中断的容许位为"1",同时AVR的全局中断容许位 I 也是"1"时,那么MCU在执行完当前一条指令以后就会响应该中断。 ▋AVR复位后,各个中断容许位以及全局中断容许位均被清零,这保证了程序在开始执行时(通常程序开头是对芯片内部以及外围系统的初始化设置)不会受到中断的干扰。 ▋AVR复位后的用户初始化程序中,须要先对须要使用的中断源进行必要的配置,待系统初始化过程结束后在置位 I ,使系统进入正常的工做状态,开始响应中断请求。 |
4)、中断嵌套
AVR在响应一个中断的过程当中经过硬件将 I 标志位自动清零,这样就阻止了MCU响应其它中断。一般状况下,AVR是不能自动实现中断嵌套的。若是系统中必需要实现中断嵌套的应用,用户能够在中断服务程序中使用指令将全局中断容许位开放,经过间接的方式实现中断的嵌套处理。
滥用中断嵌套会形成程序流程的不肯定性。所以建议只有当某中断确实需
要获得实时响应时才考虑使用中断嵌套处理,通常状况下尽可能不要采用中断嵌套,由于 AVR
自己是高速单片机,它运行速度是能足够快速的将中断服务程序执行完的。固然,用户编写
中断服务程序时,应遵循尽可能短小的原则。
AVR的中断响应过程:
1)、中断响应的过程
AVR在响应中断请求时,MCU会使用4个时钟周期自动顺序的完成如下任务:
▶ 清零状态寄存器SREG中的全局中断容许标志位 I ,禁止响应其余中断。
▶ 将被响应中断的标志位清零(这个只是部分中断有此操做)。
▶ 将中断断点的地址(即当前程序计数器PC的值)压入堆栈,并将SP寄存器中的堆栈指针减二。
▶ 自动将相应的中断向量地址压入程序计数器PC,即强行转入执行中断入口地址处的指令。
中断响应过程所有由硬件本身实现,不须要用户干预。
2)、中断返回的过程
AVR一旦执行中断返回RETI指令,MCU便开始了中断返回的过程。AVR在中断返回过程当中,使用4个时钟周期自动按顺序完成如下任务:
▶ 从栈顶弹出2个字节的数据,将这两个数据压入程序计数器PC中,并将SP寄存器中的堆栈指针加2。
▶ 置位状态寄存器SREG中的全局中断容许标志位I,容许响应其余中断。
中断返回后,会检测中断标志,若是存在其余被挂起的中断,则AVR在中断返回后还需执行一条指令,被挂起的中断才会获得响应。
3)、中断现场的保护
AVR的中断响应和返回过程主要都是由硬件自动完成的,而在整个过程当中用户程序的做用在于:
▶ 中断入口处的指令。用于指引MCU转移到中断服务程序。
▶ 中断服务程序。完成中断服务的功能。
▶ 中断返回指令。指引MCU从中断服务程序中返回。
为了提升中断响应的实时性,AVR在中断响应和返回过程当中,硬件上的处理仅仅保护和恢复了中断的断点(PC值)。而对中断现场没有采起任何处理。 所以,中断现场的保护工做须要用户在本身编写的中断服务程序中经过软件完成,以保证主程序在被打断时所使用的标志位和临时寄存器等不会被中断服务程序改变,例如,对状态寄存器SREG的保护等! |
中断服务程序编写:(三个框架)中断向量区部分、主程序部分和中断服务程序部分。
1)、中断向量区部分
缺省状况下,AVR的中断向量区在Flash程序存储器的最低端。最开始的0x0000是不可屏蔽的复位上电的中断向量,此处有一条转移到主程序开始处的跳转指令。
2)、主程序部分
单片机主程序的开始阶段一般要对整个系统已经芯片自己进行初始化设置,而后才能进入正常的工做流程中。分为:堆栈指针的初始化、中断源设置、开放全局中断、各中断源相应的中断容许设置。
开放中断源自己的中断容许位以前,最好先使用指令将该中断的中断标志位清除,而后立刻将中断容许位置“1”。 在开放中断前清楚可能存在的中断标志,保证了中断开放后不会造成一次“多余”的中断,这个“多余”的中断有时会形成致命的错误。由于在对中断源进行设置过程当中,或中断源对应的硬件模块在工做中都有可能改变中断标志位。 |
3)、中断服务程序
因为在中断向量处一般放置一条转移指令,用于再次跳转到中断服务程序的开始处,因此中断服务程序能够放置在FLASH空间的任何地方。
中断服务程序中要考虑被中断现场的保护和恢复问题。中断的产生和响应是随机的,并且在中断服务程序中常常要使用一些寄存器,或对RAM中的变量进行操做,也会有判断和跳转的操做,这些指令可能会改变SREG中的标志位,因此必须确保当从中断服务程序返回时,被中断服务程序改变的现场所有正确的恢复,这样当中断返回后,主程序才能正确继续运行下去。 |
除了一些必须在中断中完成的工做外,对于那些不须要立刻处理的工做,如键盘处理、扫描显示等应该放在主程序中完成,也就是说,中断服务程序应尽量的短。中断服务程序短,不是程序指令少,而是执行一次中断服务程序所须要的时间短。尽可能减小中断服务程序的执行时间有如下优势:
▋能够没必要采用中断嵌套技术。AVR的硬件不支持自动的中断嵌套处理,所以中断执行时间短的话可以尽快的响应其余被挂起的中断,提供系统整体的实时响应速度。
▋可以防止丢失周期性中断或其它短时中断。列如,当系统有一个1ms产生一次的周期型中断源,你的中断服务程序就必须在1ms完成,不然将会形成下一个中断的“丢失”。
有不少状况下,中断仅仅表示外围设备或内部功能部件的工做过程已经达到某种状态,但不须要立刻去处理,或者容许在一个比较充裕的限定时间内处理,这就能够将它们的处理工做放到主程序中完成。在这种状况下,最好的方式就是定义和使用信号量或标志变量,在中断服务程序中只是简单的对这些信号量或标志量进行必要的设置,不作其余处理就立刻返回主程序,由主程序中根据这些信号量或表质量的值进行和完成处理工做。 这样作的另外一个好处是,能够大大减小中断服务程序中的对中断现场保护和恢复的工做,从而又减小了中断程序的执行时间,同时也节省了堆栈空间和FLASH空间(代码少了)。 |