“简简单单DSP”系列学习活动——第四期中断结构学习
[复制链接]
1 、外围帧寄存器
2812 将外围帧寄存器分为 3 个空间,分别是:
外围帧 0 :直接映射到 CPU 存储器总线
外围帧 1 :映射到 32 位外围总线
外围帧 2 :映射到 16 位外围总线,只允许 16 操作
这里所说的外围帧寄存器就是外设寄存器,如 ADC 寄存器。映射就是分配地址,外围一个地址, CPU 一个地址,外围地址映射到 CPU 地址上。
有的寄存器受保护,对其进行操作的时候好,要屏蔽保护( EALLOW ),操作完在开启保护 (EDIS).
2 、外围中断扩展 PIE
外设寄存器中的中断标志位必须由软件清 0 ,才能允许下一次中断进入,而且每次中断后要把 PIEACKx 清 0 ,只有 PIEACKx=0 ,才可以把中断送到 CPU 级
中断分为 3 级:
a 、外设级
b 、 PIE 级
c 、 CPU 级
下面分别介绍这个不同的中断级以及这 3 级的联系
a 、外设级
一旦外设产生了中断,对应的外设中断标志寄存器中的中断标志位 IF 就会置位,如果此时对应的中断使能位设为 1 ,那么外设中断信号 可以送到 PIE 控制器,如果外设的中断被禁止输入进来,那么外设中断标志位保持为 1 ,直到软件清 0 。
外设级 和 PIE 级的联系就在外设中断使能位那了,实际外设的中断使能位使能的就是允许外设中断进入 PIE 级,相当于 PIE 级的中断源,就像外设的中断源一样,有了中断事件,外设中断标志位就会置位,这里也是外设级 就是 PIE 级得中断事件,有了外设级的中断标志位置位,中断使能位使能,那么 PIE 级的中断标志位才会置 1.
注意的是外设中断标志寄存器中的中断标志位必须由软件清 0 ,才能允许下一次中断进入。
b 、 PIE 级
PIE 级有两中寄存器,一种是中断标志寄存器 PIEIFRx ,上面已经说过他跟外设级的联系,另一个是中断使能寄存器 PIEIERx ,这个跟外设级的中断使能寄存器功能差不多,实现的是和 CPU 级的联系 .PIE 级还有两个寄存器,一个是控制寄存器 PIECTRL, 这个是控制整个 PIE 级的,还有一个应答寄存器 PIEACK, 在 PIEIFRx 置位, PIEIERx 使能还要 PIEACKx 清 0 才能把中断送到 CPU 级。
这里注意的是 PIEIFRx 由硬件清 0 ,但是 PIEACKx 要由软件清 0.
c 、 CPU 级
CPU 级是最终控制中断响应的,也是有两种寄存器,一个是中断标志寄存器 IFR ,另一个是中断使能寄存器 IER 。 IFR 是这三级中断的最终的中断标志位, IER 是这三级中断的最终中断使能位,只有这三级中断标志位同时置位,三级中断同时使能,这里还有一个 CPU 级的中断屏蔽位 INTM ,在以上条件满足的前提下,中断屏蔽位 INTM=0 , CPU 才能响应中断,找到中断向量,跳转到中断函数,执行中断操作, CPU 级的中断标志位由硬件清 0 ,在中断函数中不用管。
这就是它的中断过程。
3 、 96 个中断介绍
2812 分为 12 组中断,每组中断有 8 个中断源,以 INTx.y 表示,其中 x 是组( x=1~12 ), y ( y=1~8 )是组中的位 .
在配置中断的时候,
外设级 的中断使能位要使能;
PIECTRL 寄存器使能 PIE ;
要知道 INTx.y 中的 xy 是多少,找到 PIEIERx ( x=1~12 )的 x 是多少,使能 PIEIERx ;
PIEACKx ( x=1~12 )的 x 是多少给其清 0 ;
IERx ( x=1~12 )的 x 是多少,使能 IERx ;
中断屏蔽位 INTM=0 ;
中断函数中要处理的:
外设中断标志位软件清 0
PIEACKx ( x=1~12 )软件清 0 ;
4 、 C 代码分析
以定时器 0 的 C 代码分析
timer0 的中断向量 INT1.7 ( x=1 , y=7 ),用到的 PIE 级的中断使能寄存器是 PIEIER1 , CPU 级的 IER1.
在 2812 的库函数中有一个定义中断入口地址的函数,用户的中断函数内容可以在这里面写,就不容另外赋中断地址了。中断函数入口地址 interrupt void
TINT0_ISR(void)
。
在 DSP 复位后,进入中函数前,看门狗开着的,所以在进入中函数后第一件事情是关看门狗,在这个函数里面 InitSysCtrl(); 中断是开着的需要关闭( DINT; ), PIE 寄存器( InitPieCtrl();// 初始化 pie 寄存器)( IER = 0x0000;// 禁止所有的中断 IFR = 0x0000; )、中断向量表是没有初始化的,所以要初始化( InitPieVectTable();// 初始化 pie 中断向量表)。
InitSysCtrl();// 初始化 cpu
DINT;//关中断
InitPieCtrl();//初始化 pie 寄存器
IER = 0x0000;//禁止所有的中断
IFR = 0x0000;
InitPieVectTable();//初始化 pie 中断向量表
EALLOW;
// This is needed to write to EALLOW protected registers
PieVectTable.TINT0 = &cpu_timer0_isr;//指定中断服务子程序,这个地方要是用到了 DSP 的库函数 DSP281X_DefaultIsr() 函数就不需要了。
EDIS;
InitCpuTimers();// 初始化定时器 0
ConfigCpuTimer(&CpuTimer0,150,9.75);//配置你要定时的时间
StartCpuTimer0();//定时器开始计数
PieCtrlRegs.PIEIER1.bit.INTx7 = 1;//使能 PIE 级中断 PIEIERx 中的 x=1 ,即使能的 12 组中的第 1 组第七个
IER |= M_INT1; // 使能 CPU 级的中断第 1 组
EINT;
// 使能 INTM
ERTM;
// 使能仿真时 DBGM
5 、在中断函数中要做的
interrupt void
TINT0_ISR(void)
// CPU-Timer 0
{
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; //PIEACK清 0
CpuTimer0Regs.TCR.bit.TIF = 1;//外设中断标志位清 0
CpuTimer0Regs.TCR.bit.TRB = 1;//重新装载
}