日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【STM32+cubemx】0007 HAL库开发:外部中断,优先级和中断向量表

發(fā)布時(shí)間:2024/5/14 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【STM32+cubemx】0007 HAL库开发:外部中断,优先级和中断向量表 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

這一節(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)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。