2019-07-21 04:17发布
hougeqvjing 发表于 2018-7-30 23:26 就是小于0的中断号,不归NIVC管?
hougeqvjing 发表于 2018-7-31 23:05 NVIC里面不能设置SYSTICK的优先级,也不能开启systick的优先级,为什么说是systick绑定在NVIC中呢?中断 ...
warship 发表于 2018-8-1 17:35 3、NVIC的寄存器管理着包括系统异常(小于0)和外部中断(0-240)的所有中断的优先级。有如下三处与优先 ...
最多设置5个标签!
当然也要归nvic管了,只不过小于0的中断比较重要,影响全局,由nvic亲自管理,相当于中央直属单位
1、NVIC功能强大,将“异常”的概念发挥到了极致,可以说,搞懂了NVIC,就基本掌握了CM3内核的90%以上,因此,它的寄存器数量庞大,你翻看一下权威指南的附录D,就是NVIC寄存器小结,列出了它的所有寄存器,而SYSTICK的区区几个寄存器严格来说也属于NVIC的寄存器,NVIC管理着全天下所有异常的优先级,当然也包括SYSTICK的优先级,系统内核的异常的优先级存放在NVIC的SCB->SHP[12]中(与外部中断IP[240]类似),因为有三个系统异常的优先级是固定的,加上一个保留位置无须设优先级,所以只须16-3-1=12个字节,下标从0到11,SYSTICK为最后一个,即NVIC的SCB->SHP[11]中就存放着SYSTICK的中断优先级(我上次曾让你查看过这个寄存器,系统复位时它的值为0,实际对应最高优先级),你可以通过指令:SCB->SHP[11]=0xF0; 就可以让它的优先级为最低。另有中断控制及状态寄存器ICSR、系统Handler控制及状态寄存器SHCSR可以控制和监视系统级的异常,SYSTICK当然逃不出如来的手心了。另外,我认为不能单纯通过字面如NVIC->IP[240] 及 SCB->AIRCR中的寄存器字冠来说SCB不属于NVIC的寄存器,事实上只有与外部中断相关的一组寄存器(主要是240个中断的中断优先级、使能/除能、挂起/解挂、活动状态等寄存器)冠以NVIC以外,大量NVIC的寄存器族都另起了其它的名称,如SCB、VTOR、SYSTICK等等,具体查看权威指南的附录D。因为NVIC的寄存器种类庞大,地址跨度很大,用单一的结构体来访问比较令人头大,且不如分开成多个意义更明确。
2、你说的表中的优先级那一栏,我没有看到进一步的说明,可以理解为优先级排序,越排在前面优先级越高,前3个为负数并且值为固定,这是权威指南中有说明的,至于后面的从0开始到好几十(理论上可以至多排到240),没有太多实际意义,不是默认优先级,因为实际的芯片优先级没有那么多,我的理解是:当两个中断优先级设置完全相同时,这个排序决定了谁将会优先得到响应(表中数值小者优先)。
3、NVIC的寄存器管理着包括系统异常(小于0)和外部中断(0-240)的所有中断的优先级。有如下三处与优先级设置相关的寄存器:
一是应用程序中断及复位控制寄存器(AIRCR)的10:8这三位,用于定义全系统的优先级分组,它定义了如何去解读每一个中断优先级设定值的具体含义(即哪几位代表抢占级,哪几位代表响应级?)
二是系统异常(中断号小于0的)的中断优先级。就是第1点已经回答的SCB的SHP[12],共12个8BIT的数组,其中SHP[11]里存放着SYSTICK的优先级;
三是所有外部中断(中断号大于等于0的)的优先级,存放在IP[240]中,共240个8BIT的数组,可以通过各个中断号作为数组下标来访问。例如:如果想设置EXTI0_IRQn的优先级为最高,使用指令: NVIC->IP[6]=0x00; 就可以了(EXTI0_IRQn中断号为6)。
注意:以上二和三项的表示方法是统一的,每一个中断都可以最大用8BIT定义中断优先级,但我们常用的具体芯片只实现了4BIT,即只有高四位有效。
好点,嗯嗯。我看了下优先级分组的函数如下:
static void MY_NVIC_PriorityGroupConfig(u32 PriorityGroup)
{
uint32_t reg_value;
uint32_t PriorityGroupTmp = (PriorityGroup & 0x07);
reg_value = SCB->AIRCR;
reg_value &= ~(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk);
reg_value = (reg_value |
(0x5FA << SCB_AIRCR_VECTKEY_Pos) |
(PriorityGroupTmp << 8));
SCB->AIRCR = reg_value;
}
优先级分组展开为:0x700,0x600,,,,,我怎么感觉该函数应该为下面这样呢?
不知理解得对不对?
static void MY_NVIC_PriorityGroupConfig(u32 PriorityGroup)
{
uint32_t reg_value;
uint32_t PriorityGroupTmp = PriorityGroup;
reg_value = SCB->AIRCR;
reg_value &= ~(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk);
reg_value = (reg_value |
(0x5FA << SCB_AIRCR_VECTKEY_Pos) |
(PriorityGroupTmp));
SCB->AIRCR = reg_value;
}
一周热门 更多>