大家好,我是老耿,高職青椒一枚,一直從事單片機、嵌入式、物聯網等課程的教學。對于高職的學生層次,同行應該都懂的,老師在課堂上教學幾乎是沒什麼成就感的。正是如此,才有了借助頭條平台尋求認同感和成就感的想法。在這裡,我準備陸續把自己花了很多心思設計的教學課件分享出來,如果您正是一名單片機愛好者或是一名同行,歡迎點贊 關注,各位的支持是本人持續輸出的動力,多謝多謝!#30天學會STM32##STM32單片機##單片機#
【學習目标】
能從全局角度理解中斷機制對單片機的重要性明白中斷源和中斷服務函數在固件庫中的規範理解中斷優先級分組的設計理念 中斷可以說是單片機的“靈魂”,後續幾乎所有實驗都會涉及中斷。因此,中斷的講解放在哪一個外設裡面去講都不合适,所以這裡單獨抽出一篇來做一個概括性的介紹,這樣在其他外設涉及到中斷部分知識的時候,就不用費很大的篇幅去講解,隻要示意性帶過即可。
一、中斷的産生背景 在前面的項目實踐中,可以看到在經過初始化配置之後,程序會進入一個while(1)循環,這循環也稱為主循環,實現任務功能的代碼都是在主循環中完成的。那麼可以試想一下,如果往主循環裡塞進一大堆各種各樣的任務(LED、數碼管顯示、按鍵掃描、串口收發、傳感器采集等等),就好比讓你一個人同時應付工作、帶孩子、做飯、搞衛生,其結果必然是“顧此失彼”,也就無法實現想要的控制效果。
那要解決上述問題該怎麼辦呢?在現實生活中,你可以找保潔、保姆或父母幫忙;在單片機的世界裡,能做到分身有術的“魔法”就是中斷。中斷是CPU處理外設(突發)事件的一種手段,當事件發生時,CPU會暫停當前的程序運行,轉而去處理突發事件的程序(即中斷服務函數),處理完之後又返回到中斷點繼續執行原來的程序。從一定程度上講,中斷幾乎成了單片機的靈魂。如果沒有中斷,單片機執行起任務将“無所适從”。
中斷這個詞是咱們根據英文單詞interrupt直譯過來的,其實在開發體驗上,它更像是助手,那下面咱們就來看看STM32一共有多少個中斷助手。
二、STM32強大的中斷響應系統 ARM的CM3内核支持256個中斷,包括16個内核中斷和240個外設中斷,擁有256個中斷優先級别。可以說這樣的設計是頗有遠見的,給未來預留了很大的拓展空間,畢竟需要的助手總會越來越多的。
STM32F103系列雖然使用的是CM3内核,但并沒有使用其全部的中斷資源。盡管如此,STM32中斷還是非常強大的,每個外設都可以産生中斷。把所有中斷用一個表管理起來,如表1所示,表中帶有灰色背景的為内核異常(10個),之後的60個稱為外設中斷,這個表就稱為中斷向量表。這張表沒必要記,需要的時候回來查找即可。
表1 CM3内核的16個異常(中斷)和STM32的60個外設中斷
三、STM32中斷的總管家——NVIC STM32 的中斷如此之多,配置起來并不容易,因此需要一個強大的“嵌套中斷向量控制器NVIC(Nested Vectored Interrupt Controller)”來對中斷進行管理。NVIC控制着整個芯片中斷相關的功能,它跟内核緊密耦合,是内核裡面的一個外設,如圖1所示。各芯片廠商在設計芯片的時候會對CM3内核裡面的NVIC進行裁剪,把不需要的部分去掉。
圖1 NVIC在内核中的位置
四、中斷優先級管理很重要 下面咱們來重點解釋一下NVIC字面意思裡“中斷嵌套”的含義,這其實是對中斷優先級管理的一種方式。首先,STM32的中斷優先級具有兩個屬性,一個為搶占優先級(又稱主優先級),另一個為響應優先級(又稱子優先級),其屬性編号越小,表面它的優先級越高。其次,如果有多個中斷同時響應,搶占優先級高的中斷就會打斷搶占優先級低的中斷,即中斷嵌套。如果搶占優先級相同,就根據響應優先級的高低來決定先處理哪一個。最後,如果搶占優先級和響應優先級都相同,就根據硬件中斷編号順序(表1中的第一列)來決定哪個先執行,硬件中斷編号越小,優先級越高。
4.1 優先級管理方案 在STM32中,優先級由NVIC_IPRx寄存器來配置,這個寄存器是8位的,但隻用了高4位來配置,最多支持16種中斷優先級,并且有5種優先級分組方式,如表2所示。
表2 STM32的中斷優先級的表示和分組
4.2 通俗理解優先級分組 關于中斷優先級分組方案,可以拿生活中排隊的場景來進行類比,如圖2所示,其中每個人就好比是一個中斷源。
圖2 生活中的排隊場景
1. NVIC_PriorityGroup_0(分組方案0)
無搶占優先級,即不允許任何人員插隊,哪怕是特殊人群。這種情況僅由響應優先級決定,0号最高,15号最低,就好比是隊伍最前和最後那個人。
2. NVIC_PriorityGroup_1(分組方案1)
有2種搶占優先級,可理解為特殊人群(老弱病殘孕醫軍)與非特殊人群兩類,特殊人群優先(插隊)。每類人群内部的優先權由8種響應優先級決定,好比是軍人還是孕婦優先。
3. NVIC_PriorityGroup_2(分組方案2)
有4種搶占優先級,比如從高到低依次為:軍人、醫生、老弱病殘孕、其他常人。有4種響應優先級,比如來了一個殘疾人和一個孕婦,同屬一類人,按公德倫理,殘疾人優先,即響應優先級高于孕婦。
4. NVIC_PriorityGroup_3(分組方案3)
有8種搶占優先級,與分組方案2類似,隻是把插隊人群的類别再細分了一下。有2種響應優先級,即同類人群中區分度就不明顯了。
5. NVIC_PriorityGroup_4(分組方案4)
有16種搶占優先級,無響應優先級,這樣就有了更多插隊的情況發生。當然這種情況在現實中是不可接受的,人們彼此也不可能區分出究竟是老太太優先還是老頭優先。
四、中斷編程要點 在配置每個中斷的時候,一般有3個編程要點:
1. 使能外設某個中斷,這個具體由每個外設的相關中斷使能位控制。
2. 初始化NVIC_InitTypeDef結構體,配置中斷優先級分組,設置搶占優先級和響應優先級,使能中斷請求。這個結構體定義見如下代碼清單1。
代碼清單1 NVIC初始化結構體
● NVIC_IRQChannel:用來設置中斷源,不同中斷源的名稱不一樣,且不可寫錯,即使寫錯了程序也不會報錯,隻會導緻不響應中斷。具體的成員配置可參考stm32f10x.h頭文件裡面的IRQn_Type枚舉定義,我們摘錄在代碼清單2中。可以看出,中斷源名字的命名方式為xxx_IRQn,記住這個規則很重要。
代碼清單2 IRQn_Type枚舉定義
● NVIC_IRQChannelPreemptionPriority:搶占優先級,具體的值要根據優先級分組來确定,具體參考表2。
● NVIC_IRQChannelSubPriority:響應優先級,具體的值要根據優先級分組來确定,具體參考表2。
● NVIC_IRQChannelCmd:中斷使能(ENABLE)或失能(DISABLE)。
3. 編寫中斷服務函數。在啟動文件startup_stm32f10x_hd.s中,我們預先為每個中斷都寫了一個中斷服務函數,隻是這些函數都為空,如代碼清單3所示,為的隻是初始化中斷向量表。從其中我們可以看出中斷服務函數的命名規則為xxx_IRQHandler,這才是重點。
代碼清單3 啟動文件中定義好的中斷入口名
實際的中斷服務函數都需要我們重寫,為了方便管理,ST官方建議(并不強制)把中斷服務函數統一寫在stm32f10x_it.c這個庫文件中。最重要的是,中斷服務函數的函數名必須與啟動文件預設的一樣,如果寫錯,那麼系統就在中斷向量表中找不到中斷服務函數的入口,也就無法實現中斷。而且要命的是,Keil編譯不報錯,這就給我們排錯帶來了不小困擾。因此編寫中斷代碼時務必要注意。代碼清單4是stm32f10x_it.c給的中斷服務函數的編寫模闆,我們編寫的時候隻需要将其中的PPP換成需要的中斷名并取消注釋即可。
代碼清單4 中斷服務程序編寫範例
(本文結束)
,
更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!