目錄
eg:STM32F407ZGT6
1:NVIC(嵌套向量中斷控制器)
在參考手冊的描述中(我就直接Copy了哈):
嵌套向量中斷控制器 NVIC 包含以下特性:● STM32F405xx/07xx 和 STM32F415xx/17xx 具有 82 個可屏蔽中斷通道,STM32F42xxx和 STM32F43xxx 具有多達 86 個可屏蔽中斷通道(不包括 Cortex™-M4F 的 16 根中 斷線)● 16 個可編程優先級(使用了 4 位中斷優先級)● 低延遲異常和中斷處理● 電源管理控制● 系統控制寄存器的實現嵌套向量中斷控制器 (NVIC) 和處理器內核接口緊密配合,可以實現低延遲的中斷處理和晚到中斷的高效處理。F4是用的CM4內核,而CM4內核支持256箇中斷,其中包含了16個內核中斷和240個外部中斷,並且具用256級的可編程中斷設置。SO————STM32F407ZGT6用到的中斷資源只是CM4內核中斷資源的一部分敲黑板:
STM32F40xx/STM32F41xx的92箇中斷裏面,包括10個內核中斷和82個可屏蔽中斷,具有16級可編程的中斷優先級,而我們常用的就是這82個可屏蔽中斷。(具體的參數可以去看相應芯片的數據手冊)
2:搶佔優先級&響應優先級
就是兩種中斷的級別,可以組合。
- 高優先級的搶佔優先級是可以打斷正在進行的低搶佔優先級中斷的
- 搶佔優先級相同的中斷,高響應優先級不可以打斷低響應優先級的中斷
- 搶佔優先級相同的中斷,當兩個中斷同時發生的情況下,哪個響應優先級高,哪個先執行
- 如果兩個中斷的搶佔優先級和響應優先級是一樣的,那就看哪個先發生就安排哪個。
假設先設置中斷優先級分組爲2(下面會講中斷優先級分組)
然後設置中斷A的搶佔優先級爲2,響應優先級爲1
中斷B的搶佔優先級爲3,響應優先級爲0
中斷C的搶佔優先級爲2,響應優先級爲0
那麼這三個中斷的優先級順序爲: C>=A>B (號子越小越牛逼)
3:中斷管理的方法
首先,要對STM32中斷進行分組,組0~4。同時,對每個中斷設置一個搶佔優先級和一個響應優先級
寫代碼的時候,先設置完一次中斷優先級分組後,就不要去改變了,隨意的分組會導致中斷管理混亂。且後面所有的中斷都要滿足你這個分組的要求,比如,我設置爲組2,那麼你後面所有的中斷搶佔和響應優先級都不能高於0x03
分組配置是在應用程序中斷及復位控制寄存器SCB->AIRCR中配置
/* Set the PRIGROUP[10:8] bits according to NVIC_PriorityGroup value */ SCB->AIRCR = AIRCR_VECTKEY_MASK | NVIC_PriorityGroup;
OK,有了中斷優先級的概念後,再來看中斷設置的相關寄存器
typedef struct { __IO uint32_t ISER[8]; /*!< Offset: 0x000 (R/W) 中斷使能寄存器組 */ uint32_t RESERVED0[24]; __IO uint32_t ICER[8]; /*!< Offset: 0x080 (R/W) 中斷失能寄存器組 */ uint32_t RSERVED1[24]; __IO uint32_t ISPR[8]; /*!< Offset: 0x100 (R/W) 中斷掛起寄存器組 */ uint32_t RESERVED2[24]; __IO uint32_t ICPR[8]; /*!< Offset: 0x180 (R/W) 中斷解掛寄存器組 */ uint32_t RESERVED3[24]; __IO uint32_t IABR[8]; /*!< Offset: 0x200 (R/W) 中斷激活標誌位寄存器組 */ uint32_t RESERVED4[56]; __IO uint8_t IP[240]; /*!< Offset: 0x300 (R/W) 中斷優先級控制寄存器組(8Bit wide) */ uint32_t RESERVED5[644]; __O uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ } NVIC_Type;
- IP[240]:Interrupt Priority Registers 中斷優先級控制的寄存器組240個8位寄存器,
每個中斷使用一個寄存器來確定優先級,前面介紹了,F40系列一共82個可屏蔽中斷,使用IP[81]~IP[0].
每個IP寄存器的高四位都用來設置搶佔和響應優先級(根據分組),低4位沒有用到
2:ISER[8]:中斷使能寄存器組
用來使能中斷的,32位寄存器,每個位控制一箇中斷的使能。一共82個可屏蔽中斷,所以只使用了其中的ISER[0]~ISER[2] (因爲是32位的)
- ISER[0]的bit0~bit31分別對應中斷0~31。
- ISER[1]的bit0~27對應中斷32~63;
- ISER[2]的bit0~17對應於中斷64~81
3:ICER[8]:中斷失能寄存器組
用來失能中斷 32位寄存器,每個位控制一箇中斷的失能,和2一樣。不多bb
4:中斷掛起控制寄存器組ISPR[8],中斷解掛控制寄存器組ICPR[8],都和前兩個一樣
5:IABR[8]:中斷激活標誌位寄存器組
只讀,通過它可以知道當前在執行的中斷是哪一個,如果對應位爲1,說明該中斷正在執行
/********************************************************************************************************************/
以上,就是中斷最基本的一些知識,不需要去記住,不管是標準庫,還是HAL庫,都有相應的函數去調用,刨開那些函數,調用的也就是上面的寄存器。
至於代碼,我就不貼了,網上一大堆
4:EXTI外部中斷概述
STM32F4的每個IO都可以作爲外部中斷輸入
STM32F4的中斷控制器支持22個外部中斷/事件請求:
- EXTI線0~15:對應外部IO口的輸入中斷。
- EXTI線16:連接到PVD輸出。
- EXTI線17:連接到RTC鬧鐘事件。
- EXTI線18:連接到USB OTG FS喚醒事件。
- EXTI線19:連接到以太網喚醒事件。
- EXTI線20:連接到USB OTG HS(在FS中配置)喚醒事件。
- EXTI線21:連接到RTC入侵和時間戳事件。
- EXTI線22:連接到RTC喚醒事件。
每個外部中斷線都可以獨立的配置觸發方式(上升沿,下降沿或雙邊沿觸發),觸發/屏蔽,專用的狀態位。
上面,我們可以看到,IO口的輸入中斷線只有16個,而F4的IO口有多達百個,前面也說了,32的每個IO口都可以觸發外部中斷,所以,這個裏面是有取捨的。
看這個圖,就很明確了,把PX0拉到EXT0上,把PX1拉到EXT1上,這樣,就可以用16根IO口外部中斷線來管理上百個IO了。
但是還沒結束,並不是16根中斷線就可以分配到16箇中斷服務函數
很吝嗇的是,只有7箇中斷服務函數
後面的EXTI9-5,EXTI15-10只能擠擠了。也就是說PX9~PX5共用一個外部中斷服務函數,PX15~PX10共用一個外部中斷服務函數
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE); //使能SYSCFG時鐘 SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource0);//PA0 連接到中斷線0 /* 配置EXTI_Line0 */ EXTI_InitStructure.EXTI_Line = EXTI_Line0; //LINE0 EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //中斷事件 EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; //上升沿觸發 EXTI_InitStructure.EXTI_LineCmd = ENABLE; //使能LINE0 EXTI_Init(&EXTI_InitStructure); //配置 /*配置一下外部中斷0的中斷優先級和使能通道*/ NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn; //外部中斷0 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00;//搶佔優先級0 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02; //子優先級2 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中斷通道 NVIC_Init(&NVIC_InitStructure);//配置 //外部中斷0服務程序 void EXTI0_IRQHandler(void) { EXTI_ClearITPendingBit(EXTI_Line0); //清除LINE0上的中斷標誌位 }
看上面第一步,要使能系統配置控制器時鐘,這個很重要
#define RCC_APB2Periph_SYSCFG ((uint32_t)0x00004000) /*調用RCC_APB2PeriphClockCmd,實際上賦值給了APB2ENR寄存器*/ RCC->APB2ENR |= RCC_APB2Periph; /* 位 14 SYSCFGEN:系統配置控制器時鐘使能 (System configuration controller clock enable) 由軟件置 1 和清零。 0:禁止系統配置控制器時鐘 1:使能系統配置控制器時鐘 使能了系統配置控制器後,可以看看SYSCFG_EXTICRX寄存器的描述,你就懂了 */
5:外部中斷的一般配置步驟
- 使能SYSCFG系統配置控制器時鐘
- 初始化IO口爲輸入
- 設置IO口與中斷線的映射關係
- 初始化線上中斷,設置觸發條件等
- 配置中斷分組(NVIC),並使能中斷
- 編寫中斷服務函數
- 清除中斷標誌位