【STM32】中断优先级管理
00. 目錄
文章目錄
- 00. 目錄
- 01. 概述
- 02. 結構體聲明
- 03. 中斷分組
- 04. 相關類型
- 05. 相關函數
- 06. 附錄
- 07. 聲明
01. 概述
CM4 內核支持 256 個中斷,其中包含了 16 個內核中斷和 240 個外部中斷,并且具有256 級的可編程中斷設置。但 STM32F4 并沒有使用 CM4 內核的全部東西,而是只用了它的一部分。
STM32F40xx/STM32F41xx 總共有 92 個中斷,STM32F42xx/STM32F43xx 則總共有 96 個中斷,STM32F40xx/STM32F41xx 的 92 個中斷里面,包括 10 個內核中斷和 82 個可屏蔽中斷,具有16級可編程的中斷優先級,而我們常用的就是這82個可屏蔽中斷。
02. 結構體聲明
core_cm4.h文件中
/** \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC).*/ typedef struct {__IO uint32_t ISER[8]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */uint32_t RESERVED0[24];__IO uint32_t ICER[8]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */uint32_t RSERVED1[24];__IO uint32_t ISPR[8]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */uint32_t RESERVED2[24];__IO uint32_t ICPR[8]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */uint32_t RESERVED3[24];__IO uint32_t IABR[8]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */uint32_t RESERVED4[56];__IO uint8_t IP[240]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */uint32_t RESERVED5[644];__O uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ } NVIC_Type;STM32F4 的中斷在這些寄存器的控制下有序的執行的。只有了解這些中斷寄存器,才能方便的使用 STM32F4 的中斷。
ISER[8]:ISER 全稱是:Interrupt Set-Enable Registers,這是一個中斷使能寄存器組。上面說了 CM4 內核支持 256 個中斷,這里用 8 個 32 位寄存器來控制,每個位控制一個中斷。但是STM32F4 的可屏蔽中斷最多只有 82 個,所以對我們來說,有用的就是三個(ISER[0~2]),總共可以表示 96 個中斷。而 STM32F4 只用了其中的前 82 個。ISER[0]的 bit0~31 分別對應中斷0~31;ISER[1]的 bit0~32 對應中斷 32~63;ISER[2]的 bit0~17 對應中斷 64~81;這樣總共 82 個中斷就分別對應上了。你要使能某個中斷,必須設置相應的 ISER 位為 1,使該中斷被使能(這里僅僅是使能,還要配合中斷分組、屏蔽、IO 口映射等設置才算是一個完整的中斷設置)。具體每一位對應哪個中斷,請參考 stm32f4xx.h 里面的第 188 行處。
ICER[8]:全稱是:Interrupt Clear-Enable Registers,是一個中斷除能寄存器組。該寄存器組與 ISER 的作用恰好相反,是用來清除某個中斷的使能的。其對應位的功能,也和 ICER 一樣。這里要專門設置一個 ICER 來清除中斷位,而不是向 ISER 寫 0 來清除,是因為 NVIC 的這些寄存器都是寫 1 有效的,寫 0 是無效的。
ISPR[8]:全稱是:Interrupt Set-Pending Registers,是一個中斷掛起控制寄存器組。每個位對應的中斷和 ISER 是一樣的。通過置 1,可以將正在進行的中斷掛起,而執行同級或更高級別的中斷。寫 0 是無效的。
ICPR[8]:全稱是:Interrupt Clear-Pending Registers,是一個中斷解掛控制寄存器組。其作用與 ISPR 相反,對應位也和 ISER 是一樣的。通過設置 1,可以將掛起的中斷接掛。寫 0 無效。
IABR[8]:全稱是:Interrupt Active Bit Registers,是一個中斷激活標志位寄存器組。對應位所代表的中斷和 ISER 一樣,如果為 1,則表示該位所對應的中斷正在被執行。這是一個只讀寄存器,通過它可以知道當前在執行的中斷是哪一個。在中斷執行完了由硬件自動清零。
IP[240]:全稱是:Interrupt Priority Registers,是一個中斷優先級控制的寄存器組。這個寄存器組相當重要!STM32F4 的中斷分組與這個寄存器組密切相關。IP 寄存器組由 240 個 8bit的寄存器組成,每個可屏蔽中斷占用 8bit,這樣總共可以表示 240 個可屏蔽中斷。而 STM32F4只用到了其中的 82 個。IP[81]~IP[0]分別對應中斷 81~0。而每個可屏蔽中斷占用的 8bit 并沒有全部使用,而是只用了高 4 位。這 4 位,又分為搶占優先級和響應優先級。搶占優先級在前,響應優先級在后。而這兩個優先級各占幾個位又要根據 SCB->AIRCR 中的中斷分組設置來決定。
03. 中斷分組
STM32F4 將中斷分為 5 個組,組 0~4。該分組的設置是由 SCB->AIRCR 寄存器的 bit10~8 來定義的。
我們就可以清楚的看到組 0~4 對應的配置關系,例如組設置為 3,那么此時所有的 82 個中斷,每個中斷的中斷優先寄存器的高四位中的最高 3 位是搶占優先級,低 1 位是響應優先級。每個中斷,你可以設置搶占優先級為 0~7,響應優先級為 1 或 0。搶占優先級的級別高于響應優先級。而數值越小所代表的優先級就越高。
這里需要注意兩點:第一,如果兩個中斷的搶占優先級和響應優先級都是一樣的話,則看哪個中斷先發生就先執行;第二,高優先級的搶占優先級是可以打斷正在進行的低搶占優先級中斷的。而搶占優先級相同的中斷,高優先級的響應優先級不可以打斷低響應優先級的中斷。
結合實例說明一下:假定設置中斷優先級組為 2,然后設置中斷 3(RTC_WKUP 中斷)的搶占優先級為 2,響應優先級為 1。中斷 6(外部中斷 0)的搶占優先級為 3,響應優先級為 0。中斷 7(外部中斷 1)的搶占優先級為 2,響應優先級為 0。那么這 3 個中斷的優先級順序為:中斷 7>中斷 3>中斷 6。
上面例子中的中斷 3 和中斷 7 都可以打斷中斷 6 的中斷。而中斷 7 和中斷 3 卻不可以相互打斷!
04. 相關類型
misc.h文件
NVIC_InitTypeDef類型
/** * @brief NVIC Init Structure definition */typedef struct {uint8_t NVIC_IRQChannel; /*!< Specifies the IRQ channel to be enabled or disabled.This parameter can be an enumerator of @ref IRQn_Type enumeration (For the complete STM32 Devices IRQ Channelslist, please refer to stm32f4xx.h file) */uint8_t NVIC_IRQChannelPreemptionPriority; /*!< Specifies the pre-emption priority for the IRQ channelspecified in NVIC_IRQChannel. This parameter can be a valuebetween 0 and 15 as described in the table @ref MISC_NVIC_Priority_TableA lower priority value indicates a higher priority */uint8_t NVIC_IRQChannelSubPriority; /*!< Specifies the subpriority level for the IRQ channel specifiedin NVIC_IRQChannel. This parameter can be a valuebetween 0 and 15 as described in the table @ref MISC_NVIC_Priority_TableA lower priority value indicates a higher priority */FunctionalState NVIC_IRQChannelCmd; /*!< Specifies whether the IRQ channel defined in NVIC_IRQChannelwill be enabled or disabled. This parameter can be set either to ENABLE or DISABLE */ } NVIC_InitTypeDef;MISC_Vector_Table_Base
/** @defgroup MISC_Vector_Table_Base * @{*/#define NVIC_VectTab_RAM ((uint32_t)0x20000000) #define NVIC_VectTab_FLASH ((uint32_t)0x08000000) #define IS_NVIC_VECTTAB(VECTTAB) (((VECTTAB) == NVIC_VectTab_RAM) || \((VECTTAB) == NVIC_VectTab_FLASH))MISC_System_Low_Power
/** @defgroup MISC_System_Low_Power * @{*/#define NVIC_LP_SEVONPEND ((uint8_t)0x10) #define NVIC_LP_SLEEPDEEP ((uint8_t)0x04) #define NVIC_LP_SLEEPONEXIT ((uint8_t)0x02) #define IS_NVIC_LP(LP) (((LP) == NVIC_LP_SEVONPEND) || \((LP) == NVIC_LP_SLEEPDEEP) || \((LP) == NVIC_LP_SLEEPONEXIT))MISC_Preemption_Priority_Group
/** @defgroup MISC_Preemption_Priority_Group * @{*/#define NVIC_PriorityGroup_0 ((uint32_t)0x700) /*!< 0 bits for pre-emption priority4 bits for subpriority */ #define NVIC_PriorityGroup_1 ((uint32_t)0x600) /*!< 1 bits for pre-emption priority3 bits for subpriority */ #define NVIC_PriorityGroup_2 ((uint32_t)0x500) /*!< 2 bits for pre-emption priority2 bits for subpriority */ #define NVIC_PriorityGroup_3 ((uint32_t)0x400) /*!< 3 bits for pre-emption priority1 bits for subpriority */ #define NVIC_PriorityGroup_4 ((uint32_t)0x300) /*!< 4 bits for pre-emption priority0 bits for subpriority */#define IS_NVIC_PRIORITY_GROUP(GROUP) (((GROUP) == NVIC_PriorityGroup_0) || \((GROUP) == NVIC_PriorityGroup_1) || \((GROUP) == NVIC_PriorityGroup_2) || \((GROUP) == NVIC_PriorityGroup_3) || \((GROUP) == NVIC_PriorityGroup_4))#define IS_NVIC_PREEMPTION_PRIORITY(PRIORITY) ((PRIORITY) < 0x10)#define IS_NVIC_SUB_PRIORITY(PRIORITY) ((PRIORITY) < 0x10)#define IS_NVIC_OFFSET(OFFSET) ((OFFSET) < 0x000FFFFF)MISC_SysTick_clock_source
/** @defgroup MISC_SysTick_clock_source * @{*/#define SysTick_CLKSource_HCLK_Div8 ((uint32_t)0xFFFFFFFB) #define SysTick_CLKSource_HCLK ((uint32_t)0x00000004) #define IS_SYSTICK_CLK_SOURCE(SOURCE) (((SOURCE) == SysTick_CLKSource_HCLK) || \((SOURCE) == SysTick_CLKSource_HCLK_Div8))中斷名字(stm32f4xx.h)
/*** @brief STM32F4XX Interrupt Number Definition, according to the selected device * in @ref Library_configuration_section */ typedef enum IRQn { /****** Cortex-M4 Processor Exceptions Numbers ****************************************************************/NonMaskableInt_IRQn = -14, /*!< 2 Non Maskable Interrupt */MemoryManagement_IRQn = -12, /*!< 4 Cortex-M4 Memory Management Interrupt */BusFault_IRQn = -11, /*!< 5 Cortex-M4 Bus Fault Interrupt */UsageFault_IRQn = -10, /*!< 6 Cortex-M4 Usage Fault Interrupt */SVCall_IRQn = -5, /*!< 11 Cortex-M4 SV Call Interrupt */DebugMonitor_IRQn = -4, /*!< 12 Cortex-M4 Debug Monitor Interrupt */PendSV_IRQn = -2, /*!< 14 Cortex-M4 Pend SV Interrupt */SysTick_IRQn = -1, /*!< 15 Cortex-M4 System Tick Interrupt */ /****** STM32 specific Interrupt Numbers **********************************************************************/WWDG_IRQn = 0, /*!< Window WatchDog Interrupt */PVD_IRQn = 1, /*!< PVD through EXTI Line detection Interrupt */TAMP_STAMP_IRQn = 2, /*!< Tamper and TimeStamp interrupts through the EXTI line */RTC_WKUP_IRQn = 3, /*!< RTC Wakeup interrupt through the EXTI line */FLASH_IRQn = 4, /*!< FLASH global Interrupt */RCC_IRQn = 5, /*!< RCC global Interrupt */EXTI0_IRQn = 6, /*!< EXTI Line0 Interrupt */EXTI1_IRQn = 7, /*!< EXTI Line1 Interrupt */EXTI2_IRQn = 8, /*!< EXTI Line2 Interrupt */EXTI3_IRQn = 9, /*!< EXTI Line3 Interrupt */EXTI4_IRQn = 10, /*!< EXTI Line4 Interrupt */DMA1_Stream0_IRQn = 11, /*!< DMA1 Stream 0 global Interrupt */DMA1_Stream1_IRQn = 12, /*!< DMA1 Stream 1 global Interrupt */DMA1_Stream2_IRQn = 13, /*!< DMA1 Stream 2 global Interrupt */DMA1_Stream3_IRQn = 14, /*!< DMA1 Stream 3 global Interrupt */DMA1_Stream4_IRQn = 15, /*!< DMA1 Stream 4 global Interrupt */DMA1_Stream5_IRQn = 16, /*!< DMA1 Stream 5 global Interrupt */DMA1_Stream6_IRQn = 17, /*!< DMA1 Stream 6 global Interrupt */ADC_IRQn = 18, /*!< ADC1, ADC2 and ADC3 global Interrupts */#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 */05. 相關函數
/* Exported macro ------------------------------------------------------------*/ /* Exported functions --------------------------------------------------------*/void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup); void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct); void NVIC_SetVectorTable(uint32_t NVIC_VectTab, uint32_t Offset); void NVIC_SystemLPConfig(uint8_t LowPowerMode, FunctionalState NewState); void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource);06. 附錄
6.1 【STM32】STM32系列教程匯總
網址:【STM32】STM32系列教程匯總
07. 聲明
該教程參考了正點原子的《STM32 F4 開發指南》
總結
以上是生活随笔為你收集整理的【STM32】中断优先级管理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【STM32】中断相关函数和类型
- 下一篇: 【STM32】外部中断