1. 程式人生 > >stm32學習——中斷的優先順序設定

stm32學習——中斷的優先順序設定

stm32的中斷具有不同的優先順序,可以使用NVIC(巢狀向量中斷控制器,Nested Vectored Interrupt Controller)來控制。
一、基本原理介紹
stm32的中斷優先順序分主副兩類(也稱為搶佔式優先順序和響應式優先順序),主優先順序是搶佔式的(為零表示最高),即,優先順序高的中斷到來時即使優先順序較低的中斷正在執行,也要停下來先執行優先順序較高的中斷。而輔優先順序是非搶佔式的,即,具有相同主優先順序的兩個中斷,如果輔優先順序較高的中斷到來,此時有副優先順序較低的中斷正在執行,要等這個中斷執行完了再執行後到來的這個中斷。
stm32使用4為暫存器來管理中斷優先順序,NVIC_PriorityGroup來設定中斷優先順序的分組方式的,有以下幾種:
NVIC_PriorityGroup_0 => 選擇第0組
NVIC_PriorityGroup_1 => 選擇第1組
NVIC_PriorityGroup_2 => 選擇第2組
NVIC_PriorityGroup_3 => 選擇第3組
NVIC_PriorityGroup_4 => 選擇第4組
他們分別表示:
第0組:所有4位用於指定響應優先順序(16種)
第1組:最高1位用於指定搶佔式優先順序,最低3位用於指定響應優先順序(8種)
第2組:最高2位用於指定搶佔式優先順序,最低2位用於指定響應優先順序(4種)
第3組:最高3位用於指定搶佔式優先順序,最低1位用於指定響應優先順序(2種)
第4組:所有4位用於指定搶佔式優先順序

比如選擇NVIC_PriorityGroup_1,那麼搶佔式優先順序便佔一位,也就是說可以有21個級別,可以設定為0和1,而響應優先順序則佔3位,也就是說可以有23個選擇,可以設定為0~7;總共來說就可以區別>16種優先順序了。

也就是說,stm32的每一箇中斷都需要設定他的主優先順序和副優先順序,(當然,在這之前首先要設定暫存器的分組方式)通過這兩個值將每一箇中斷放在中斷向量體系中的某一個位置,在實際執行過程中,就可以按照既定的規則響應中斷。

二、中斷優先順序的初始化過程
1、定義資料結構
NVIC_InitTypeDef NVIC_InitStructure; //定義資料結構
2、定義分組方式
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//這裡定義的分組方式是第二組,指定搶佔優先順序為兩位(可以設定0,1,2,3,4),響應優先順序為2位(可以設定0,1,2,3,4),(搶佔優先順序->響應優先順序->中斷向量表順序)
3、指定中斷
NVIC_InitStructure.NVIC_IRQChannel=TIM3_IRQn;//指定TIMER3中斷
4、設定主優先順序
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;//指定搶佔優先順序為2
5、設定副優先順序
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;//指定響應優先順序為0
6、使能中斷請求
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能中斷請求
7、用結構體初始化中斷向量暫存器
NVIC_Init(&NVIC_InitStructure); //根據賦的結構體對NVIC初始化

三、具體例子,這個例子初始化了三個中斷向量
void Nvic_Init(void)//中斷優先順序初始化
{
NVIC_InitTypeDef NVIC_InitStructure;

/* NVIC_PriorityGroup */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//指定搶佔優先順序為兩位,響應優先順序為2位,(搶佔優先順序->響應優先順序->中斷向量表順序)
NVIC_InitStructure.NVIC_IRQChannel=TIM3_IRQn;//指定TIMER3中斷
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;//指定搶佔優先順序為2
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;//指定響應優先順序為0
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能中斷請求
NVIC_Init(&NVIC_InitStructure);//根據賦的結構體對NVIC初始化

NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn; //指定TIMER4中斷
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //指定搶佔優先順序為0,0為最高優先順序
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //指定響應優先順序為0
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能中斷請求
NVIC_Init(&NVIC_InitStructure); //根據賦的結構體對NVIC初始化

/* Enable the USARTy Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;//指定串列埠3中斷
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;//指定搶佔優先順序為1
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;//指定響應優先順序為0
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能中斷請求
NVIC_Init(&NVIC_InitStructure);//根據賦的結構體對NVIC初始化
}