開發(fā)環(huán)境:MDK(keil 5) + STM32CubeMX
1.1 中斷的作用
中斷的主要作用就是允許一些緊急的任務(wù)“插隊”,提前進(jìn)行。比如,大家在排隊做核酸檢測,但是,現(xiàn)在來了一位男士,他說他有緊急情況,希望能夠先做,在征得同意后,他先做了核酸,他做完了跑了,但大家仍然按照原來的順序排隊進(jìn)行,這就是中斷。
又如,你在玩游戲,但是一個重要電話進(jìn)來了,你只得暫停當(dāng)前的游戲,先接電話,接完電話繼續(xù)玩。這也是中斷。
在各種電子產(chǎn)品中,中斷用得非常非常多,在我看來,它和GPIO、串口、定時器一起,是各種處理器學(xué)習(xí)的最重要的四個模塊之一,我稱之為“四大金剛”。
1.2 GD32的中斷的執(zhí)行及其優(yōu)先級
對于GD32的中斷,我們需要關(guān)注以下問題:
1.那些模塊可以申請中斷?絕大部分的模塊,比如串口、定時器、SPI接口等都可以申請中斷,這些可以申請中斷的模塊我們叫中斷源。
2.某個模塊申請中斷,并獲得系統(tǒng)同意后,系統(tǒng)將會做什么?中斷申請并獲得通過后,將會執(zhí)行中斷函數(shù),中斷函數(shù)執(zhí)行完后又回到原來的地方繼續(xù)執(zhí)行。
GD32的各個模塊的中斷函數(shù)的函數(shù)名廠家已經(jīng)幫我們?nèi)『昧?,在啟動文?.s文件)中,具體如圖1所示。
圖1 GD32的中斷函數(shù)
3.如果有多個中斷同時到來,處理器該怎么辦呢?它會先去執(zhí)行哪個中斷的中斷函數(shù)呢?通過每個中斷的優(yōu)先級才裁決先響應(yīng)誰!優(yōu)先級高的中斷,它的中斷函數(shù)將會獲得優(yōu)先執(zhí)行。GD32的每個中斷的優(yōu)先級分為搶占式優(yōu)先級和子優(yōu)先級兩部分,在實際應(yīng)用中,一般我們都是只需要設(shè)置搶占式優(yōu)先級即可,子優(yōu)先級不用理會。搶占式優(yōu)先級可以設(shè)置的值為0-15,值越小優(yōu)先級越高,這點跟freertos操作系統(tǒng)的優(yōu)先級剛好相反,freertos的是值越高優(yōu)先級越高。
GD32的中斷由一個叫NVIC的模塊統(tǒng)一處理,NVIC全稱叫嵌套中斷向量控制器,搶占式優(yōu)先級、子優(yōu)先級、中斷允許、中斷失能都在它里面設(shè)置。
最后補(bǔ)充說明兩點:
1.GD32的每一個模塊都會有至少一個中斷開關(guān),只有這個開關(guān)處于使能狀態(tài),該模塊的中斷信號才能進(jìn)入到NVIC內(nèi)部。
2.中斷函數(shù)中盡量不要有延時,如必須要延時,則延時要盡量小,要快進(jìn)快出,不要影響后續(xù)的中斷的響應(yīng)!
1.3 GD32的外部中斷
GD32F103VET6支持19個外部中斷,注意,這里雖然用了外部兩個字,但真正只有16來自于芯片的外部,有3個仍然是在芯片的內(nèi)部。外部的16個中斷分別為EXTI0~EXTI15,其中EXTI0可以從PA0、PB0、PC0等標(biāo)號為0的引腳進(jìn)入,EXTI1可以從PA1、PB1、PC1等標(biāo)號為1引腳進(jìn)入,其他外部中斷同理。
在這16個從IO引腳進(jìn)入的中斷中,他們的中斷函數(shù)分別為
●EXTI0-EXTI4都有自己獨(dú)立的中斷函數(shù),他們的函數(shù)名分別為EXTI0_IRQHandler~ EXTI4_IRQHandler;
●外部中斷5到9共用一個中斷函數(shù),函數(shù)名為EXTI9_5_IRQHandler;
●外部中斷10到15共用一個中斷函數(shù),函數(shù)名為EXTI15_10_IRQHandler。
對于這些共用中斷函數(shù)的外部中斷,需要在中斷函數(shù)的內(nèi)部進(jìn)一步判斷是那個外部中斷。
外部中斷的觸發(fā)方式可以有下降沿觸發(fā)和上升沿觸發(fā),這個可以根據(jù)具體情況來選擇。
1.4 外部中斷應(yīng)用示例
下面我們通過一個例子來學(xué)習(xí)外部中斷的應(yīng)用。
【例1】使用PE2外部的按鍵KEY0產(chǎn)生外部中斷,每發(fā)生一次外部中斷將LED0的狀態(tài)反轉(zhuǎn)一次。在整個過程中,LED1以1秒的頻率閃爍。
【實現(xiàn)過程】
1.設(shè)置系統(tǒng)時鐘源和系統(tǒng)時鐘的頻率為72MHz;
2.設(shè)置調(diào)試方式為Serial Wire;
3.設(shè)置與LED0相連的PE12,與LED1相連的PE13工作方式為輸出;
4.設(shè)置與KEY0相連的PE2引腳的為外部中斷引腳,搶占式優(yōu)先級為3(由于系統(tǒng)滴答定時器的優(yōu)先級為0,所以這個優(yōu)先級比0低即可)。整個過程的步驟為:
(1)設(shè)置PE2的工作模式為外部中斷,如圖2所示。
圖2 PE2引腳設(shè)置為外部中斷示意圖
(2)在GPIO中設(shè)置PE2的中斷觸發(fā)方式為下降沿觸發(fā)(按鍵按下就觸發(fā)),如圖3所示。
圖3 設(shè)置下降沿觸發(fā)示意圖
(3)設(shè)置外部中斷2的搶占式優(yōu)先級的值為3,實際上由于本工程中除了系統(tǒng)滴答定時器的中斷,其他的中斷都沒有,所以這里設(shè)置不與滴答定時器的中斷優(yōu)先級相同即可(滴答定時器的中斷優(yōu)先級為0)。設(shè)置步驟和結(jié)果如圖4所示。
圖4 優(yōu)先級設(shè)置示意圖
注意,如果EXTI2的中斷的優(yōu)先級采用默認(rèn),也就是搶占式優(yōu)先級為0,子優(yōu)先級也為0,這兩個優(yōu)先級跟滴答定時器(System tick timer)的優(yōu)先級一樣,則可能在中斷中使用延時函數(shù)HAL_Delay()時,有可能會使系統(tǒng)死機(jī)(延時函數(shù)HAL_Delay()通過tick 定時器的中斷來工作,當(dāng)進(jìn)入EXTI2中斷函數(shù)執(zhí)行時,tick 定時器的中斷得不到及時執(zhí)行,所以會出現(xiàn)死機(jī)現(xiàn)象!)。
5.配置好中斷后,接下來是配置工程名、工程存放路徑等信息,然后點擊生成代碼,生成代碼后,我們需要補(bǔ)充如下功能:
(1)在主函數(shù)的while循環(huán)中補(bǔ)充是的LED1閃爍的程序段,具體如圖5所示。
圖5 LED1閃爍程序段示意圖
(2)編寫中斷服務(wù)回調(diào)函數(shù),注意不是中斷服務(wù)函數(shù),該函數(shù)的內(nèi)容如圖6所示。
圖6 EXTI2的中斷回調(diào)(callback)函數(shù)
程序編寫好后,編譯程序并將程序下載到開發(fā)板中,可以看到LED1閃爍,LED0則是按下一次KEY0鍵LE0的狀態(tài)反轉(zhuǎn)一次,任務(wù)目標(biāo)完成。
1.5 HAL庫中中斷函數(shù)的執(zhí)行流程
在剛才的步驟中,有一步為編寫中斷服務(wù)回調(diào)函數(shù),注意,為回調(diào)函數(shù)而不是中斷服務(wù)函數(shù),這跟我們前面的介紹是不是互相矛盾呢?我們通過觀察CubeMX生成的工程的中斷的執(zhí)行流程來回答這個問題。這個流程如下:
①系統(tǒng)接收到EXTI2的中斷請求并響應(yīng)后,到.s文件中尋找到該中斷函數(shù)的入口,如圖7所示。
圖7 外部中斷EXTI2的中斷服務(wù)函數(shù)的入口示意圖
②由于函數(shù)的名字就是函數(shù)的入口,所以找到入口后,接下來執(zhí)行函數(shù)EXTI2_IRQHandler,如圖8所示。函數(shù)EXTI2_IRQHandler就是EXTI2的中斷服務(wù)函數(shù)。
圖8 中斷服務(wù)函數(shù)EXTI2_IRQHandler的內(nèi)容
③執(zhí)行通用IO口外部中斷函數(shù)HAL_GPIO_EXTI_IRQHandler(),這個函數(shù)是一個通用函數(shù),其他的GPIO口的外部中斷都調(diào)用這個函數(shù),它的參數(shù)只有一個,就是中斷的輸入引腳標(biāo)號,實際上就是外部中斷線編號。函數(shù)HAL_GPIO_EXTI_IRQHandler的內(nèi)容如圖9所示。
圖9 通用外部中斷函數(shù)的內(nèi)容示意圖
由圖9可以看到,在該函數(shù)中,在判斷GPIO_Pin引腳對應(yīng)的標(biāo)志位為真后執(zhí)行兩個動作,分別是
●使用宏__HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin)來清除標(biāo)志位,以便下一次的中斷能夠進(jìn)來;
●調(diào)用中斷回調(diào)函數(shù)HAL_GPIO_EXTI_Callback(),我們要實現(xiàn)的中斷需要做的事情就在中斷回調(diào)函數(shù)中實現(xiàn),所以在前面的步驟中,我們編寫的是中斷回調(diào)函數(shù)的代碼,而不是中斷服務(wù)函數(shù)的代碼,當(dāng)然,大家也可以將代碼內(nèi)容直接寫到中斷服務(wù)函數(shù)中。
1.6 外部中斷實驗中涉及到的HAL庫的函數(shù)/宏及其他相關(guān)知識
1.獲取外部中斷標(biāo)志位和清除外部中斷標(biāo)志位
中斷標(biāo)志位被置1說明該中斷獲得了響應(yīng),獲得響應(yīng)后要在中斷服務(wù)函數(shù)中清除該標(biāo)志位,以使得下次該中斷有中斷申請到來時能獲得響應(yīng)。HAL庫中,獲取中斷標(biāo)志位和清除中斷標(biāo)志位分別用下面兩個宏來完成。
●獲取中斷標(biāo)志位:__HAL_GPIO_EXTI_GET_IT()
●清除中斷標(biāo)志位: __HAL_GPIO_EXTI_CLEAR_IT()
這兩個宏都只有一個參數(shù),就是外部中斷輸入引腳的編號。
注意,與HAL庫中的函數(shù)不用,HAL庫中宏名用兩個下劃線開始,其格式為
“__” + “HAL” + 模塊名 + 執(zhí)行動作名
2.外部中斷回調(diào)函數(shù)HAL_GPIO_EXTI_Callback()
HAL庫中回調(diào)函數(shù)使用Callback結(jié)尾,對于外部中斷回調(diào)函數(shù),它只有一個參數(shù),這個參數(shù)就是外部中斷的編號—也即外部中斷輸入IO引腳的標(biāo)號。
3.HAL庫初始化函數(shù)HAL_Init()
每次我們用STM32CubeMX生成工程時,主函數(shù)中的第一條語句就是執(zhí)行函數(shù)HAL_Init()的內(nèi)容,這個函數(shù)具體做什么呢?我們打開看一下,可以看到這個函數(shù)的內(nèi)容如圖10所示。
圖10 HAL庫初始化函數(shù)HAL_Init()的內(nèi)容
由圖可見,函數(shù)HAL_Init()主要所兩個事,分別是:
①設(shè)置搶占式優(yōu)先級的位數(shù),這里是設(shè)置為4位,其值可以從015,所以搶占式優(yōu)先級可以設(shè)置為015的任意數(shù)字。
②配置tick timer定時器,并設(shè)置它的優(yōu)先級。
1.7 結(jié)論及注意事項
在本章的學(xué)習(xí)中,主要注意以下幾點:
1.發(fā)生外部中斷后,在系統(tǒng)提供的中斷服務(wù)函數(shù)中已經(jīng)清除了中斷標(biāo)志位,所以大家在編寫中斷回調(diào)函數(shù)的時候不需要再次清除中斷標(biāo)志位。
2.中斷的優(yōu)先級不要跟tick timer,也就是滴答定時器的中斷優(yōu)先級一樣,否則在中斷回調(diào)函數(shù)中使用HAL_Delay函數(shù)時會出現(xiàn)死機(jī)現(xiàn)象。
3.GD32/STM32的優(yōu)先級是:優(yōu)先級值越小的中斷,它的中斷優(yōu)先級越高。
-
處理器
+關(guān)注
關(guān)注
68文章
19432瀏覽量
231261 -
FreeRTOS
+關(guān)注
關(guān)注
12文章
484瀏覽量
62410 -
外部中斷
+關(guān)注
關(guān)注
1文章
132瀏覽量
15890 -
GD32F103
+關(guān)注
關(guān)注
5文章
18瀏覽量
9473 -
stm32cubemx
+關(guān)注
關(guān)注
5文章
284瀏覽量
15028
發(fā)布評論請先 登錄
相關(guān)推薦
GD32的外部中斷介紹
GD32串口dma接收空閑中斷配置流程是怎樣的?
GD32-Colibri-F207實驗板中斷主從機(jī)通信
GD32-Colibri-F207實驗板中斷主從機(jī)通信發(fā)送
STM32 中斷原理及外部中斷的實現(xiàn)
![STM32 <b class='flag-5'>中斷</b>原理及<b class='flag-5'>外部</b><b class='flag-5'>中斷</b>的<b class='flag-5'>實現(xiàn)</b>](https://file.elecfans.com/web1/M00/D9/4E/pIYBAF_1ac2Ac0EEAABDkS1IP1s689.png)
GD32系列外部中斷
![<b class='flag-5'>GD32</b>系列<b class='flag-5'>外部</b><b class='flag-5'>中斷</b>](https://file.elecfans.com/web1/M00/D9/4E/pIYBAF_1ac2Ac0EEAABDkS1IP1s689.png)
GD32外部中斷(按鍵問題實現(xiàn))
![<b class='flag-5'>GD32</b><b class='flag-5'>外部</b><b class='flag-5'>中斷</b>(按鍵問題<b class='flag-5'>實現(xiàn)</b>)](https://file.elecfans.com/web1/M00/D9/4E/pIYBAF_1ac2Ac0EEAABDkS1IP1s689.png)
STM32如何配置外部中斷?STM32外部中斷配置步驟
GD32 MCU是如何進(jìn)入中斷函數(shù)的
![<b class='flag-5'>GD32</b> MCU是如何進(jìn)入<b class='flag-5'>中斷</b>函數(shù)的](https://file1.elecfans.com/web2/M00/BE/E0/wKgZomW4VICAb4pRAABCcJF26bY814.png)
評論