nvic 共支援 1 至 240 個外部中斷輸入(通常外部中斷寫作 irqs)。 具體的數值由晶元廠商在設計晶元時決定。此外, nvic 還支援乙個「永垂不朽」的不可遮蔽中斷(nmi)輸入。nmi 的實際功能亦由晶元製造商決定。在某些情況下, nmi 無法由外部中斷源控制。
在 stm32/cortex-m3 中是通過改變 cpu 的當前優先順序來允許或禁止中斷。
異常掩蔽暫存器primask位:只允許 nmi 和 hard fault 異常,其他中斷/異常都被遮蔽(當前 cpu 優先順序=0,為可程式設計優先順序中的最高優先順序) 。
該暫存器可以通過 mrs 和 msr 以下例方式訪問:
1. 關中斷mov r0, #1
msr primask, r0
2. 開中斷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);
上面兩組函式要成對使用,不能交叉使用。
例如: 第一種方法(常用): nvic_setprimask(); //關閉總中斷
nvic_resetprimask();//開放總中斷
第二種方法: nvic_setfaultmask(); //關閉總中斷
nvic_resetfaultmask(); //開放總中斷
在 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:關閉全域性中斷時需要注意的問題(未驗證是否確有此問題)
stm32在使用時有時需要禁用全域性中斷。但測試發現乙個問題,在關閉總中斷後,如果有中斷觸發,雖然此時不會引發中斷,但在呼叫__enable_irq()開啟總中斷後,mcu會立即處理之前觸發的中斷。這說明__disable_irq()只是禁止cpu去響應中斷,沒有真正的去遮蔽中斷的觸發,中斷發生後,相應的暫存器會將中斷標誌置位,在__enable_irq()開啟中斷後,由於相應的中斷標誌沒有清空,因而還會觸發中斷。
所以要想禁止所有中斷,必須對逐個模組的中斷進行disable操作,由於每個模組中斷源有很多,對逐個中斷disable的話比較複雜,較為簡單的方法是通過***_clearitpendingbit()清除中斷標誌或者直接通過***_deinit()來清除暫存器的狀態。這樣在__enable_irq()開啟總中斷後,mcu就不會響應之前觸發的中斷了。
STM32關於開關總中斷的問題
nvic 共支援 1 至 240 個外部中斷輸入 通常外部中斷寫作 irqs 具體的數值由晶元廠商在設計晶元時決定。此外,nvic 還支援乙個 永垂不朽 的不可遮蔽中斷 nmi 輸入。nmi 的實際功能亦由晶元製造商決定。在某些情況下,nmi 無法由外部中斷源控制。異常掩蔽暫存器primask位 只...
STM32 禁用或開啟總中斷
今天把之前自己的一些在中斷方面所產生的疑惑把具體的解決辦法給大家分享一下,希望能夠幫到大家。stm32在使用時有時需要禁用全域性中斷,比如mcu在公升級過程中需禁用外部中斷,防止公升級過程中外部中斷觸發導致公升級失敗。arm mdk中提供了如下兩個介面來禁用和開啟總中斷 disable irq 關閉...
STM32外部中斷
一 基本概念 arm coetex m3核心共支援256個中斷,其中16個內部中斷,240個外部中斷和可程式設計的256級中斷優先順序的設定。stm32目前支援的中斷共84個 16個內部 68個外部 還有16級可程式設計的中斷優先順序的設定,僅使用中斷優先順序設定8bit中的高4位。stm32可支援...