外设中断扩展模块(PIE:Peripheral Interrupt Expansion)是为了使 F2812 DSP 微处理器能够有效管理众多的中断而设计的。PIE 将 DSP 微处理器中的中断分组,使多个中断信号复用 1 个 CPU 级中断信号,从而使 CPU 能够高效地管理中断信号请求。
PIE 管理的中断源共 96 个(其中正在使用的有45个,其它的作为扩展资源供厂商测试或留待芯片升级时使用),这些中断分为12
组,每个组有 8 个中断。这 12 组从 1 开始编号,依次分别接到 CPU 级的 INT1-INT12 中断信号上。96 个中断源对应 96 个中断向量,在存储器空间中专门留出一块来保存 96 个中断向量,当中断发生时,其对应的中断向量能够自动被取出从而调用相应的中断服务程序(F2812 中断向量的取出和跳转是由硬件自动完成的,相对于软件分离子中断的方式,这种方式能够大大提高中断的响应速度)。 注意:中断向量表是受
EALLOW 保护的。
PIE 配置及控制寄存器:
PIE 相关的寄存器咋看一下非常多,但是如果按组归类,对于一个特定的中断,与它相关的寄存器就只有 PIECTRL、PIEACK、PIEIERx、PIEIFRx。
除了上述寄存器,中断还与 IFR、IER 寄存器及全局中断屏蔽位 INTM 相关,下图是典型的
PIE - CPU 响应流程:
下面通过分析源代码来深入理解 F2812 中断机制: void main() { DINT;//关全局可屏蔽中断 #define DINT asm(" setc INTM") InitPieCtrl();//初始化pie寄存器
IER = 0x0000;//禁止所有的中断
IFR = 0x0000; InitPieVectTable();//初始化pie中断向量表 EALLOW; // This is needed to write to EALLOW protected registers PieVectTable.TINT0 = &cpu_timer0_isr;//指定中断服务子程序
EDIS; …… // Enable CPU INT1 which is connected to CPU-Timer 0:
IER |= M_INT1; //#define M_INT1 0x0001 // Enable TINT0 in the PIE: Group 1 interrupt 7
PieCtrlRegs.PIEIER1.bit.INTx7 = 1; // Enable global Interrupts
EINT; //#define EINT asm(" clrc INTM") }
// This function initializes the PIE control registers to a known state. void InitPieCtrl(void) @ DSP281x_PieCtrl.c
{
// Disable Interrupts at the CPU level:
DINT;
// Disable the PIE
PieCtrlRegs.PIECRTL.bit.ENPIE = 0;