NVIC寄存器列表
2-1 中断允许寄存器中断允许寄存器(ISER)用于使能中断设置,同时可返回当前允许中断设置。需要注意的是,对该寄存器写0是无效的,是不能禁止中断的。要禁止中断,就需要下面介绍的中断禁止寄存器。
2-2 中断禁止寄存器有使能中断的设置,相应的就会有禁止中断设置,这就是中断禁止寄存器的作用。对寄存器进行写1操作,就可以禁止中断设置。。需要注意的是,对该寄存器写0是无效的。对寄存器进行读操作,同返回当前禁止中断设置。
2-3 中断挂起寄存器当有中断事件发生时,中断挂起寄存器(ISPR)中对应的中断位就会置位 。此时读取寄存器就可以判断具体的中断源。同时我们也可以向寄存器的中断位写1,来强制中断进入挂起状态。
2-4 清除中断挂起寄存器当MCU响应了中断请求,并且执行完对应的中断子程序后,MCU便会返回断点处继续运行。但在返回前需要通过清除中断挂起寄存器(ICPR),来清除对应的中断挂起,这样当次的中断流程算是完整结束。
2-5 中断优先级寄存器如同我们做事情有轻重缓急之分,单片机对中断的处理也有“轻重缓急”。具体就是靠8组中断优先级寄存器IPR0~7来实现。每组寄存器对应4个中断源的优先级。这样刚好决定了中断0~中断31的优先级。
每一组的中断优先级寄存器IPRn的每个字节最高两位决定优先级,因此有0~3共4个优先级可以选择,越低的值表示优先级越高,当优先级更高的中断发生时,高优先级的中断会打断低优先级中断。如果是同优先级中断,则并不会打断当前中断,而是依次响应中断。中断优先级寄存器IPRn如图所示:
这里介绍个快速的方法来计算中断 M 的 IPR 寄存器号:
• 计算对应的 IPR 寄存器号, N, N = M / 4
• 计算 IPR 寄存器内的字节偏移量 M % 4, 其中:
– 字节偏移量 0 对应寄存器的位 7:0
– 字节偏移量 1 对应寄存器的位 15:8
– 字节偏移量 2 对应寄存器的位 23:16
– 字节偏移量 3 对应寄存器的位 31:24
4、ME32F030端口中断例程
本篇中我们首先讲解了ME32F030的GPIO中断系统,然后又介绍了嵌套向量中断控制器(NVIC)的原理。
最后,我们还是要通过具体的实例来把我们学到的理论知识应用到实际的例子中。我们将两者结合起来做个小实验,测试程序的代码如下:
unsigned int uiCnt = 0;//端口反转次数
int main(void)
{
PA->DIR_b.DIR0 = 1; //PA_0 设置为输出口
PA->IS_b.ISENSE0 = 0; //PA_0 设置为沿触发
PA->IBE_b.IBE0 = 1; //PA_0 上升沿和下降沿都触发中断
PA->IC_b.CLR0 =1 ; //PA_0 中断标志位清除
PA->IE_b.MASK0 = 1; //PA_0 中断使能
PB->DIR_b.DIR9=1; //PB_9 设置为输出口
NVIC_EnableIRQ(PA_IRQn); //使能PA_IRQ中断
lcd_init(); //LCD液晶初始化
while (1)
{
uiCnt ; //端口反转次数加1
PA->NOT_b.NOT0=1; //PA_0 输出取反
SYS_DelaymS(500);
if(uiCnt == 20) //当反转20次时
{
PA->IE_b.MASK0 = 0; //PA_0 中断关闭
}
}
}
//PA_IRQ中断子程序
void PA_IRQHandler(void)
{
PB->NOT_b.NOT9=1; //PB_9(LED灯)输出取反
PA->IC_b.CLR0 =1 ; //清除PA_0中断位
//LCD显示中断发生的次数
LCD->MEMMAP1 = lcd[uiCnt/10] | (lcd[uiCnt]<<16);
}
测试程序是通过PA_0端口输出反转,来产生下降沿和上升沿。但同时它的端口中断功能是被使能的,因此可以通过输出电平来“触发”自己的中断。在中断服务子程序中,LED小灯端口输出取反来进行点亮和熄灭,同时加入了LCD段码液晶来显示中断发生的次数。在程序全速运行的过程中,当端口输出反转20次之后,会关闭端口的中断功能。接下来下载并仿真例程来进行说明。
程序下载并仿真后,先在程序这两处打上断点。然后用快捷键F5全速运行,程序首先会运行到第78行处的断点,这时端口还没有进行输出反转。接下来用快捷键F10单步运行观察。
仿真1
F10单步运行后,发现程序已经跳转到了PA_IRQ中断服务子程序中,继续F10单步运行并观察执行每一步的现象,直到把中断服务子程序走完。