五、NVIC
中斷向量嵌套控制器是用來管理所有中斷和事件的,包括中斷的使能和除能,中斷的優先級。這個是屬於內核的東西,所以ST的參考手冊上對它的描述較少,但他又是十分重要的東西,要了解它就要看ARM的《Cortex™-M4 Devices Generic User Guide》。
相關寄存器
譯自《Cortex™-M4 Devices Generic UserGuide》,若有錯誤,請以原文爲準。
中斷使能寄存器NVIC_ISER[8]
中斷使能寄存器共有8個,ISER[0]設置0~31號中斷的使能,ISER[1]設置32~63號中斷的使能,如此類推。以下以ISER[0]爲例:
[31:0] SETENA中斷設置使能位。
寫:
0 =無影響
1 =使能中斷。
讀:
0 =中斷是禁止的
1=中斷已經被使能
如果要使能0號中斷,就向該寄存器的0位寫1,如果要使能38號中斷,就向NVIC_ISER[1]的6位寫1,如此類推,至於哪個中斷對應哪個中斷號,請參見參考手冊《RM0090 Reference manual》中的第9章Table 30. Vector table的Position一列。
中斷除能寄存器NVIC_ICER[8]
中斷除能寄存器共有8個,ICER[0]設置0~31號中斷除能,ICER[1]設置32~63號中斷的使能,如此類推。以下以ICER[0]爲例:
[31:0] SETENA中斷設置使能位。
寫:
0 =無影響
1 =除能中斷。
讀:
0 =中斷是禁止的
1=中斷已經被使能
以下寄存器均爲8個,僅以***R[0]爲例
中斷掛起設置寄存器NVIC_ISPR[8]
[31:0]SETPEND中斷掛起設置位。
寫:
0 =無影響
1 =改變中斷狀態爲掛起。
讀:
0 =中斷沒有掛起
1 =中斷正在等待處理。
解除中斷掛起寄存器NVIC_ICPR[8]
[31:0] CLRPEND中斷清除掛起位。
寫:
0 =無影響
1 =刪除中斷的掛起狀態。
讀:
0 =沒有掛起的中斷
1 =中斷正在等待處理。
中斷激活位寄存器NVIC_IABR[8]
[31:0]中斷活躍的標誌:
0 =中斷不活躍
1 =中斷活躍。
如果相應的中斷的狀態是作爲一個活躍的或活躍和正被掛起的,讀該位將會讀出1。
中斷優先級寄存器NVIC_IPR[60]
中斷優先級寄存器爲60個32位寄存器,st的結構體中用了240個8位的字節數組NVIC->IP[240]來映射,每一個對應一箇中斷的優先級。
ARM的中斷優先級分兩種,搶佔優先級和響應優先級。
具有高搶佔式優先級的中斷可以在具有低搶佔式優先級的中斷處理過程中被響應,即中斷嵌套,或者說高搶佔式優先級的中斷可以嵌套低搶佔式優先級的中斷。
當兩個中斷源的搶佔式優先級相同時,這兩個中斷將沒有嵌套關係,當一箇中斷到來後,如果正在處理另一箇中斷,這個後到來的中斷就要等到前一箇中斷處理完之後才能被處理。如果這兩個中斷同時到達,則中斷控制器根據他們的響應優先級高低來決定先處理哪一個;如果他們的搶佔式優先級和響應優先級都相等,則根據他們在中斷表中的排位順序決定先處理哪一個。
中斷優先級分組就是把優先級寄存器分割,分開哪幾位是響應優先級,哪幾位是搶佔優先級。至於怎樣設置分組,就要看一個不屬於NVIC的寄存器了。
應用中斷和復位控制寄存器SCB_AIRCR
在這裏我們需要看的是[31:16]位和[10:8]位,[31:16]位是識別碼,用以保護此寄存器不會被意外修改,[10:8]位就是中斷優先級分組的設置位。
[31:16]
寫:VECTKEYSTAT
讀:VECTKEY
RW註冊鍵:
讀爲0xFA05
寫入時,要寫0x05FA到 VECTKEY,否則寫入將被忽略。
[10:8]中斷優先級
每一個ARM的M4中斷優先級設計爲可編程的8位,具體到stm32f4就只留給用戶4位共16級的可編程優先級,其中低4位已被佔用。也就是說stm32f4的優先級分組情況如下表所示:
[10:8] |
分割點 |
搶佔優先級位 |
響應優先級位 |
搶佔優先級數 |
響應優先級數 |
0b011 |
xxxx |
[7:4] |
none |
16 |
1 |
0b100 |
xxx.y |
[7:5] |
[4] |
8 |
2 |
0b101 |
xx.yy |
[7:6] |
[5:4] |
4 |
4 |
0b110 |
x.yyy |
[7] |
[6:4] |
2 |
8 |
0b111 |
yyyy |
none |
[7:4] |
1 |
16 |
最後一個NVIC的寄存器
軟件觸發中斷寄存器NVIC_STIR
當SCB_CCR的USERSETMPEND位爲1時,無特權的用戶程序才能寫此寄存器。
[31:9]保留。
[8:0] INTID ID號中斷觸發,
範圍0-239。例如,0x03的指定中斷IRQ3觸發。