關於單片機中斷

一、基本概念

1.ARM cortex_m3 內核支持 256 箇中斷(16 個內核+240 外部)和可編程 256 級中斷優先級

的設置,與其相關的中斷控制和中斷優先級控制寄存器(NVIC、SYSTICK 等)也都屬於

cortex_m3 內核的部分。STM32 採用了 cortex_m3 內核,所以這部分仍舊保留使用,但 STM32

並沒有使用 cortex_m3 內核全部的東西(如內存保護單元 MPU 等),因此它的 NVIC 是

cortex_m3 內核的 NVIC 的子集。

2.STM32 目前支持的中斷共為 84 個(16 個內核+68 個外部),和 16 級可編程中斷優先級

的設置(僅使用中斷優先級設置 8bit 中的高 4 位,見後面解釋)。《參考最新 101xx-107xx

STM32 Reference manual, RM0008》。

3.以下主要對“外部中斷通道”進行說明。

對於 cortex_m3 內核所支持的 240 個外部中斷,我在這裡使用了“中斷通道”這個概

念,因為儘管每個中斷對應一個外圍設備,但該外圍設備通常具備若干個可以引起中斷的

中斷源或中斷事件。而該設備的所有的中斷都只能通過該指定的“中斷通道”向內核申請

中斷。因此,下面關於中斷優先級的概念都是針對“中斷通道”的。當該中斷通道的優先

級確定後,也就確定了該外圍設備的中斷優先級,並且該設備所能產生的所有類型的中斷,

都享有相同的通道中斷優先級。至於該設備本身產生的多箇中斷的執行順序,則取決於用

戶的中斷服務程序。

4. STM32 可以支持的 68 個外部中斷通道,已經固定的分配給相應的外部設備。每個中斷

通道都具備自己的中斷優先級控制字節 PRI_n(8 位,但在 STM32 中只使用 4 位,高 4 位有

效),每 4 個通道的 8 位中斷優先級控制字(PRI_n)構成一個 32 位的優先級寄存器(Priority

Register)。68 個通道的優先級控制字至少構成 17 個 32 位的優先級寄存器,它們是 NVIC

寄存器中的一個重要部分。

5.對於這 4bit 的中斷優先級控制位還必須分成 2 組看:從高位開始,前面是定義搶先式優

先級的位,後面用於定義子優先級。4bit 的分組組合可以有以下幾種形式:

編 號 分配情況

7 0:4 無搶先式優先級,16 個子優先級

6 1:3 2 個搶先式優先級,8 個子優先級

5 2:2 4 個搶先式優先級,4 個子優先級

4 3:1 8 個搶先式優先級,2 個子優先級

3/2/1/0 4:0 16 個搶先式優先級,無子優先級

6.在一個系統中,通常只使用上面 5 種分配情況的一種,具體採用哪一種,需要在初始化

時寫入到一個 32 位寄存器 AIRC(Application Interrupt and Reset Control Register)的第[10:8]這 3 個位中。這 3 個 bit 位有專門的稱呼:PRIGROUP(具體寫操作後面介紹)。

比如你將 0x05(即上表中的編號)寫到 AIRC 的[10:8]中,那麼也就規定了你的系統中只

有 4 個搶先式優先級,相同的搶先式優先級下還可以有 4 個不同級別的子優先級。

7.AIRC 中 PRIGROUP 的值規定了設置和確定每個外部中斷通道優先級的格式。例如,在上

面將 0x05 寫入了 AIRC 中 PRIGROUP,也就規定了當前系統中只能有 4 個搶先式優先級,相

同的搶先式優先級下還可以有 4 個不同級別的子優先級,他們分別為:

位[7:6]

位[5:4]

位[3:0]

00 0 號搶先優先級 00 0 號子優先級 無效

01 1 號搶先優先級 01 1 號子優先級 無效

10 2 號搶先優先級 10 2 號子優先級 無效

11 3 號搶先優先級 11 3 號子優先級 無效

8.如果在你的系統中使用了 TIME2(中斷通道 28)和 EXTI0(中斷通道 6)兩個中斷,而

TIME2 中斷必須優先響應,而且當系統在執行 EXIT0 中斷服務時也必須打斷(搶先、嵌套),

就必須設置 TIME2 的搶先優先級比 EXTI0 的搶先優先級要高(數目小)。假定 EXTI0 為 2 號

搶先優先級,那麼 TIME2 就必須設置成 0 或 1 號搶先優先級。這些工作需要在 AIRC 中的

PRIGROUP 設置完成,確定了整個系統所具有的優先級個數後,再分別對每個中斷通道(設

備)進行設置。

9.具體優先級的確定和嵌套規則。ARM cortex_m3(STM32)規定

a/ 只能高搶先優先級的中斷可以打斷低搶先優先級的中斷服務,構成中斷嵌套。

b/ 當 2(n)個相同搶先優先級的中斷出現,它們之間不能構成中斷嵌套,但 STM32 首

先響應子優先級高的中斷。

c/ 當 2(n)個相同搶先優先級和相同子優先級的中斷出現,STM32 首先響應中斷通道

所對應的中斷向量地址低的那個中斷(見 ROM0008,表 52)。

具體一點:

0 號搶先優先級的中斷,可以打斷任何中斷搶先優先級為非 0 號的中斷;1 號搶先優先

級的中斷,可以打斷任何中斷搶先優先級為 2、3、4 號的中斷;……;構成中斷嵌套。

如果兩個中斷的搶先優先級相同,誰先出現,就先響應誰,不構成嵌套。如果一起出

現(或掛在那裡等待),就看它們 2 個誰的子優先級高了,如果子優先級也相同,就看它們

的中斷向量位置了。

10.上電 Reset 後,寄存器 AIRC 中 PRIGROUP[10:8]的值為 0(編號 0),因此此時系統使

用 16 個搶先優先級,無子優先級。另外由於所有外部中斷通道的優先級控制字 PRI_n 也都

是 0,所以根據上面的定義可以得出,此時 68 個外部中斷通道的搶先優先級都是 0 號,沒

有子優先級的區分。故此時不會發生任何的中斷嵌套行為,誰也不能打斷當前正在執行的中

斷服務。當多箇中斷出現後,則看它們的中斷向量地址:地址越低,中斷級別越高,STM32

優先響應。

注意:此時內部中斷的搶先優先級也都是 0 號,由於它們的中斷向量地址比外部中斷向

量地址都低,所以它們的優先級比外部中斷通道高,但如果此時正在執行一個外部中斷服務,

它們也必須排隊等待,只是可以插隊,當正在執行的中斷完成後,它們可以優先得到執行。

瞭解以上基本概念還是不夠的,還要了解具體中斷的控制有那些途徑,中斷服務程序

如何正確的編寫。下面的描述主要以 TIME2 通道為例。

二、中斷控制

1.對於 STM32 講,外部中斷通道位置 28(35 號優先級)是給外部設備 TIME2 的,但 TIME2

本身能夠引起中斷的中斷源或事件有好多個,比如更新事件(上溢/下溢)、輸入捕獲、輸出

匹配、DMA 申請等。所有 TIME2 的中斷事件都是通過一個 TIME2 的中斷通道向 STM32 內核提

出中斷申請,那麼 STM32 中如何處理和控制 TIME2 和它眾多的、不同的、中斷申請呢?

(題外話:STM32 中的一個通用定時計數器,就比 8 位控制器(如 AVR,MCS-51 就更不必說了)中 TIME

要複雜多了。學過 AVR 的,可能對輸入捕獲、輸出匹配等還有概念,但如果你學的標準架構的 MCS-51,那

麼上手 32 位可能困難就更多了。所以我一直推薦學習 8 位機應該認真的從 AVR 開始。儘管 51 有很大的市

場,價格也相對便宜,但從長遠的眼光看問題,從後續掌握 32 位的使用,考慮到學生的可持續發展,AVR

應該是比較好的選擇。)

2.cortex_m3 內核對於每一個外部中斷通道都有相應的控制字和控制位,用於單獨的和總

的控制該中斷通道。它們包括有:

z 中斷優先級控制字:PRI_n(上面提到的)

z 中斷允許設置位:在 ISER 寄存器中

z 中斷允許清除位:在 ICER 寄存器中

z 中斷懸掛 Pending(排隊等待)位置位:在 ISPR 寄存器中(類似於置中斷通道標誌位)

z 中斷懸掛 Pending(排隊等待)位清除:在 ICPR 寄存器中(用於清除中斷通道標誌位)

z 正在被服務(活動)的中斷(Active)標誌位:在 IABR 寄存器中,(只讀,可以知道當

前內核正在處理哪個中斷通道)

因此,與 TIME2 中斷通道相關的,在 NVIC 中有 13 個 bits,它們是 PRI_28(IP[28]),

的 8 個 bits(只用高 4 位);加上中斷通道允許,中斷通道清除(相當禁止中斷),中斷通道

Pending 置位(我的理解是中斷請求發生了,但當前有其它中斷服務在執行,你的中斷級別

又不能打斷別人,所以 Pending 等待,這個應該由硬件自動置位的),中斷 Pending 位清除

(可以通過軟件將本次中斷請求、且尚處在 Pending 狀態,取消掉),正在被服務的中斷

(Active)標誌位,各 1 個 bit。

上面的控制字和控制位都是分佈在 NVIC 的寄存器組中的,可惜在 STM32 手冊中竟然不

給出任何的解釋和說明。

3.作為外圍設備 TIME2 本身也包括更具體的,管理自己不同中斷的中斷控制器(位),它們

主要是自身各個不同類型中斷的允許控制位,和各自相應的中斷標誌位(這個在 STM32 的手

冊中有詳細的說明了)。

4.在弄清楚 2、3 兩點的基礎上,我們可以全程、全面和綜合的來了解 TIME2 的中斷過程,

以及如何控制的。

a/ 初始化過程

首先要設置寄存器 AIRC 中 PRIGROUP 的值,規定系統中的搶先優先級和子優先級的個數(在 4 個 bits 中佔用的位數);

設置 TIME2 本身的寄存器,允許相應的中斷,如允許 UIE(TIME2_DIER 的第[0]位)

設置 TIME2 中斷通道的搶先優先級和子優先級(IP[28],在 NVIC 寄存器組中)

設置允許 TIME2 中斷通道。在 NVIC 寄存器組的 ISER 寄存器中的一位。

b/ 中斷響應過程

當 TIME2 的 UIE 條件成立(更新,上溢或下溢),硬件將 TIME2 本身寄存器中 UIE 中斷

標誌置位,然後通過 TIME2 中斷通道向內核申請中斷服務。

此時內核硬件將 TIME2 中斷通道的 Pending 標誌置位(相當與中斷通道標誌置位),表

示 TIME2 有中斷申請。

如果當前有中斷在處理,TIME2 的中斷級別不夠高,那麼就保持 Pending 標誌,當然用

戶可以在軟件中通過寫 ICPR 寄存器中相應的位把本次中斷清除掉。

當內核有空,開始響應 TIME2 的中斷,進入 TIME2 的中斷服務。此時硬件將 IABR 寄存

器中相應的標誌位置位,表示 TIME2 中斷正在被處理。同時硬件清除 TIME2 的 Pending 標誌

位。

c/ 執行 TIME2 的中斷服務程序

所有 TIME2 的中斷事件,都是在一個 TIME2 中斷服務程序中完成的,所以進入中斷程序

後,中斷程序需要首先判斷是哪個 TIME2 的具體事件的中斷,然後轉移到相應的服務代碼段

去。

注意不要忘了把該具體中斷事件的中斷標誌位清除掉,硬件是不會自動清除 TIME2 寄存

器中具體的中斷標誌位的。

如果 TIME2 本身的中斷事件多於 2 個,那麼它們服務的先後次序就由用戶編寫的中斷服

務決定了。換句話說,對於 TIME2 本身的多箇中斷的優先級,系統是不能設置的。所以用戶

在編寫服務程序時,應該根據實際的情況和要求,通過軟件的方式,將重要的中斷優先處理

掉。

當然你也可以每次中斷服務只處理其中的一個,然後再次進入中斷,處理下一個。

d/ 中斷返回

內核執行完中斷服務後,便進入中斷返回過程,在這個過程中需要:

硬件將 IABR 寄存器中相應的標誌位清另,表示該中斷處理完成

如果 TIME2 本身還有中斷標誌位置位,表示 TIME2 還有中斷在申請,則重新將 TIME2

的 Pending 標誌置為 1,等待再次進入 TIME2 的中斷服務。


分享到:


相關文章: