STM32CubeMX教程4 EXTI 按键外部中断
1、準備材料
開發板(STM32F407G-DISC1)
ST-LINK/V2驅動
STM32CubeMX軟件(Version 6.10.0)
keil μVision5 IDE(MDK-Arm)
2、實驗目標
使用STM32CubeMX軟件配置STM32F407開發板通過用戶按鍵產生外部中斷,然后在中斷中翻轉綠色LED燈的狀態
3、中斷系統概述
3.1、中斷向量表
STM32F4系列有10個系統中斷和82個可屏蔽的外部中斷(注釋1),除系統Reset中斷外每個中斷均有對應的中斷服務函數
3.2、中斷優先級
嵌套向量中斷控制器(NVIC)采用4位二進制數表示中斷優先級,這4位二進制數表示的中斷優先級又分為了搶占優先級和次優先級,其中根據搶占優先級所使用的二進制位數分成了5個組,分為NVIC_PRIORITYGROUP_0 ~ NVIC_PRIORITYGROUP_4,分別表示搶占優先級使用0~4位二進制數表示,具體規則如下幾點所述:
① 高搶占優先級的中斷可以打斷低搶占優先級的中斷
② 搶占優先級和次優先級均相同的兩個中斷誰先發生誰就先執行
③ 搶占優先級相同但次優先級不同的兩個中斷,后觸發的中斷需要等待先觸發的中斷執行完畢才可以執行
4、實驗流程
4.0、前提知識
STM32F407一共有23個外部中斷,其中包含16個外部中斷(EXTI0~EXTI15)和7個對應不同的事件的中斷,如下表所示
每一組GPIO的0號引腳均可以作為EXTI0的輸入,同理,每一組GPIO的15號引腳均可以作為EXTI15的輸入,具體映射如下圖所示(注釋2)
4.1、CubeMX相關配置
請先閱讀“STM32CubeMX 工程建立”實驗3.4.1小節配置RCC和SYS
4.1.1、時鐘樹配置
系統時鐘樹設置為STM32F407各個總線能達到的最高時鐘頻率,具體如下圖所示
4.1.2、外設參數配置
在Pinout & Configuration頁面右邊單片機引腳預覽Pinout view中,尋找需要設置的具體GPIO,這里我們仍然選擇用戶按鍵的PA0引腳,但是右鍵單擊將其配置為GPIO_EXTI0
在頁面的中間GPIO Mode and Configuration欄中選中PA0引腳,然后在下方對其引腳進行配置,外部中斷主要配置GPIO模式和GPIO Pull-up/Pull-down,GPIO模式有外部中斷上升沿、下降沿、上/下降沿觸發、外部事件上升沿、下降沿和上/下降沿觸發共計6中模式,這里我們使用的是外部中斷,并且在按鍵按下松開時既會產生上升沿也會產生下降沿,因此筆者這里選擇下降沿觸發的外部中斷模式,具體配置如下圖所示
4.1.3、外設中斷配置
將引腳配置為中斷模式后,還需要在NVIC中啟動其具體的中斷,單擊頁面左側的NVIC配置,選擇合適的中斷優先級組,然后啟動對應的中斷,這里即用戶按鍵引腳PA0的中斷EXTline0 interrupt,具體配置如下圖所示
4.2、生成代碼
請先閱讀“STM32CubeMX 工程建立”實驗3.4.3小節配置Project Manager
單擊上圖頁面右上角GENERATE CODE重新生成工程
當僅僅配置了引腳為外部中斷模式,而不啟動對應的外部中斷時,在生成的代碼引腳初始化函數MX_GPIO_Init中只會增加如下圖框中所示的代碼,此時由于未使能中斷,因此中斷不能正常響應
當配置了引腳為外部中斷模式,且使能了引腳對應的中斷,首先會在HAL_Init(void)函數中設置中斷優先級組(系統默認開啟了一些中斷,因此即使我們不使能外部中斷該函數也會被其他開啟的中斷調用從而設置中斷優先級組)
另外除了上述的引腳模式設置代碼外,還會在引腳初始化函數MX_GPIO_Init中新增加中斷優先級設置及對應中斷使能的函數
然后在stm32f4xx_it.c文件中會出現對應的中斷服務子函數void EXTI0_IRQHandler(void)(注釋3),中斷服務子函數中調用了HAL_GPIO_EXTI_IRQHandler(GPIO_Pin)函數,跳轉過去在函數內部執行了 ① 檢測該中斷線是否有掛起的外部中斷 ② 如果有則清除掛起的外部中斷線 ③ 然后調用外部中斷回調函數HAL_GPIO_EXTI_Callback(GPIO_Pin)(此函數為虛函數,可由用戶自定義),具體流程如下圖所示
此時用戶只需要重新實現HAL_GPIO_EXTI_Callback(GPIO_Pin)函數即可,在該函數體內可以實現中斷觸發后想要實現的功能代碼,筆者將該函數重新實現在了gpio.c中,值得注意的是在外部中斷回調函數中使用到了HAL庫延時函數來對按鍵消抖,此處可能會存在嚴重的問題(注釋4),具體代碼如下圖所示
源代碼如下
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
if(GPIO_Pin == USER_KEY_Pin)
{
HAL_Delay(10);
HAL_GPIO_TogglePin(GREEN_LED_GPIO_Port, GREEN_LED_Pin);
}
}
5、常用函數
/*所有外部中斷觸發回調服務子函數,通過GPIO_Pin判斷是哪個中斷線,然后在函數體內做相應動作*/
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
6、燒錄驗證
6.1、具體步驟
“初始化LED引腳為輸出 -> 初始化用戶按鍵為外部中斷模式 -> 啟動對應外部中斷 -> 重新實現HAL_GPIO_EXTI_Callback(GPIO_Pin)函數 -> 在函數中實現翻轉綠色LED燈狀態”,具體代碼參看上述4.2
6.2、實驗現象
燒錄程序,然后可以觀察到當開發板上電后,四個顏色LED全部點亮,然后每按下一次用戶按鍵,綠色LED燈狀態均會發生翻轉
7、注釋解析
注釋1:具體的中斷向量表可以在keil工程目錄啟動文件startup_stm32f407xx.s中查看,這里的中斷數量筆者是根據啟動文件中的數量計算的,其中Reserved的中斷向量未計數
注釋2:圖片來自STM32F4xx中文參考手冊.pdf
注釋3:以后對于每一個外設中斷,啟用后都會在stm32f4xx_it.c文件中找到對應的中斷服務函數
注釋4:HAL庫延時函數HAL_Delay使用的是系統滴答定時器作為時間基準,而系統滴答定時器同為中斷,在外部中斷中觸發系統滴答定時器中斷會涉及中斷優先級的問題,此時需保證滴答定時器的搶占優先級高于我們所使用的外部中斷,否則會出現卡死的現象發生
更多內容請瀏覽 OSnotes的CSDN博客
總結
以上是生活随笔為你收集整理的STM32CubeMX教程4 EXTI 按键外部中断的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Ef Core花里胡哨系列(7) 使用E
- 下一篇: DigitalOcean和AWS两大云服