nvic 共支援 1 至 240 個外部中斷輸入(通常外部中斷寫作 irqs)。 具體的數值由晶元廠商在設計晶元時決定。此外, nvic 還支援乙個「永垂不朽」的不可遮蔽中斷(nmi)輸入。nmi 的實際功能亦由晶元製造商決定。在某些情況下, nmi 無法由外部中斷源控制。
異常掩蔽暫存器primask位:
只允許 nmi 和 hard fault 異常,其他中斷/異常都被遮蔽(當前 cpu 優先順序=0,為可程式設計優先順序中的最高優先順序) 。
該暫存器可以通過 mrs 和 msr 以下例方式訪問:
關中斷:
mov r0, #1
msr primask, r0
開中斷
mov r0, #0
msr primask, r0
此外,還可以通過cps指令快速完成上述功能:
cpsid i;
//primask=1 ; 關中斷
cpsie i;
//primask=0 ; 開中斷
cpsid f;
//faultmask=1 ; 關異常
cpsie f;
//faultmask=0 ; 開異常
異常掩蔽暫存器faultmask位:
只允許 nmi,其他所有中斷/異常都被遮蔽(當前 cpu 優先順序=-1)。注意的是,faultmask會在異常退出時自動清零。
掩蔽暫存器雖然能一手遮天,卻都動不了nmi,因為nmi是用在最危急的情況下的。因此系統為它開出單行道,無需**只是不要遲到。
在 stm32 韌體庫中(stm32f10x_nvic.c 和 stm32f10x_nvic.h) 定義了四個函式操作 primask 位和faultmask 位,改變 cpu 的當前優先順序,從而達到控制所有中斷的目的。
下面兩個函式等效於關閉總中斷:
void
nvic_setprimask
(void
);void
nvic_setfaultmask
(void
);
下面兩個函式等效於開放總中斷:
void
nvic_resetprimask
(void
);void
nvic_resetfaultmask
(void
);
上面兩組函式要成對使用,不能交叉使用。
在 3.0 的庫中上述庫函式已經沒有,可以用下列方法實現:
#define cli() __set_primask(1)
#define sei() __set_primask(0)
或者在編譯器裡使用:
__disable_irq()
;// 關閉總中斷
__enable_irq()
;// 開啟總中斷
補充1:異常掩蔽暫存器basepri位
在更精巧的設計中,需要對中斷掩蔽進行更細膩的控制——只掩蔽優先順序低於某一閾值的中斷(它們的優先順序在數字上大於等於某個數)。那麼這個數儲存在**?就儲存在basepri中。
不過,如果往basepri中寫0,則另當別論——basepri將停止掩蔽任何中斷。
如果你需要掩蔽所有優先順序不高於0x60的中斷,則可以如下程式設計:
mov r0, #0x60
msr basepri, r0
如果需要取消 basepri 對中斷的掩蔽,則示例**如下:
mov r0, #0
msr basepri, r0
補充2:關閉全域性中斷時需要注意的問題
但測試發現這樣乙個問題,在關閉總中斷後,如果有中斷觸發,雖然此時不會引發中斷,但在呼叫enable_irq()開啟總中斷後,mcu會立即處理之前觸發的中斷。這說明disable_irq()只是禁止cpu去響應中斷,沒有真正的去遮蔽中斷的觸發,中斷發生後,相應的暫存器會將中斷標誌置位,在enable_irq()開啟中斷後,由於相應的中斷標誌沒有清空,因而還會觸發中斷。所以要想禁止所有中斷,必須對逐個模組的中斷進行disable操作,由於每個模組中斷源有很多,對逐個中斷disable的話比較複雜,較為簡單的方法是通過***_clearitpendingbit()清除中斷標誌或者直接通過***_deinit()來清除暫存器的狀態。這樣在__enable_irq()開啟總中斷後,mcu就不會響應之前觸發的中斷了。
stm32開關總中斷
nvic 共支援 1 至 240 個外部中斷輸入 通常外部中斷寫作 irqs 具體的數值由晶元廠商在設計晶元時決定。此外,nvic 還支援乙個 永垂不朽 的不可遮蔽中斷 nmi 輸入。nmi 的實際功能亦由晶元製造商決定。在某些情況下,nmi 無法由外部中斷源控制。在 stm32 cortex m3...
STM32 M3 M0關於開關總中斷的問題
nvic 共支援 1 至 240 個外部中斷輸入 通常外部中斷寫作 irqs 具體的數值由晶元廠商在設計晶元時決定。此外,nvic 還支援乙個 永垂不朽 的不可遮蔽中斷 nmi 輸入。nmi 的實際功能亦由晶元製造商決定。在某些情況下,nmi 無法由外部中斷源控制。在 stm32 cortex m3...
關於STM32空閒中斷
有一次做乙個東西,為了盡量不占用cpu的處理資料時間,所以就使用dma接收串列埠的資料,但是呢問題來了.怎麼樣才能確定接收到了一條完整的資料了,我們都知道只要開啟dma 那傢伙就不停的把接收的資料放到我們指定的地方.只要接收到一條完整的資料我就該去處理了 關於空閒中斷,就是說每接收到一條完整的資料就...