关于STM32 NVIC 中断优先级管理 也是由一系列寄存器组组成的
对于初学者而言,很对寄存器是不需要太深的研究,因为系统默认已经配置好了,但这里也给大家简单介绍一下
如 ISER[8]: ISER 全称是: Interrupt Set-Enable Registers,这是一个中断使能寄存器组。
ICER[8]:全称是: Interrupt Clear-Enable Registers,是一个中断除能寄存器组
ISPR[8]:全称是: Interrupt Set-Pending Registers,是一个中断挂起控制寄存器组
ICPR[8]:全称是: Interrupt Clear-Pending Registers,是一个中断解挂控制寄存器组
IABR[8]:全称是: Interrupt Active Bit Registers,是一个中断激活标志位寄存器组
IP[240]:全称是: Interrupt Priority Registers,是一个中断优先级控制的寄存器组
对于每个寄存器后面中括号 数字标识的意义是 该中断组是由几个32位的寄存器所组成 stm32是由一个很强大的系统中断所组成的,每个IO都对应一个中断
而每个寄存器的每一位同样控制着不同的中断 对于更细致的对应关系读者可根据查看相应的参考手册。
对于初学者,主要所掌握的寄存器,IP[240]中断优先级控制的寄存器组,前边所讲的基本也是废话,接下来就是今天所要掌握的。
(IP[240]STM32 的中断分组与这个寄存器组密切相关。 IP 寄存器组由 240 个 8bit 的寄
存器组成,每个可屏蔽中断占用 8bit,这样总共可以表示 240 个可屏蔽中断。 而 STM32 只用到
了其中的前 60 个。 IP[59]~IP[0]分别对应中断 59~0。 而每个可屏蔽中断占用的 8bit 并没有全部
使用,而是 只用了高 4 位。这 4 位,又分为抢占优先级和子优先级。抢占优先级在前,子优先
级在后。而这两个优先级各占几个位又要根据 SCB->AIRCR 中的中断分组设置来决定.)
每个中断都是由该寄存器组中寄存器的高四位来控制中断处理优先级,而这四位对于两种中断响应的控制关系并不是固定的。
以抢占优先级所占位数为理解可分0、1、2、3、4 共五种情况
要知道的是抢占优先是大于响应优先的,了解了中断响应分组原理对相应函数的使用就会更轻松。接下来看一下相应函数的使用。
首先要讲解的是中断优先级分组函数 NVIC_PriorityGroupConfig,其函数申明如下:
void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup);
看一下函数定义
void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup)
{
assert_param(IS_NVIC_PRIORITY_GROUP(NVIC_PriorityGroup));
SCB->AIRCR = AIRCR_VECTKEY_MASK | NVIC_PriorityGroup;
}
这个函数唯一目的就是通过设置 SCB->AIRCR 寄存器来设置中断优先级分组,而且这个函数在系统中只能被调用一次,一旦分组确定就最好不要更改。
同样系统也已经宏定义好了各分组名称,只需要调用就可以。
比如我们设置整个系统的中断优先级分组值为 2,那么方法是:
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
中断优先级分组是与多个中断密不可分的,在后续中断中其作用会很明显。
设置好了系统中断分组,那么对于每个中断我们又怎么确定他的抢占优先级和响应优先级
呢?下面我们讲解一个重要的函数为中断初始化函数 NVIC_Init();
void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct)
其中 NVIC_InitTypeDef 是一个结构体,我们可以看看结构体的成员变量:
typedef struct
{
uint8_t NVIC_IRQChannel; // 定义初始化的是哪个中断
uint8_t NVIC_IRQChannelPreemptionPriority; //定义这个中断的抢占优先级别
uint8_t NVIC_IRQChannelSubPriority; //定义这个中断的子优先级别
FunctionalState NVIC_IRQChannelCmd; //该中断是否使能
}NVIC_InitTypeDef;
比如我们要使能串口 1 的中断,同时设置抢占优先级为 1,子优先级位 2,初始化的方法是:
NVIC_InitTypeDef | NVIC_InitStructure; |
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; //串口 1 中断 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1 ;// 抢占优先级为 1 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;// 子优先级位 2 |
|
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; | //IRQ 通道使能 |
NVIC_Init(&NVIC_InitStructure); | //根据上面指定的参数初始化 NVIC 寄存器 |
这里优先级分组为分组2
则抢占优先级可设置为0-3 子优先级为0-3 抢占>响应 同优先级 数值小优先中断。
数值
中断响应
有几个