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就不會響應之前觸發的中斷了。
M0核心與M3核心比較
m3比m0效能更高,原因是 1 m0比m3少好多指令,m0只有56條指令,其中50條是16位的,因此好多m3一條指令就能完成的功能m0需要多條指令 2 m3的資料匯流排和指令匯流排是分開的,可以同時取指和取運算元,而m0取指和取運算元是同一條匯流排 m0相對於m3的優點是更小,所以 便宜。之所以用m...
STM32 F103 外部晶振8M改為12M
stm32 實現外部晶振變換有2種方法 第一種修改系統庫函式 第一步,開啟stm32f10x.h,將 define hse value uint32 t 8000000 修改為 define hse value uint32 t 12000000 重要必須做 第二步,開啟system stm32f1...
關於STM32的I2S通訊飛利浦協議和MSB協議
最近公司乙個專案要用到codec晶元來做語音的採集和輸出,驅動是用的stm32f405的i2s介面。之前沒有深入的了解過i2s的知識,只是大概的知道它是一種用於傳輸音訊資料的匯流排。本來以為沒什麼難的,實際用下來其實也沒感覺有有什麼特別的。但是還是在使用的過程中把自己坑了一把。codec晶元型號是m...