1.1優先級分組
首先,我們先通過標識來解釋手冊里NVIC向量表的含義:
Core-M4內核最多支持256級的可編程優先級。用8位來表示優先級級別,,優先級級別分為8組,分別是組0~組7,如表1.0所示 (8位范圍:0~255)
表1.1 中斷分組講解
組號 | 搶占優先級 | 響應優先級 |
0 | 用高七位表示搶占優先級 0~127 如果CPU的中斷分組選擇為“組 0”,則 搶占優先級可以設置為0~127,注意:數字越小,級別越高。 |
最低表示響應優先級 0~1 響應優先級可以設置為0或者1,注意:數字越小級別越高。 |
1 | 用高六位表示搶占優先級 如果CPU的中斷分組選擇為“組 1”, 搶占優先級可以設置為0~63 |
低兩位表示響應優先級 響應優先級可以設置為0~3 |
2 | 用高5位表示搶占優先級 如果CPU的中斷分組選擇為“組 2”, 搶占優先級可以設置為0~31 |
低三位表示響應優先級 響應優先級可以設置為0~7 |
3 | 用高4位表示搶占優先級 如果CPU的中斷分組選擇為“組 2”, 搶占優先級可以設置為0~15 |
低四位表示響應優先級 響應優先級可以設置為0~15 |
4 | 用高3位表示搶占優先級 如果CPU的中斷分組選擇為“組 2”, 搶占優先級可以設置為0~7 |
低五位表示響應優先級 響應優先級可以設置為0~31 |
5 | 用高2位表示搶占優先級 如果CPU的中斷分組選擇為“組 2”, 搶占優先級可以設置為0~3 |
低6位表示響應優先級 響應優先級可以設置為0~63 |
6 | 最高位表示搶占優先級 如果CPU的中斷分組選擇為“組 2”, 搶占優先級可以設置為0~1 |
低7位表示響應優先級 響應優先級可以設置為0~127 |
7 | 8位表示響應優先級 響應優先級可以設置為0~255 |
如果用圖來形象表示,則看圖1.1-8位中斷分組 :
1.1 8位中斷分組
stm32為了節省材料成本,並沒有完全使用這8位,它忽略低4位。如下圖1-2
1.2 高位分組
表1.2 裁剪分組講解
組號 | 中斷優先級分組說明 | 搶占優先級等級范圍 | 響應優先級等級范圍 |
3 | 所有4位用於指定搶占優先級 | 0~15 | 不可設置 |
4 | 最高3位用於指定搶占優先級,最低1位用於指定響應優先級 | 0~7 | 0~1 |
5 | 最高2位用於指定搶占優先級,最低2位用於指定響應優先級 | 0~3 | 0~3 |
6 | 最高1位用於指定搶占優先級,低3位用於指定響應優先級 | 0~1 | 0~7 |
7 | 所有4位用於指定響應優先級 | 不可設置 | 0~15 |
1.2 NVIC中斷中斷控制器相關函數
NVIC分組設置
void NVIC_SetPriorityGrouping(uint32_t PriorityGroup)
位置:core_cm4.h的1453行
作用:設置優先級分組。
參數:PriorityGroup優先級分組組號
舉例:STM32的優先級分組設置為組5,則對應的代碼如下:NVIC_SetPriorityGrouping(5);
NVIC具體中斷優先級編碼
uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority)
作用:設置搶占優先級和響應優先級的級別
位置:core_cm4.h的1610行
參數:PriorityGroup優先級分組組號;PreemptPriority:搶占優先級;SubPriority:響應優先級
返回值:32位的編碼值,編碼值用於中斷優先級設置
舉例:優先級分組選擇為組5,搶占優先級為2,響應優先級為2,代碼如下:
u32 prio;
prio = NVIC_EncodePriority(5,2,2);
NVIC中斷優先級設置
void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
作用:將優先級分組情況以及搶占優先級和響應優先級設置到響應的中斷。
參數:
IRQn :中斷通道編號。
priority:是NVIC_EncodePriority函數的返回值
舉例:設置串口1全局中斷的優先級分組選擇為組5,搶占優先級為2,響應優先級為3
對應的代碼:
u32 prio;
prio = NVIC_EncodePriority(5,2,3);
NVIC_SetPriority(37,prio);
也可以寫成NVIC_SetPriority(USART1_IRQn,prio);
NVIC中斷使能
void NVIC_EnableIRQ(IRQn_Type IRQn)
作用:使能中斷通道
參數:IRQn :中斷通道編號。
舉例:使能串口1全局中斷,NVIC_EnableIRQ(37); 可以寫成NVIC_EnableIRQ(USART1_IRQn);
NVIC中斷禁能
void NVIC_DisableIRQ(IRQn_Type IRQn)
作用:禁止中斷通道。
參數:IRQn :中斷通道編號。
舉例:禁止串口1全局中斷,NVIC_DisableIRQ(37);
1.3 實例代碼之串口中斷:

#include "stm32f4xx.h" //PA9 ----TXD--發送數據 (站在芯片角度) //PA10 --- RXD--接收收據 (站在芯片角度) void Usart1_Init(u32 baudRate) { u32 prio; float USARTDIV; u16 Mantissa; //整數 u8 Fraction; //小數 /****使能GPIOA的時鍾***/ RCC->AHB1ENR |= 1<<0; /****配置PA10為復用功能+上拉***/ GPIOA->MODER |= 2<<20;//復用功能 GPIOA->PUPDR |= 1<<20;//上拉 /****配置PA9位復用功能+推挽***/ GPIOA->MODER |= 2<<18;//復用功能 GPIOA->OTYPER &=~(1<<9);//推挽 /****PA9選擇復用功能7,TXD***/ GPIOA->AFR[1] |= 7<<4 ; /****PA10選擇復用功能7,RXD***/ GPIOA->AFR[1] |= 7<<8 ; /****使能串口1的時鍾***/ RCC->APB2ENR |= 1<<4; /****設置數據幀格式***/ USART1->CR1 |= 1<<15;//OVER8設置為1 USART1->CR1 &=~(1<<12);//將串口1的數據幀設置為“1 起始位, 8 數據位, n 停止位 ” USART1->CR2 &=~(3<<12);//1位停止位 USART1->CR1 &=~(1<<10);//禁止奇偶校驗 /****設置波特率***/ //USARTDIV = fCK/8*(2- OVER8 )/TxRx 波特率 USARTDIV = (float)84000000/8/baudRate; Mantissa = (int)USARTDIV; Fraction = (u8)((USARTDIV-Mantissa)*16); USART1->BRR = Mantissa<<4 | Fraction; USART1->CR1 |= 1<<5; //使能串口接收中斷 NVIC_SetPriorityGrouping(5); //設置優先級分組設置為組5,注意:一個工程只能有一個分組 prio = NVIC_EncodePriority(5,2,2); //組5,搶占優先級為2,響應優先級為2 NVIC_SetPriority(USART1_IRQn,prio); NVIC_EnableIRQ(USART1_IRQn); //使能串口1中斷通道USART1_IRQn==37 也可以用37表示串口1的通道編號 USART1->CR1 |= 1<<3;//使能發送器 USART1->CR1 |= 1<<2;//使能接收器 USART1->CR1 |= 1<<13;//使能串口1 } //中斷服務程序代碼,在接收到一個字節是會進入串口中斷服務函數 void USART1_IRQHandler(void) { u8 data; if(USART1->SR&(1<<5)) { data = USART1->DR; /*******接收到一個字節原樣回發*******/ USART1->DR = data; while(!(USART1->SR&(1<<6))); USART1->SR &=~(1<<6); //清零 } }
注意:優先級的執行先后問題可參考本人之前記錄:
https://www.cnblogs.com/anSn/p/11620920.html