在学习STM32的时候对这个函数表示疑惑,不知道它的优先级是怎么设置的,所以对它学习了一下
精髓:优先级数值越小,优先级越高,抢占优先级>子优先级>IRQ编号,由此判定优先顺序
嵌套向量中断控制器NVIC
外部中断/事件控制器由20个产生事件/中断请求的边沿检测器组成,对于其它
产品,则有19个能产生事件/中断请求的边沿检测器。每个输入线可以独立地配置输入类型(脉冲
或挂起)和对应的触发事件(上升沿或下降沿或者双边沿都触发)。每个输入线都可以独立地被屏
蔽。挂起寄存器保持着状态线的中断请求。
主要特性
EXTI控制器的主要特性如下:
● 每个中断/事件都有独立的触发和屏蔽
● 每个中断线都有专用的状态位
● 支持多达20个软件的中断/事件请求
● 检测脉冲宽度低于APB2时钟宽度的外部信号。参见数据手册中电气特性部分的相关参数。
优先级概念
STM32中有两个优先级的概念:抢占式优先级和响应优先级(也叫副优先级)。
他们的特性是:
1:高抢占式优先级的中断可以嵌套在低抢占式优先级的中断中:即低抢占式优先级的中断可以被高抢占式优先级的中断打断;
2:当两个中断源的抢占式优先级相同时,这两个中断将没有嵌套关系,当一个中断到来后,如果正在处理另一个中断,这个后到来的中断就要等到前一个中断处理完之后才能被处理。
3:如果两个具有相同抢占式优先级的中断同时到达,那么系统给先处理高响应优先级的中断;
4:如果两个中断的抢占式优先级和响应优先级都相等,则根据他们在中断表中的排位顺序决定先处理哪一个。
它们的级别关系是: 抢占式优先级 > 响应优先级 > 中断表中的排位顺序。只有在上一级优先级相同时下一级优先级才会起作用。
代码解析
/**
* @brief 配置嵌套向量中断控制器NVIC
* @param 无
* @retval 无
*/
static void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
/* 嵌套向量中断控制器组选择 */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
/* 配置USART为中断源 */
NVIC_InitStructure.NVIC_IRQChannel = DEBUG_USART_IRQ;
/* 抢断优先级为1 */
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
/* 子优先级为1 */
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
/* 使能中断 */
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
/* 初始化配置NVIC */
NVIC_Init(&NVIC_InitStructure);
}
NVIC_PriorityGroupConfig函数
可配置选项
#define NVIC_PriorityGroup_0 ((uint32_t)0x700) /*!< 0 bits for pre-emption priority
4 bits for subpriority */
#define NVIC_PriorityGroup_1 ((uint32_t)0x600) /*!< 1 bits for pre-emption priority
3 bits for subpriority */
#define NVIC_PriorityGroup_2 ((uint32_t)0x500) /*!< 2 bits for pre-emption priority
2 bits for subpriority */
#define NVIC_PriorityGroup_3 ((uint32_t)0x400) /*!< 3 bits for pre-emption priority
1 bits for subpriority */
#define NVIC_PriorityGroup_4 ((uint32_t)0x300) /*!< 4 bits for pre-emption priority
0 bits for subpriority */
第0组 NVIC_PriorityGroup_0 使用0bits表示抢占式优先级------NVIC_IRQChannelPreemptionPriority无效,4bits表示响应优先级--NVIC_IRQChannelSubPriority值可为0~15。因此,在这一组中的中断没有抢占式优先级,只有响应优先级,它们互相不可打断。
第1组 NVIC_PriorityGroup_1 使用1bits表示抢占优先级------NVIC_IRQChannelPreemptionPriority值可为0~1,使用3bits表示响应优先级NVIC_IRQChannelSubPriority值可为0~8。
第2组 NVIC_PriorityGroup_2 使用2bits表示抢占优先级------NVIC_IRQChannelPreemptionPriority值可为0~3,使用2bits表示响应优先级NVIC_IRQChannelSubPriority值可为0~3。
第3组 NVIC_PriorityGroup_3 使用3bits表示抢占优先级------NVIC_IRQChannelPreemptionPriority值可为0~7,使用1bits表示响应优先级NVIC_IRQChannelSubPriority值可为0~1。
第4组 NVIC_PriorityGroup_4 使用4bits表示抢占优先级------NVIC_IRQChannelPreemptionPriority值可为0~15,使用0bits表示响应优先级NVIC_IRQChannelSubPriority值可为0无效。
无论使用哪一组,其优先级总数(抢占优先级*响应优先级)都是16.
中断源设置NVIC_IRQChannel
中断根据不同芯片的设置大同小异,都可以在stmfxxx.h,比如我是stm32f407就在stm32f4xxx.h中
在具体的不用型号的芯片中在头部的宏定义都是有分类的
#if defined(STM32F40_41xxx)
CAN1_TX_IRQn = 19, /*!< CAN1 TX Interrupt */
CAN1_RX0_IRQn = 20, /*!< CAN1 RX0 Interrupt */
CAN1_RX1_IRQn = 21, /*!< CAN1 RX1 Interrupt */
CAN1_SCE_IRQn = 22, /*!< CAN1 SCE Interrupt */
EXTI9_5_IRQn = 23, /*!< External Line[9:5] Interrupts */
TIM1_BRK_TIM9_IRQn = 24, /*!< TIM1 Break interrupt and TIM9 global interrupt */
TIM1_UP_TIM10_IRQn = 25, /*!< TIM1 Update Interrupt and TIM10 global interrupt */
TIM1_TRG_COM_TIM11_IRQn = 26, /*!< TIM1 Trigger and Commutation Interrupt and TIM11 global interrupt */
TIM1_CC_IRQn = 27, /*!< TIM1 Capture Compare Interrupt */
TIM2_IRQn = 28, /*!< TIM2 global Interrupt */
TIM3_IRQn = 29, /*!< TIM3 global Interrupt */
TIM4_IRQn = 30, /*!< TIM4 global Interrupt */
I2C1_EV_IRQn = 31, /*!< I2C1 Event Interrupt */
I2C1_ER_IRQn = 32, /*!< I2C1 Error Interrupt */
I2C2_EV_IRQn = 33, /*!< I2C2 Event Interrupt */
I2C2_ER_IRQn = 34, /*!< I2C2 Error Interrupt */
SPI1_IRQn = 35, /*!< SPI1 global Interrupt */
SPI2_IRQn = 36, /*!< SPI2 global Interrupt */
USART1_IRQn = 37, /*!< USART1 global Interrupt */
USART2_IRQn = 38, /*!< USART2 global Interrupt */
USART3_IRQn = 39, /*!< USART3 global Interrupt */
EXTI15_10_IRQn = 40, /*!< External Line[15:10] Interrupts */
RTC_Alarm_IRQn = 41, /*!< RTC Alarm (A and B) through EXTI Line Interrupt */
OTG_FS_WKUP_IRQn = 42, /*!< USB OTG FS Wakeup through EXTI line interrupt */
TIM8_BRK_TIM12_IRQn = 43, /*!< TIM8 Break Interrupt and TIM12 global interrupt */
TIM8_UP_TIM13_IRQn = 44, /*!< TIM8 Update Interrupt and TIM13 global interrupt */
TIM8_TRG_COM_TIM14_IRQn = 45, /*!< TIM8 Trigger and Commutation Interrupt and TIM14 global interrupt */
TIM8_CC_IRQn = 46, /*!< TIM8 Capture Compare Interrupt */
DMA1_Stream7_IRQn = 47, /*!< DMA1 Stream7 Interrupt */
FSMC_IRQn = 48, /*!< FSMC global Interrupt */
SDIO_IRQn = 49, /*!< SDIO global Interrupt */
TIM5_IRQn = 50, /*!< TIM5 global Interrupt */
SPI3_IRQn = 51, /*!< SPI3 global Interrupt */
UART4_IRQn = 52, /*!< UART4 global Interrupt */
UART5_IRQn = 53, /*!< UART5 global Interrupt */
TIM6_DAC_IRQn = 54, /*!< TIM6 global and DAC1&2 underrun error interrupts */
TIM7_IRQn = 55, /*!< TIM7 global interrupt */
DMA2_Stream0_IRQn = 56, /*!< DMA2 Stream 0 global Interrupt */
DMA2_Stream1_IRQn = 57, /*!< DMA2 Stream 1 global Interrupt */
DMA2_Stream2_IRQn = 58, /*!< DMA2 Stream 2 global Interrupt */
DMA2_Stream3_IRQn = 59, /*!< DMA2 Stream 3 global Interrupt */
DMA2_Stream4_IRQn = 60, /*!< DMA2 Stream 4 global Interrupt */
ETH_IRQn = 61, /*!< Ethernet global Interrupt */
ETH_WKUP_IRQn = 62, /*!< Ethernet Wakeup through EXTI line Interrupt */
CAN2_TX_IRQn = 63, /*!< CAN2 TX Interrupt */
CAN2_RX0_IRQn = 64, /*!< CAN2 RX0 Interrupt */
CAN2_RX1_IRQn = 65, /*!< CAN2 RX1 Interrupt */
CAN2_SCE_IRQn = 66, /*!< CAN2 SCE Interrupt */
OTG_FS_IRQn = 67, /*!< USB OTG FS global Interrupt */
DMA2_Stream5_IRQn = 68, /*!< DMA2 Stream 5 global interrupt */
DMA2_Stream6_IRQn = 69, /*!< DMA2 Stream 6 global interrupt */
DMA2_Stream7_IRQn = 70, /*!< DMA2 Stream 7 global interrupt */
USART6_IRQn = 71, /*!< USART6 global interrupt */
I2C3_EV_IRQn = 72, /*!< I2C3 event interrupt */
I2C3_ER_IRQn = 73, /*!< I2C3 error interrupt */
OTG_HS_EP1_OUT_IRQn = 74, /*!< USB OTG HS End Point 1 Out global interrupt */
OTG_HS_EP1_IN_IRQn = 75, /*!< USB OTG HS End Point 1 In global interrupt */
OTG_HS_WKUP_IRQn = 76, /*!< USB OTG HS Wakeup through EXTI interrupt */
OTG_HS_IRQn = 77, /*!< USB OTG HS global interrupt */
DCMI_IRQn = 78, /*!< DCMI global interrupt */
CRYP_IRQn = 79, /*!< CRYP crypto global interrupt */
HASH_RNG_IRQn = 80, /*!< Hash and Rng global interrupt */
FPU_IRQn = 81 /*!< FPU global interrupt */
#endif /* STM32F40_41xxx */
优先级设置
优先级设置跟NVIC_PriorityGroupConfig嵌套向量中断控制器组选择、NVIC_IRQChannelPreemptionPriority、NVIC_IRQChannelSubPriority是有关系的
设置控制器组后要这么配置抢占优先级和子优先级看如下
============================================================================================================================
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