什么是中断?中断(Interrupt)是硬件和软件驱动事件,它使得CPU暂停当前的主程序,并转而去执行一个中断服务程序。
2812的中断系统
2812的CPU能够支持一个不可屏蔽中断NMI和16个可屏蔽的中断INT1-INT14、RTOSINT和DLOGINT,2812的CPU为了能够及时有效的处理好各个外设的中断请求,设计了一个专门处理外设中断的扩展模块(the Peripheral Interrupt Expansion block),叫做外设中断控制器PIE,它能够对各种中断请求源(例如来自于外设或者其他外部引脚的请求)做出判断以及相应的决策。PIE 可以支持96个不同的中断,这些中断分成了12个组,每个组有8个中断,而且每个组都被反馈到CPU内核的12 条中断线中的某一条上(INT1-INT12)。PIE 目前只使用了96 个终端中的45 个,其他的等待将来的功能扩展。
2812的PIE内部的中断分布图
PIE内部的中断8列12行,总共有96个中断,黄色部分表示已经使用的中断,例如:查看事件管理器EVA中定时器T1的周期中断T1PINT-------T1PINT在行号为INT2,列号为INTx.4的位置,也就是说T1IPNT对应于INT2,是INT2中的第四个中断。
2812的3级中断机制
2812的中断是3级中断机制,分别是外设级,PIE级以及CPU级,对于某一个具体的外设中断请求,任意一级的不许可,CPU最终都不会执行该外设中断。下面我们将以2812的外设EVA中定时器T1的周期中断T1PINT为例。
(1).外设级
假如在程序的执行过程中,某一个外设产生了一个中断事件,那么在这个外设的某个寄存器中与该中断事件相关的中断标志位(IF=Interrupt Flag)被置为1。此时,如果该中断相应的中断使能(IE=Interrupt Flag)已经被置位为1,外设就会向PIE控制器发出一个中断请求。相反的,如果虽然中断事件产生了,相应的中断标志位也被置1了,但是该中断没有被使能(相应的使能位为0),那么外设就不会向PIE发出中断请求,但是值得一提的是,相应的中断标志位会一直保持置位状态,直到用程序清楚它为止。当然,在中断标志位保持在1的时候,一旦该中断被使能了,那么外设立马会向PIE发出中断申请。 我们用具体的T1PINT来进行进一步的说明。当定时器T1的计数器寄存器T1CNT计数到和T1周期寄存器T1PINT的值匹配时(相等时),就产生了一个T1PINT事件,即T1的周期中断。这时候,事件管理器EVA的中断标志寄存器A(EVAIFRA)中的第7位T1PINT FLAG被置为1,这时候如果EVA的中断屏蔽寄存器A(EVAIMRA)中的第7位T1PINT的使能位是1,则EVA就会向PIE发出中断请求,当然,如果该位的值是0,也就是该中断未被使能(被屏蔽),则EVA不会向PIE发出中断请求,而且EVAIFRA中T1PINT FLAG位将一直保持为1,除非通过程序将其清除。需要注意的是,不管在什么情况下,外设寄存器中的中断标志位都必须手工清除。
中断外设级总结:
外设中断的屏蔽,需要将与该中断相关的外设寄存中的中断使能位置0;
外设中断标志位的清除,需要将与该中断相关的外设寄存中的中断标志位置1;
清除T1PINT标志位: EvaRegs.EVAIFRA.bit.T1PINT = 1;
中断屏蔽位使能 : EvaRegs.EVAIMRA.bit.T1PINT = 1;
(2).PIE级
当外设产生中断事件,相关中断标志位置位,中断使能位使能之后,外设就会把中断请求提交给我们的PIE模块。PIE模块将96个外设和外部引脚的中断进行了分组,每8个中断为1组,一共是12组,分别是PIE1-PIE12。每个组的中断被多路汇集进入1个CPU中断,例如PDPINDA,PDPINDB,XINT1,XINT2,ADCINT,TINT0,WAKEINT这7个中断都在PIE1组内,这些中断都汇集到CPU中断的INT1。 和外设级类似的,PIE控制器中的每个组都会有一个中断标志寄存器PIEIFRx和和中断使能寄存器PIEIERx,当然x=1.....12。每个寄存器的低8位对应于8个外设中断,高8位保留。例如T1PINT对应于PIEIFR2的第4位和PIEIER2的第4位。PIE除了每组具有刚才的PIEIERx,PIEIFRx寄存器之外,还有一个PIEACK寄存器,它的低12位分别对应着12个组,即INT1-INT12,高位保留。假如T1的周期中断被响应了,则PIEACK寄存器的第2位(对应于INT2)就会被置位,并且一直保持直到手动清除这个标志位。当CPU在响应T1PNT的时候,PIEACK的第2位一直是1,这时候如果PIE2组内发生其他的外设中断,则暂时不会被PIE响应送给CPU,必须等到PIEACK的第2位被复位之后,如果该中断请求还存在,那么立马由PIE控制块将中断请求送至CPU。所以,每个外设中断被响应之后,一定要对PIEACK的相关位进行手动服务,否则同组内的其他中断都不会被响应。
中断PIE级总结:
PIE中断的使能。就得将其相应组的使能寄存器PIEIERx的相应位进行置位;
PIE中断的屏蔽。这是和使能相反的操作;
PIE应答寄存器 PIEACK相关位的清除,以使得CPU能够响应同组的其他中断。
将PIE级的中断和外设级的中断相比较之后发现,外设中断的中断标志位是需要手工清除的,而PIE级的中断标志位都是自动置位或者清除的。但是PIE多了一个PIEACK寄存器,同一时间只能放一个中断过去,只有等到这个中断被响应,给PIEACK置位,才能让同组的下一个中断过去,被CPU响应清除PIE中与T1PINT相关的应答位: PieCtrl.PIEACK.bit.ACK2=1;
使能PIE中断INT2.4(T1PINT中断): PieCtrlRegs.PIEIER2.all=M_INT4; //M_INT4=0x0008
(3)CPU级
CPU也有标志寄存器IFR和使能寄存器IER。当某一个外设中断请求通过PIE发送到CPU时,CPU级中与INTx相关的中断标志位就会被置位。例如,T1的周期中断T1PINT的请求到达CPU这边时,与其相关的INT2的标志位就会被置位。这时候,该标志位就会被所存在IFR中,这时候,CPU不会马上去执行相应的中断,而是等待CPU使能IER寄存器的相关位,并且对CPU寄存器ST1中的全局中断屏蔽位做适当的使能。如果IER中的相关位被置位了,并且INTM的值为0,则中断就会被CPU响应。在T1PINT里,当IER的第2位即INT2被置位,INTM为0,则CPU就会响应定时器T1的周期中断。 CPU接到了终端的请求,就得暂停正在执行的程序,转而去响应中断程序,但是此时,它必须得做一些准备工作,以便于执行完中断程序之后回过头来还能找到原来的地方和原来的状态。CPU会将相应的IER和IFR位进行清除,EALLOW也被清除,INTM被置位,就是不能响应其他中断了,CPU向其他中断发出了通知,正在忙,没空来处理你们的请求了,得等到处理完手上的中断之后才能再来处理你们的请求。然后,CPU会存储返回地址并自动保存相关的信息,例如将正在处理的数据放入堆栈等等,做好这些准备工作之后,CPU会从PIE块中取出对应的中断向量ISR,从而转去执行中断子程序。
中断CPU级总结:
CPU级的操作都是自动的,不管是中断标志位(IFR),还是中断的使能位(IER)。 |