這篇文章是對 Cortex-M3 內核中斷系統 和 STM32F1 系列 NVIC(嵌套向量中斷控制器) 的解析說明。我將從結構清晰、層次分明的角度,對 NVIC 中斷優先級分組的概念和 STM32F103 的實際情況做一個系統性的總結與敘述。
參考資料:
STM32F1xx官方資料:《STM32中文參考手冊V10》---- 第9章 中斷和事件
附圖:
為什么一定需要中斷?
中斷的本質是打破“順序執行”的限制,使 CPU 能在關鍵事件發生時立即響應,從而實現多任務、高實時性和高效率運行。
如果沒有中斷會發生什么?
假設沒有中斷,CPU 想要獲取外設狀態(比如按鍵、串口、傳感器數據),怎么辦?
那我們只能使用輪詢(Polling):
while (1) {if (UART_GetFlag() == 1) {// 接收到數據}
}
使用這種方式的缺點:
CPU效率低 一直忙等,浪費資源
實時性差 響應時間取決于輪詢頻率
多任務困難 輪詢一個設備時,其他任務無法執行
數據易丟失 如果輪詢間隔太長,可能錯過事件而中斷則具備解決這些問題的優勢:
高實時性 外設事件立即響應
高效率 CPU 空閑時間可執行主任務
多任務協作 支持 RTOS、任務調度
異步處理 外設與主程序解耦
可靠性提升 不易丟數據、不依賴輪詢頻率
引入中斷的優勢: 中斷機制允許 CPU “只在需要時被打斷”,避免無效等待。
中斷觸發后:
- CPU 自動跳轉到中斷服務函數(ISR)
- ISR 執行完畢后自動返回原來任務
- 響應迅速,處理高效
幾乎所有操作皆離不開中斷:
按鍵響應 用戶按鍵瞬間觸發 EXTI 外部中斷
串口通信 接收到數據立即處理 USART 中斷
定時任務 每秒觸發一次事件 TIM 定時器中斷
CAN 總線 收到幀立即解析 CAN 中斷
操作系統調度 多任務切換 SysTick 定時器中斷
沒有中斷 | 有中斷 |
---|---|
一切順序執行 | 支持事件驅動 |
必須輪詢外設 | 被動等待變主動響應 |
單任務運行 | 支持多任務調度 |
類比 | 你每分鐘看一次手機有沒有來電(輪詢) 手機響了你立刻接聽(中斷) |
效率 | 浪費精力,不及時 高效、及時響應 |
中斷機制是從串行思維 → 并發思維的轉變,是現代計算系統的基石。
中斷是嵌入式系統中不可或缺的機制,它讓 CPU 不再“苦等”,而是“即來即辦”,極大提升了系統的實時性、效率與響應能力。
一、Cortex-M3 內核支持的中斷資源(理論上限)
項目 | 數量 |
---|---|
核心中斷(系統異常) | 16 個(含 HardFault、SysTick、PendSV 等) |
外部中斷(可屏蔽) | 最多 240 個 |
可編程中斷優先級級別 | 256(8位) |
這表示 Cortex-M3 可以 支持 256 級中斷優先級(理論),但 MCU 廠商會根據芯片實際資源進行裁剪。
二、STM32F103 實際中斷資源(裁剪后)
項目 | STM32F103xx | STM32F107xx |
---|---|---|
內核中斷 | 16 個 | 16 個 |
外部中斷(可屏蔽) | 60 個 | 68 個 |
可用中斷優先級位數 | 4 位(即 16 級) | 同上 |
總中斷源數 | 16(系統) + 60(外部) = 76 | 84 |
STM32 只是用了 Cortex-M3 的一部分功能,比如只用了
4位中斷優先級
而不是 8 位。
NVIC 優先級的兩個概念
那么有幾十個中斷,怎么管理這么多的中斷呢?于是,我們需要對NVIC中斷優先級分組。
中斷管理方法:首先,對STM32中斷進行分組,組0~4。同時,對每個中斷設置一個搶占優先級和一個響應優先級值。
分組配置是在寄存器
SCB->AIRCR
中配置:
綜上↓:
CM3內核支持256個中斷,其中包含了16個內核中斷和240個外部中斷,并且具有256級的可編程中斷設置。
STM32并沒有使用CM3內核的全部東西,而是只用了它的一部分。
STM32有84個中斷,包括16個內核中斷和68個可屏蔽中斷,具有16級可編程的中斷優先級。
STM32F103系列上面,又只有60個可屏蔽中斷(在107系列才有68個)
NVIC 中斷優先級的兩個維度:搶占優先級 & 響應優先級
- 搶占優先級(Preemption Priority)
- 控制中斷是否能“打斷”其他中斷
- 數字越小,優先級越高
- 響應優先級 / 子優先級(Sub Priority)
- 控制多個中斷“同時觸發”時誰先執行
- 不影響中斷嵌套
中斷優先級比較規則總結:
1.高優先級的搶占優先級是可以打斷正在進行的低搶占優先級中斷的。
2.搶占優先級相同的中斷,高響應優先級不可以打斷低響應優先級的中斷。
3.搶占優先級相同的中斷,當兩個中斷同時發生的情況下,哪個響應優先級高,哪個先執行。
4.如果兩個中斷的搶占優先級和響應優先級都是一樣的話,則看哪個中斷先發生就先執行;
中斷優先級分組(Priority Group)
STM32 使用 AIRCR
寄存器 配置優先級分組,分組如下:
分組 | 搶占優先級位數 | 子優先級位數 | 描述 |
---|---|---|---|
Group 0 | 0 bit | 4 bit | 全子優先級,無嵌套 |
Group 1 | 1 bit | 3 bit | 最多兩級嵌套 |
Group 2 | 2 bit | 2 bit | 推薦使用,嵌套+排序 |
Group 3 | 3 bit | 1 bit | 高嵌套,低排序 |
Group 4 | 4 bit | 0 bit | 全搶占優先級,滿嵌套 |
設置方式:
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); // 2位搶占 + 2位子優先級
這是中斷優先級分組函數: void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup);
void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup)
{assert_param(IS_NVIC_PRIORITY_GROUP(NVIC_PriorityGroup));SCB->AIRCR = AIRCR_VECTKEY_MASK | NVIC_PriorityGroup;
}應用:NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
舉例分析強化理解
假定設置中斷優先級組為2,然后設置中斷3(RTC中斷)的搶占優先級為2,響應優先級為1。 中斷6(外部中斷0)的搶占優先級為3,響應優先級為0。中斷7(外部中斷1)的搶占優先級為2,響應優先級為0。
- 設置分組2(2位搶占 + 2位響應)
- 中斷配置如下:
中斷號 | 中斷類型 | 搶占優先級 | 響應優先級 |
---|---|---|---|
中斷3 | RTC中斷 | 2 | 1 |
中斷6 | 外部中斷0(EXTI0 |