STM32的NVIC理解

Reference Datasheet中是这样说的



SCB->AIRCR中目前只用到4位,也就是最高能有16级中断嵌套,如果全使用的话可以达到256级


选用优先级分组(实际就是选几位用于主优先级几位用于辅优先级)

注意,我们在一个工程中只能用一种分组方式


The table below gives the allowed values of the pre-emption priority and subpriority according
 to the Priority Grouping configuration performed by NVIC_PriorityGroupConfig function
  ===========================================================================
    NVIC_PriorityGroup   | NVIC_IRQChannelPreemptionPriority | NVIC_IRQChannelSubPriority  | Description
  ===========================================================================
   NVIC_PriorityGroup_0  |                0                  |            0-15             |   0 bits for pre-emption priority
                                       |                                    |                                |   4 bits for subpriority
  ----------------------------------------------------------------------------------------------------------------------------
   NVIC_PriorityGroup_1  |                0-1               |            0-7              |   1 bits for pre-emption priority
                                       |                                     |                               |   3 bits for subpriority
  ----------------------------------------------------------------------------------------------------------------------------   
   NVIC_PriorityGroup_2  |                0-3                |            0-3              |   2 bits for pre-emption priority
                                       |                                     |                               |   2 bits for subpriority
  ----------------------------------------------------------------------------------------------------------------------------   
   NVIC_PriorityGroup_3  |                0-7                |            0-1              |   3 bits for pre-emption priority
                                       |                                      |                               |   1 bits for subpriority
  ----------------------------------------------------------------------------------------------------------------------------   
   NVIC_PriorityGroup_4  |                0-15              |            0                 |   4 bits for pre-emption priority
                                        |                                     |                              |   0 bits for subpriority

以上是我提取库中misc.h中的说明便于大家理解


我的分析:

STM32有43个channel的settable的中断源;AIRC(Application Interrupt and Reset Register)寄存器中有用于指定优先级的4 bits。这4个bits用于分配preemption优先级和sub优先级,在STM32的固件库中定义如下

#define NVIC_PriorityGroup_0 ((u32)0x700)
#define NVIC_PriorityGroup_1 ((u32)0x600)
#define NVIC_PriorityGroup_2 ((u32)0x500)
#define NVIC_PriorityGroup_3 ((u32)0x400)
#define NVIC_PriorityGroup_4 ((u32)0x300)

形象化的理解是:

你是上帝,造了43个人,这么多人要分社会阶级和社会阶层了;因为“阶级”的词性比较重;"阶层"比较中性,所以preemption优先级->阶级;每个阶级内部,有一些阶层,sub优先级->阶层;

如果按照NVIC_PriorityGroup_4这么分,就分为了16个阶级(1个阶层就是1个preemption优先级),0个阶层;高阶级的人,可以打断低阶级的正在做事的人(嵌套),最多可以完成1个中断和15级嵌套。
每个阶级(每个preemption优先级),你来指定这43人中,谁进入该阶级;一个人叫EXTI0_IRQChannel,你指定他进入“阶级8”,则
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPrio rity = 8; // 指定抢占式优先级别1,可取0-15

另外,在同一阶级内部,一个人在做事的时候,另外一个人不能打断他;(preemption优先级别相同的中断源之间没有嵌套关系)
还有,如果他们两个同时想做事,因为没有阶层,那么就根据Vector table中的物理排序,让排名靠前的人去做;

又有1个人SPI1_IRQChannel,设定如下
NVIC_InitStructure.NVIC_IRQChannel = SPI1_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPrio rity = 0; // 指定抢占式优先级别1,可取0-15

SPI1_IRQChannel的阶级高,EXTI0_IRQChannel做事的时候可以打断(嵌套)。


如果按照NVIC_PriorityGroup_3这么分,就分为了8个阶级(1个阶级是1个preemption优先级),每个阶级内有2个阶层(sub优先级);高阶级的人,可以打断低阶级的正在做事的人(嵌套),最多可以完成1个中断和7级嵌套。

每个阶级(每个preemption优先级),你来指定这43人中,谁进入该阶级;一个人叫EXTI0_IRQChannel,你指定他进入“阶级3”,则:
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPrio rity = 3; // 指定抢占式优先级别1,可取0-7
还需要指定他的阶层:
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // 指定响应优先级别0,可取0-1

另有1个人叫EXTI9_5_IRQChannel,他的阶级和阶层设定如下
NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPrio rity = 3; // 指定抢占式优先级别0,可取0-7
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; // 指定响应优先级别1

那么这两个人是同一阶级的兄弟,一个人在做事的时候,另外一个人不能打断他;(preemption优先级别相同的中断源之间没有嵌套关系)
如果他们两个同时想做事,因为前者的阶层高,所以前者优先。

还有一个人叫USART1_IRQChannel,他的阶级和阶层设定如下
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPrio rity = 2; // 指定抢占式优先级别0,可取0-7
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; // 指定响应优先级别1

USART1_IRQChannel的优先级最高,当前面两个人做事的时候,他都可以打断(嵌套)。

以下的类推。


代码讲解:

如果要使用中断那就得把中断向量表( NVIC_VectTab_RAM或是 NVIC_VectTab_FLASH)先存储到存储器

void NVIC_Configuration(void)
{
         NVIC_InitTypeDef NVIC_InitStructure;
#ifdef VECT_TAB_RAM
         NVIC_SetVectorTable(NVIC_VectTab_RAM,0x0);
#else
         NVIC_SetVectorTable(NVIC_VectTab_FLASH,0x0);
#endif
         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);

         NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQChannel;
         NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
         NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
         NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 

         NVIC_Init(&NVIC_InitStructure); 
}

这里边包含一个条件编译,如果我们要把中断向量表存储在RAM或者FLASH就要定义相关的宏

后边选用优先级分组的0组,也就是0位用于主优先级,4位用于辅优先级

 

主优先级可以中断嵌套(可以抢占)

辅优先级不可以中断嵌套,只能在当前中断完成之后再相应优先级最高的

如果辅优先级相同则相应中断向量表靠前的

NVIC_IRQChannel 是说明用的哪种中断,包括所有的中断与异常(NVIC都管理,包括内核的)

 

讲到这里我们要提一下不可屏蔽中断(NMI),这个中断是不能屏蔽的,其他中断都是可以屏蔽的。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值