您的位置:首页 > 其它

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

2017-09-02 23:20 871 查看
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,那么抢占式优先级便占一位,也就是说可以有2^1个级别,可以设置为0和1,而响应优先级则占3位,也就是说可以有2^3个选择,可以设置为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初始化

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  stm32