內嵌向量中斷控制器:Nested Vectored Interrupt Controller (NVIC)
設置中斷向量的優先級並使能。
響應優先級& 搶占優先級
搶占優先級:一個中斷A還在處理時,另一個中斷B發生,B能否先處理? 答:如果B搶占優先級高就行。
響應優先級:搶占優先級相同時,中斷A和中斷B同時發生時,先處理哪個? 答:響應優先級高的哪個。
而搶占優先級相同的中斷,高優先級的響應優先級不可以打斷低響應優先級的中斷。
中斷優先級組
是指在寄存器SCB->AIRCR中,配置:
4個位當中,幾位是搶占優先級,幾位是響應優先級

注意:設置好后不要再改了!以免造成混亂
相關庫函數
NVIC相關的庫函數在FWLIB的misc.c中
中斷優先級分組函數
(一般只調用一次!)
void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup);
例如:
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
中斷初始化函數
void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct)
其中 NVIC_InitTypeDef 是一個結構體,我們可以看看結構體的成員變量:
typedef struct
{
uint8_t NVIC_IRQChannel;
uint8_t NVIC_IRQChannelPreemptionPriority;
uint8_t NVIC_IRQChannelSubPriority;
FunctionalState NVIC_IRQChannelCmd;
} NVIC_InitTypeDef;
NVIC_InitTypeDef 結構體中間有三個成員變量,這三個成員變量的作用是:
NVIC_IRQChannel:定義初始化的是哪個中斷,這個我們可以在 stm32f4xx.h 中定義的枚舉類 型 IRQn
的成員變量中可以找到每個中斷對應的名字。例如串口 1 對應 USART1_IRQn。
NVIC_IRQChannelPreemptionPriority:定義這個中斷的搶占優先級別。
NVIC_IRQChannelSubPriority:定義這個中斷的響應優先級別。
NVIC_IRQChannelCmd:該中斷通道是否使能。
比如我們要使能串口 1 的中斷,同時設置搶占優先級為 1,響應優先級位 2,初始化的方法是:
NVIC_InitTypeDef NVIC_InitStructure;;
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;//串口 1 中斷
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1 ;// 搶占優先級為 1
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;// 響應優先級位 2
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ 通道使能
NVIC_Init(&NVIC_InitStructure); //根據上面指定的參數初始化 NVIC 寄存器
編程步驟
最簡單的應用中,只要
- 設置分組
- 外設中斷使能(函數名在外設的頭文件中有)
- 初始化
- 寫中斷服務函數(函數名在setup巴拉巴拉中定義)
即可:
//1.
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //可能在主函數
//2.
USART_ITConfig(USART1,USART_IT_RXNE,ENABLE); //可能在初始化函數中
//3.
NVIC_InitTypeDef NVIC_InitStructure; / /可能在初始化函數
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;//串口 1 中斷
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1 ;// 搶占優先級為 1
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;// 響應優先級位 2
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ 通道使能
NVIC_Init(&NVIC_InitStructure); //根據上面指定的參數初始化 NVIC 寄存器
//4.中斷服務函數
void USART1_IRQHandler(void)
{
}
上面是一些常用的東西,下面是其他一些有的沒的
支持的中斷數量
- CM4內核支持256個中斷,其中包含了16個內核中斷和240個外部中斷,並且具有256級的可編程中斷設置。
- STM32F4並沒有使用CM4內核的全部東西,而是只用了它的一部分。
STM32F40xx/STM32F41xx總共有92個中斷。
STM32F42xx/STM32F43xx則總共有96個中斷 - STM32F40xx/STM32F41xx的92個中斷里面,包括10個內核中斷和82個可屏蔽中斷,具有16級可編程的中斷優先級,而我們常用的就是這82個可屏蔽中斷。
中斷設置相關的寄存器
__IO uint8_t IP[240]; //中斷優先級控制的寄存器組
__IO uint32_t ISER[8]; //中斷使能寄存器組
__IO uint32_t ICER[8]; //中斷失能寄存器組
__IO uint32_t ISPR[8]; //中斷掛起寄存器組
__IO uint32_t ICPR[8]; //中斷解掛寄存器組
__IO uint32_t IABR[8]; //中斷激活標志位寄存器組
中斷優先級控制寄存器組:IP[240]
Interrupt Priority Registers
240個8位寄存器
void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct);
例如:NVIC_Init(&NVIC_InitStructure);
中斷使能寄存器組:ISER[8]
8個32位寄存器(CM4內核支持256個中斷)
每個位控制一個中斷的使能
STM32F40x只有82個可屏蔽中斷,所以只使用了其中的ISER[0]~ISER[2]。
ISER[0]的bit031分別對應中斷0-31
ISER[1]的bit0-27對應中斷32-63;
ISER[2]的bit0-17對應中斷64~81;
