stm32学习——中断的优先级设置

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wgj99991111/article/details/77806338

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初始化
}

猜你喜欢

转载自blog.csdn.net/wgj99991111/article/details/77806338