STM32F0單片機快速入門五: GPIO中斷

  1. 按鍵如何觸發中斷

我們從一個例程看一下,如何用一個GPIO引腳來觸發中斷,來控制另一個引腳的翻轉去控制LED指示燈。

 

我們用 Keil 打開下面這個工程:

STM32Cube_FW_F0_V1.11.0\Projects\STM32F030R8-Nucleo\Examples\GPIO\GPIO_EXTI\MDK-ARM\Project.uvprojx

 

編譯下載運行此代碼,然後按壓 B1 USER 這個按鍵,每一次按壓會觸發板上一個LED燈翻轉一次。這個功能也很簡單,但它牽涉到的東西卻不少。看一下代碼:

上一篇文章講了如何翻轉GPIO引腳,所以現在我們只關注一下如何用一個引腳觸發中斷吧。main()函數裏調用了一個外部中斷模塊(EXTI)初始化後就進入while循環了。

 

我們在下面可以找到這個初始化函數的實現。它調用HAL庫函數對按鍵連接的引腳PC13做了初始化,把此引腳初始化爲能觸發中斷的模式。

初始化函數的下面是一個回調函數(Callback Function)。在此函數中翻轉了連接LED的引腳。我們接下來分別講一下這個回調函數和如何把一個GPIO引腳初始化爲中斷模式。

 

2.回調函數

回調函數這個概念,解釋可以說五花八門,什麼原因呢?因爲這好像不是一句自然(人)語言(話)。咱們還是打個比方好理解一些。

 

好比你在廚房做菜,突然發現醬油沒了。你叫你兒子去給你打醬油,兒子就是你的驅動。兒子聽到你的召喚,說:行啊,老爸,但你得先給我點錢啊!你看,兒子這就是回調(Callback)。一會兒兒子打醬油回來了,然後把醬油交給你,這也是回調。

 

那我們回到程序,看一下應用程序(Application),驅動(Driver)和回調函數(Callback Function)是什麼關係。如果應用程序調用一個驅動,這個驅動在執行前先調用一個函數來獲取一些參數,而這些參數需要由應用程序提供,所以此函數位於應用層,它就是一個回調函數。還有一種情況就是驅動執行完畢,通過調用應用層的一個函數返回結果,或通知應用層執行完畢,此函數也是回調函數。

 

下面就是從中斷髮生,一直到應用層的回調路徑:

 

B1 USER 按鍵(連接至PC13引腳)按下,中斷髮生

EXTI4_15_IRQHandler     <-startup_stm32f030x8.s

EXTI4_15_IRQHandler(void)     <-stm32f0xx_it.c

HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)     <- stm32f0xx_hal_gpio.c

HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)     <-main.c

 

那麼如何才能讓PC13觸發這個中斷呢?

 

3.GPIO中斷引腳配置

MCU是如何把一個引腳電平的變化和一箇中斷聯繫起來的呢?我們馬上想到給每個GPIO引腳分配一箇中斷向量就好了。當一個引腳電平變化,馬上就可以跳轉到自己對應的中斷服務程序。這確實是最簡單的辦法,但MCU一般都有幾十個引腳,如果這樣做像M0這種內核只支持32個外部中斷,根本就不夠用的。所以我們看STM32F030僅支持16個外部中斷,又在中斷向量表中進一步縮減爲3箇中斷向量。

                                                                    RM0360 STM32F030 Reference manual

外部中斷0至15

0,1對應一箇中斷向量(5號中斷);

2,3對應一個(6號中斷);

4至15對應一個(7號中斷)。

 

STM32F030的16個外部中斷是如何對應到各個引腳上的呢?

這就要通過 EXTI (Extended interrupts and events controller)這個模塊。它除了可以完成中斷引腳的選擇(映射),還可以配置是上升沿還是下降沿觸發,也可以屏蔽(Mask)某個引腳。下面的示意圖簡要的顯示了這種關係。

大家注意,圖中這些模塊雖然都在一個芯片內,但是EXTI是芯片級模塊,NVIC是在M0內核之中。

 

相關寄存器介紹:

一共有4個這樣的寄存器:

SYSCFG_EXTICR1,SYSCFG_EXTICR2,SYSCFG_EXTICR3,SYSCFG_EXTICR4

每一個寄存器對應着4個引腳的選擇。

 

下面的這些寄存器都有 32 bits (Bit31 - Bit0),每一個bit對應一箇中斷。

EXTI_IMR (Interrupt mask register)

0: 屏蔽所對應的中斷。1: 允許對應中斷。

 

EXTI_RTSR (Rising trigger selection register)

0: 禁止上升沿觸發。1: 使能上升沿觸發。

 

EXTI_FTSR (Falling trigger selection register)

0: 禁止下降沿觸發。1: 使能下降沿觸發。

 

如果上升沿和下降沿都設置爲1,那麼在上升沿和下降沿都會觸發中斷。

 

EXTI_PR (Pending register)

0: 沒有中斷請求。1: 有中斷請求。

當中斷髮生使此寄存器某一位被置1後,在此位寫入1可以清除此標誌位。

 

現在大家再返回去,理解代碼就會容易一些了。

 

 

參考資料:

PM0215  STM32F0xxx Cortex-M0 programming manual

UM1785 Description of STM32F0 HAL and low-layer drivers

STM32F030 Datasheet

STM32F030 Reference Manual

 

……………………………………………………………………………………………………

歡迎掃碼關注我們,獲取更多精彩內容:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章