1. 中斷類型
在此不嚴格區分中斷和異常,即簡單的認爲中斷與異常一個概念。
M4 內核搭載了異常響應系統,支持衆多的系統異常和外部中斷。其中,F429芯片,系統異常10個,外部中斷91個。除個別異常的優先級固定外,其它均可編程。stm32f4xx.h
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(STM32F429_439xx) 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 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 */ FMC_IRQn = 48, /*!< FMC 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_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 */ UART7_IRQn = 82, /*!< UART7 global interrupt */ UART8_IRQn = 83, /*!< UART8 global interrupt */ SPI4_IRQn = 84, /*!< SPI4 global Interrupt */ SPI5_IRQn = 85, /*!< SPI5 global Interrupt */ SPI6_IRQn = 86, /*!< SPI6 global Interrupt */ SAI1_IRQn = 87, /*!< SAI1 global Interrupt */ LTDC_IRQn = 88, /*!< LTDC global Interrupt */ LTDC_ER_IRQn = 89, /*!< LTDC Error global Interrupt */ DMA2D_IRQn = 90 /*!< DMA2D global Interrupt */ #endif /* STM32F429_439xx */ } IRQn_Type;
2. NVIC 概述
NVIC是嵌套向量中斷控制器,控制着整個芯片中斷相關的功能,它跟內核緊密耦合,是內核裏面的一個外設。但是各個芯片廠商在設計芯片的時候會對Cortex-M4內核裏面的NVIC進行裁剪,把不需要的部分去掉,所以說STM32的NVIC是Cortex-M4的NVIC的一個子集。
NVIC結構體定義,來自固件庫頭文: core_cm4.
在配置中斷的時候我們一般只用ISER、ICER和IP這三個寄存器,ISER用來使能中斷,ICER用來失能中斷,IP用來設置中斷優先級。
/** 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;
注:系統異常優先級配置擁有獨立於外設優先級配置的寄存器
3. 中斷優先級
在NVIC 有一個專門的寄存器:中斷優先級寄存器NVIC_IPRx(在F429中,x=0...90)用來配置外部中斷的優先級,IPR寬度爲8bit,原則上每個外部中斷可配置的優先級爲0~255,數值越小,優先級越高。但是絕大多數CM4芯片都會精簡設計,以致實際上支持的優先級數減少,在F429中,只使用了高4bit。
F429 使用 4bit表達優先級 表達優先級
用於表達優先級的這4bit,又被分組成搶佔優先級和子優先級。如果有多箇中斷同時響應,搶佔優先級高的就會 搶佔 搶佔優先級低的優先得到執行,如果搶佔優先級相同,就比較子優先級。如果搶佔優先級和子優先級都相同的話,就比較他們的硬件中斷編號,編號越小,優先級越高。
4. 優先級分組
優先級的分組由內核外設SCB的應用程序中斷及復位控制寄存器AIRCR的PRIGROUP[10:8]位決定,F429分爲了5組,具體如下:主優先級=搶佔優先級。
設置優先級分組可調用庫函數NVIC_PriorityGroupConfig()實現,有關NVIC中斷相關的庫函數都在庫文件misc.c和misc.h中。
優先級分組真值表
5. 編程要點
使能外設某個中斷,這個具體由每個外設的相關中斷使能位控制
初始化NVIC_InitTypeDef結構體,配置中斷優先級分組,設置搶佔優先級和子優先級,使能中斷請求
編寫中斷服務函數,短小精悍。
最後在個大家提供一些stm32方面的參考資料
(時鐘系統)
http://www.makeru.com.cn/live/1392_1082.html?s=45051
STM32中斷系統
http://www.makeru.com.cn/live/3523_1745.html?s=45051
(stm32串口應用)
http://www.makeru.com.cn/live/1392_1164.html?s=45051