【STM32+cubemx】0007 HAL库开发:外部中断,优先级和中断向量表
這一節(jié)我們以外部中斷為例子,講講中斷的優(yōu)先級和中斷向量表的知識(shí)。
1)cubemx生成代碼
首先還是在cubemx中生成代碼,選擇器件、設(shè)置SYS(調(diào)試接口)、設(shè)置RCC(外部晶振時(shí)鐘源)。
然后設(shè)置GPIO引腳,選擇PC13作為輸出(用于LED指示),如下圖選擇PA0設(shè)置為外部中斷輸入引腳:
然后設(shè)置中斷使能和優(yōu)先級,如下圖:
這里的幾處選項(xiàng)解釋一下:
最上面的Priority group是選擇優(yōu)先級分組,STM32(更確切地說是contex-M3內(nèi)核的單片機(jī))使用4個(gè)bit位來分組,這里可以設(shè)置用幾個(gè)bit來區(qū)分搶占優(yōu)先級和響應(yīng)優(yōu)先級;
比如圖中選擇的是3bit用來區(qū)分搶占優(yōu)先級、1bit用來區(qū)分響應(yīng)優(yōu)先級,則搶占優(yōu)先級可以選擇為0~7(圖中選的是6),響應(yīng)優(yōu)先級可以選擇為0~1(圖中選的是1);數(shù)值越小則優(yōu)先級越高;
搶占優(yōu)先級高的可以中斷低優(yōu)先級的中斷,中斷嵌套的形式實(shí)現(xiàn);
搶占優(yōu)先級相同時(shí),有多個(gè)中斷同時(shí)發(fā)生,則先運(yùn)行響應(yīng)優(yōu)先級高的中斷。
由于咱們這個(gè)例子只有一個(gè)中斷,選哪個(gè)都不影響,但是要勾上使能。
到GPIO頁面下,將PA0的狀態(tài)改為上拉、中斷下降沿觸發(fā):
之后,在時(shí)鐘選項(xiàng)卡設(shè)置主時(shí)鐘為72M;在project Manager選項(xiàng)卡設(shè)置工程名和路徑,生成工程代碼。
2)HAL庫函數(shù)的使用
生成的工程中,已經(jīng)有比較完善的初始化代碼。我們直接看中斷服務(wù)程序,在stm32f1xx_it.c中:
其中的HAL_GPIO_EXTI_IRQHandler函數(shù)實(shí)現(xiàn)如下:
我們重寫它的回調(diào)函數(shù),實(shí)現(xiàn)翻轉(zhuǎn)一次PC13(LED翻轉(zhuǎn)):
編譯下載到板子上后,將PA0引腳接觸一下GND,可以看到LED有翻轉(zhuǎn)。
由于這里沒有去抖,將PA0接觸GND時(shí)可能會(huì)產(chǎn)生多次中斷,有可能LED的狀態(tài)來回變化多次,可以在調(diào)試模式下,在中斷中設(shè)置斷點(diǎn)來觀察,是否每次接觸都會(huì)進(jìn)入中斷。
3)中斷向量表的概念
在中斷發(fā)生時(shí),為什么會(huì)跳到如下這個(gè)函數(shù)來執(zhí)行呢?
首先,我們在初始化時(shí),開啟了外部中斷0(這是配置完cubemx自動(dòng)生成的):
在MCU中,每個(gè)中斷源會(huì)對應(yīng)一個(gè)地址,當(dāng)某個(gè)中斷產(chǎn)生時(shí),程序就會(huì)保存現(xiàn)場,自動(dòng)跳轉(zhuǎn)到這個(gè)地址去執(zhí)行,執(zhí)行完后再恢復(fù)現(xiàn)場,回到原來的程序執(zhí)行。這些中斷源對應(yīng)的地址就是中斷向量表。
如下圖,stm32的工程代碼中,啟動(dòng)文件中設(shè)置的中斷向量表,都是跳轉(zhuǎn)到某個(gè)函數(shù)執(zhí)行:
這個(gè)啟動(dòng)文件里的中斷向量表是從程序存儲(chǔ)的地址起始開始往下排列的,每行占用4個(gè)字節(jié)(32bit),也就是說,EXTI0_IRQHandler在第23行,對應(yīng)地址22*4=0x00000058;我們查看stm32f103的數(shù)據(jù)手冊,發(fā)現(xiàn)這個(gè)地址就是外部中斷0的中斷向量地址:
所以,產(chǎn)生外部中斷0時(shí),會(huì)自動(dòng)跳到其對應(yīng)的中斷向量表0x00000058處去執(zhí)行,也就是調(diào)用EXTI0_IRQHandler函數(shù)。
4)中斷向量表的重映射
在某些應(yīng)用中,需要將中斷向量表移到別處。比如說含有IAP功能的程序,一般bootlooder程序是從MCU默認(rèn)啟動(dòng)的位置(地址0)執(zhí)行,其中斷向量表也在從0起始的位置;而app程序一般存儲(chǔ)在bootlooder之后的一段地址中,這樣app程序中定義的中斷向量表就會(huì)偏離0地址。
為了正確訪問中斷向量表的地址,需要在app程序的起始,進(jìn)行中斷向量表的映射,可以用以下函數(shù)實(shí)現(xiàn):
void NVIC_SetVectorTable(uint32_t NVIC_VectTab, uint32_t Offset) { /* Check the parameters */assert_param(IS_NVIC_VECTTAB(NVIC_VectTab));assert_param(IS_NVIC_OFFSET(Offset)); SCB->VTOR = NVIC_VectTab | (Offset & (uint32_t)0x1FFFFF80); }如下使用,可以將中斷向量表起始地址設(shè)置為0x08003000:
NVIC_SetVectorTable(0x08000000, 0x3000);這里說明一下, stm32芯片的rom地址是從0x08000000開始的,如keil中的默認(rèn)設(shè)置:
stm32芯片在內(nèi)部自動(dòng)進(jìn)行了映射,把0x08000000和地址0進(jìn)行了映射,所以app程序燒寫到0x08000000地址,不用進(jìn)行其他設(shè)置,也是可以訪問到中斷向量表的。
但是,如果app程序被燒寫到了別的地址,如0x08003000,則需要程序中重新映射一下,使用這個(gè)函數(shù):NVIC_SetVectorTable(0x08000000, 0x3000),這個(gè)用法以后講到IAP的時(shí)候會(huì)用到。
好了,這一節(jié)的內(nèi)容基本講完了。
歡迎關(guān)注我的公眾號,可留言“資料”獲取相關(guān)程序和軟件:
總結(jié)
以上是生活随笔為你收集整理的【STM32+cubemx】0007 HAL库开发:外部中断,优先级和中断向量表的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Word文档隐藏文字设置
- 下一篇: 2016计算机国二试题,全国计算机等级考