STM32中斷相關知識總結

學術馬發表於2020-10-07

STM32中斷相關知識總結

一:中斷是什麼?

中斷是指處理器執行過程中,出現某些意外情況,CPU能自動停止正在執行的程式並轉入處理新情況的程式(中斷服務函式),處理完畢後又返回原被暫停的程式繼續執行。
CM3和CM7 核心支援 256 箇中斷,其中包含了 16 個核心中斷和 240 個外部中斷,並且具有 256級的可程式設計中斷設定。但 STM32 並沒有使用 CM3或CM7 核心的全部東西,而是隻用了它的一部分。STM32F1系列有 84 箇中斷,包括 16 個核心中斷和 68 個可遮蔽中斷,STM32F767xx總共有118箇中斷,包括10個核心中斷和108個可遮蔽中斷,他們都具有16級可程式設計的中斷優先順序。我們經常使用的一般是它們的可遮蔽中斷。

二:什麼是可遮蔽中斷和不可遮蔽中斷?
1:可由程式控制其遮蔽的中斷稱為可遮蔽中斷。
2:不能由程式控制其遮蔽,處理機一定要立即處理的中斷稱為非遮蔽中斷或不可遮蔽中斷。
不可遮蔽中斷主要用於斷電、電源故障等必須立即處理的情況

三:核心中斷和外部中斷
STM32F1的核心中斷
在這裡插入圖片描述
STM32F1的外部中斷
在這裡插入圖片描述
三:什麼是中斷優先順序
在實際系統中,常常遇到多箇中斷源同時請求中斷的情況,這時CPU必須確定首先為哪一個中斷源服務,以及服務的次序。解決的方法是中斷優先排隊,即根據中斷源請求的輕重緩急,排好中斷處理的優先次序即優先順序( Priority ),又稱優先權,先響應優先順序最高的中斷請求。另外,當CPU正在處理某一中斷時,要能響應另一個優先順序更高的中斷請求,而遮蔽掉同級或較低階的中斷請求,形成中斷巢狀。

四:STM32的中斷管理辦法
對STM32中斷進行分組,組0-4.同時,對每個中斷設定一個搶佔優先順序和響應優先順序。

五:搶佔優先順序和響應優先順序的區別?
1:高優先順序的搶佔優先順序可以打斷正在進行的低搶佔優先順序中斷。
2:搶佔 優先順序相同的中斷、高優先順序不可以打斷低響應優先順序的中斷。
3:搶佔優先順序相同的中斷,當兩個中斷同時發生的情況下,哪個響應優先順序高,哪個先執行。
4:如果兩個中斷的搶佔優先順序和響應優先順序都是一樣的話,則看哪個中斷先發生就先執行。
例項說明:假定設定中斷優先順序組為 2,然後設定
中斷 3(RTC 中斷)的搶佔優先順序為 2,響應優先順序為 1。
中斷 6(外部中斷 0)的搶佔優先順序為 3,響應優先順序為 0。
中斷 7(外部中斷 1)的搶佔優先順序為 2,響應優先順序為 0。
那麼這 3 箇中斷的優先順序順序為:中斷 7>中 斷 3>中斷 6。中斷 3 和中斷 7 都可以打斷中斷 6 的中斷。而中斷 7 和中斷 3 卻不可以相互打斷!

六;中斷優先順序分組
STM32將中斷分為5個組,組0-4。該分組的設定是由SCB->AIRCR 暫存器的 bit10~8 來定義的。
在這裡插入圖片描述通過這個表,可以清楚的看到組 0~4 對應的配置關係,例如分組設定為 3,那麼此時所有的 68 箇中斷,每個中斷的中斷優先暫存器的高四位中的最高 3 位是搶佔優先順序,低 1 位是響應優先順序。每個中斷,你可以設定搶佔優先順序為 0~7,響應優先順序為 1 或 0。搶佔優先順序的級別高於響應優先順序。而數值越小所代表的優先順序就越高

七:中斷優先順序分組函式

//設定 NVIC 分組
//NVIC_Group:NVIC 分組 0~4 總共 5 組 
void MY_NVIC_PriorityGroupConfig(u8 NVIC_Group)
{ 
u32 temp,temp1; 
//為什麼取“反”,注意優先順序分組的標誌,111對應組0,110對應組1
//可以看到都是相應的組號取反後的結果
temp1=(~NVIC_Group)&0x07;//取後三位
temp1<<=8;
temp=SCB->AIRCR; //讀取先前的設定
temp&=0X0000F8FF; //清空先前分組
temp|=0X05FA0000; //寫入鑰匙
temp|=temp1; //寫入優先順序分組
SCB->AIRCR=temp; //設定分組
}

STM32 的 5 個分組是通過設定 SCB->AIRCR 的 BIT[10:8]來實
現的, SCB->AIRCR 的修改需要通過在高 16 位寫入 0X05FA 這個金鑰才能修改的,故在設定 AIRCR 之前,應該把金鑰加入到要寫入的內容的高 16 位,以保證能正常的寫入 AIRCR。在修改 AIRCR 的時候,我們一般採用讀-改-寫的步驟,來實現不改變 AIRCR 原來的其他設定。

八:中斷設定相關暫存器

typedef struct
{
 __IO uint32_t ISER[8]; //中斷使能暫存器組
 uint32_t RESERVED0[24];
 __IO uint32_t ICER[8]; //中斷除能暫存器組
 uint32_t RSERVED1[24];
 __IO uint32_t ISPR[8]; //中斷掛起控制暫存器組
 uint32_t RESERVED2[24];
 __IO uint32_t ICPR[8]; //中斷解掛控制暫存器組
 uint32_t RESERVED3[24];
 __IO uint32_t IABR[8]; //中斷啟用標誌位暫存器組
 uint32_t RESERVED4[56];
 __IO uint8_t IP[240]; //中斷優先順序控制暫存器組
 uint32_t RESERVED5[644];
 __O uint32_t STIR; //軟體觸發中斷暫存器組
} NVIC_Type;

ISER[8]:ISER 全稱是:Interrupt Set-Enable Registers,這是一箇中斷使能暫存器組。 CM3 核心支援 256 箇中斷,這裡用 8 個 32 位暫存器來控制,每個位控制一箇中斷。但是STM32 的可遮蔽中斷最多隻有 68 個(互聯型),所以對我們來說,有用的就是三個(ISER[0~2]]),總共可以表示 96 箇中斷。而 STM32 只用了其中的前 68 位。ISER[0]的 bit0~31 分別對應中斷0~31;ISER[1]的 bit0~32 對應中斷 32~63;ISER[2]的 bit0~3 對應中斷 64~67;這樣總共 68 箇中斷就分別對應上了。你要使能某個中斷,必須設定相應的 ISER 位為 1,使該中斷被使能(這裡僅僅是使能,還要配合中斷分組、遮蔽、IO 口對映等設定才算是一個完整的中斷設定)。
ICER[8]:全稱是:Interrupt Clear-Enable Registers,是一箇中斷除能暫存器組。該暫存器組與 ISER 的作用恰好相反,是用來清除某個中斷的使能的。其對應位的功能,也和 ICER 一樣。這裡要專門設定一個 ICER 來清除中斷位,而不是向 ISER 寫 0 來清除,是因為 NVIC 的這些暫存器都是寫 1 有效的,寫 0 是無效的。具體為什麼這麼設計,是因為通過這種方式,使能/除能中斷時只需把“當事位”寫成1,其它的位可以全部為零。再也不用像以前那樣,害怕有些位被寫入 0 而破壞其對應的中斷設定(寫 0 沒有效果),從而實現每個中斷都可以自顧地設定,而互不侵犯——只需單一的寫指令,不再需要讀‐改‐寫。
在這裡插入圖片描述
ISPR[8]:全稱是:Interrupt Set-Pending Registers,是一箇中斷掛起控制暫存器組。如果中斷髮生時,正在處理同級或高優先順序異常,或者被掩蔽,則中斷不能立即得到響應。此時中斷被懸起。中斷的懸起狀態可以通過“中斷設定懸起暫存器(SETPEND)”和“中斷懸起清除暫存器(CLRPEND)”來讀取,還可以寫它們來手工懸起中斷。每個位對應的中斷和 ISER 是一樣的。通過置 1,可以將正在進行的中斷掛起,而執行同級或更高階別的中斷。寫 0 是無效的。
ICPR[8]:全稱是:Interrupt Clear-Pending Registers,是一箇中斷解掛控制暫存器組。其作用與 ISPR 相反,對應位也和 ISER 是一樣的。通過設定 1,可以將掛起的中斷接掛。寫 0 無效。
在這裡插入圖片描述

IABR[8]:全稱是:Interrupt Active Bit Registers,是一箇中斷啟用標誌位暫存器組。對應位所代表的中斷和 ISER 一樣,如果為 1,則表示該位所對應的中斷正在被執行。這是一個只讀寄
存器,通過它可以知道當前在執行的中斷是哪一個。在中斷執行完了由硬體自動清零。由於支援巢狀,允許高優先順序異常搶佔某個ISR。然而,哪怕一箇中斷被搶佔,其活動狀態也依然為1。
在這裡插入圖片描述

IP[240]:全稱是:Interrupt Priority Registers,是一箇中斷優先順序控制的暫存器組。這個寄
存器組相當重要!STM32 的中斷分組與這個暫存器組密切相關。IP 暫存器組由 240 個 8bit 的暫存器組成,每個可遮蔽中斷佔用 8bit,這樣總共可以表示 240 個可遮蔽中斷。而 STM32 只用到了其中的 68 個。IP[67]~IP[0]分別對應中斷 67~0。而每個可遮蔽中斷佔用的 8bit 並沒有全部使用,而是 只用了高 4 位。這 4 位,又分為搶佔優先順序和子優先順序。搶佔優先順序在前,子優先順序
在後。而這兩個優先順序各佔幾個位又要根據 SCB->AIRCR 中的中斷分組設定來決定。
在這裡插入圖片描述
九:相關配置函式

//設定 NVIC 
//NVIC_PreemptionPriority:搶佔優先順序
//NVIC_SubPriority :響應優先順序
//NVIC_Channel :中斷編號
//NVIC_Group :中斷分組 0~4
//注意優先順序不能超過設定的組的範圍!否則會有意想不到的錯誤
//組劃分:
//組 0:0 位搶佔優先順序,4 位響應優先順序
//組 1:1 位搶佔優先順序,3 位響應優先順序
//組 2:2 位搶佔優先順序,2 位響應優先順序
//組 3:3 位搶佔優先順序,1 位響應優先順序
//組 4:4 位搶佔優先順序,0 位響應優先順序
//NVIC_SubPriority 和 NVIC_PreemptionPriority 的原則是,數值越小,越優先
void MY_NVIC_Init(u8 NVIC_PreemptionPriority,u8 NVIC_SubPriority,u8 NVIC_Channel,
u8 NVIC_Group)
{ 
u32 temp;
MY_NVIC_PriorityGroupConfig(NVIC_Group);//設定分組
temp=NVIC_PreemptionPriority<<(4-NVIC_Group); 
temp|=NVIC_SubPriority&(0x0f>>NVIC_Group);
temp&=0xf; //取低四位 
NVIC->ISER[NVIC_Channel/32]|=(1<<NVIC_Channel%32);
//使能中斷位(要清除的話,相反操作就 OK) 
NVIC->IP[NVIC_Channel]|=temp<<4; //設定響應優先順序和搶斷優先順序
}

參考:《STM32不完全手冊_暫存器版本_V3.1》
《Cortex-M3權威指南(中文)》
正點原子相關教程

相關文章