STM32工作笔记0051---NVIC中断优先级管理

技术交流QQ群【JAVA,C++,Python,.NET,BigData,AI】:170933152

这里可以看到其实这个CM3内核支持256个中断,其中包含了16个内核中断和240个外部中断.

有256级的可编程中断设置.

但对于STM32F1系列,有84个中断,16个内核中断,68个可屏蔽中断(可屏蔽中断,就是外部中断.)

这里多少级,什么是可编程中断设置,什么是可屏蔽中断,后面会说.

上面说这个STM32103有60个可屏蔽中断,这个是文档中copy出来的.

可以看到,这里这个互联型号的这个我就是107,他有

68个可屏蔽中断.

对于F103可以看到他有60个可屏蔽中断.

看一些常用的中断

这里是串口的.

SPI的中断.

当然还有USB的等,这里还有

经常用的外部中断线的中断.

一共60个.

对于51单片机一共就几个中断,而F103这里有60个中断,那么对于这些中断STM32F103是怎么管理的呢

接下来说这个

首先有个中断优先级分组

这个是在AIRCR寄存器中配置的

这个是什么意思呢?

也就是说首先要给这60个中断进行分组,一共可以分成0到4组,这里就是通过这个AIRCR这个寄存器的

8到10这三个位来进行的分组.

而这个分组一般是在系统初始化的时候,就进行的,首先把这些中断分成4个组,然后

再去选择对应的一个组,比如系统初始化的时候,我们把AIRCR寄存器的8到10位

设置成了101,那么就相当于我们选择了2这个分组了.

这里设置了分组位101,第二组以后,对应的IP寄存器也相当于设置了.

注意IP寄存器是有4个位的 也就是 4 5 6 7,这个是这个位来设置的.

这里一个分组,也对应一个IP寄存器,这个101这个分组,对应的IP寄存器,就会用两位来设置抢占优先级,用2位

来设置响应优先级,其他的分组也是一样的,上图都说明了.

前面说

STM32F103有16个可编程优先级,为什么有16个呢.

是因为这里有4个位,可以设置优先级的情况,也就是2的4次方也就是16个可编程优先级.

这个分组的意思再说一下,其实就是,

系统初始化的时候,首先选择一个分组,然后就可以确定,系统使用的时候,优先级规则,是由几位抢占优先级

有几位响应优先级.

然后再看看,什么是抢占优先级,什么是响应优先级

可以看到这里,比如咱们设置的分组是2,然后因为对应的,IP寄存器,为2位可以设置抢占优先级

2位可以设置响应优先级

那么也就是说抢占优先级可以设置为0-3 

0011=3

假如这个时候有两个中断要执行,那么如果A的抢占优先级是0,注意抢占优先级越小,他的优先级就越高,

B的抢占优先级是1,那么,如果这个时候B的中断函数正在执行,那么如果这个时候A产生中断了,那么A的

中断会打断B的中断,转而去执行A的中断函数,A的中断函数执行完了以后再去执行B的中断函数.

这是因为A的抢占优先级高是0 ,B的抢占优先级低是1

注意如果抢占优先级不一样的时候,响应优先级是不起作用的,这就跟两种模式一样.

抢占优先级相同的情况下,响应优先级才有意义.

再看第二个,这里可以看到,当抢占优先级相同的时候,那么高响应优先级不可以打断低响应优先级,

举个例子,如果A,B这两个中断,A的抢占优先级是0 B的抢占优先级也是0,

A的响应优先级是0,B的响应优先级是1

那么这个时候,比如B正在执行中断函数,那么A的响应优先级虽然,比B的要高,因为A的是0,B的是1

这个时候,A也不能打断B执行中断函数.那么这个响应优先级有什么用呢.

接下来看第三个:

他的意思是这样的:

这个响应优先级,他不是定义谁可以打断谁的执行.

而是定义了,当A B两个中断同时发生的时候,哪个中断函数先执行,只是定义了,高响应优先级,会优先响应

再看最后一个:

如果,抢占优先级和响应优先级都一样的话,那么

就要看哪个中断先发生就会先执行哪个.

这里举个例子说明一下,

咱们说,首先设置中断优先级分组,然后设置IP寄存器,也就是设置中断的模式,

假定设置中断优先级组为 2 ,然后设置

中断3(RTC中断)的抢占优先级为2,响应优先级为1  中断6(外部中断0)的抢占优先级为3,响应优先级为0。中断7(外部中断1)的抢占优先级为2,响应优先级为0

整理一下:

中断3  2  1

中断6  3  0

中断7  2  0

可以看到中断7的优先级最大,然后是中断3,然后是中断6

因为中断7和中断3比的话,抢占优先级一样,但是响应优先级中断7的高,

所以中断7>中断3

然后中断3和中断6,先看抢占优先级,抢占优先级中断3,大于中断6 ,所以

中断3>中断6

所以优先级是中断7>中断3>中断6

也就是发生中断的时候,先去执行中断7,再去执行中断3 ,再去执行中断6,是这样的关系.

这里一般设置好中断分组后就不在动了,因为,比如原来设置的是分组是2,他对应的IP 优先级模式是,2位抢占优先级

2位响应优先级,如果变更了分组以后,可能中途,就变成了3位抢占优先级,1位响应优先级,到时候,程序执行结果可能

就乱了.

接下来,看一下中断优先级分组函数怎么用.

用这个函数设置分组,参数是哪个分组.

需要使用寄存器进行配置

打开跑马灯程序源码

可以看到这里有这个优先级分组函数.去看一下他的参数的定义.

可以看到从分组0到分组4

再看看中断优先级的寄存器是在哪个文件中定义的呢

可以看到再core_cm3.h中有定义,这几个寄存器

那么这几个寄存器.

每个寄存器是什么意思,咱们看看

这里,咱们知道因为对于STM32F1系列的芯片,并没有用到Conter-m3内核的所有的中断

所以这里标注蓝色部分的寄存器是没有用到的.

来看红色部分的..

注意这里,用来控制优先级的寄存器IP寄存器,一共有240个,因为,咱们知道conterx-m3有240个中断可以设置,

STM32F103系列,只有60个可屏蔽中断这里只用到了IP59--IP0

这些寄存器是8位的.

高4位用来设置抢占和响应优先级低4位没有用到.

咱们看看这个函数

可以看到里面有个结构体,去看一下.

可以看到,第一个是通道,第二个是抢占优先级,第三个是响应优先级,第四个是是否使能这个优先级通道.

一会再看这个函数如何使用,先继续看

再看一个寄存器,这个寄存器,用来使能一个中断,这个寄存器是ISER[8],一共有8个这样的寄存器,每个寄存器有32位,

因为Conterx-m3支持的比较多前面有说好像是240个外部中断,这里STM32F103系列,支持60个可屏蔽中断,也就是

只用到了两个ISER寄存器,也就是ISER0和ISER1.

这个也是通过NVIC_INIT函数配置的.

看一下代码,实际上,下面的这个NVIC_IRQChannelCmd这个就是使能用的,把这个设置为

ENABLE,那么对应的通道,也就是对应的中断,也就是上面的NVIC_IRQChannel就被使能了.

当然有使能,还有失能,失能也是在这个函数里面设置的

还有就是挂起和解挂用的寄存器,也就是挂起中断,和解挂中断.

ISPR和ICPR这个跟上面的一样用的,对应的函数也有

这些函数实际上也是有的.

可以看到这些函数都有,这些函数实验中用的不多.

这个函数也是这样的,用来激活中断的.

主要去看一下下面这个初始化函数如何用:

可以看到,需要自己去定义这个结构体.

可以看到

NVIC_InitTypeDef   NVIC_InitStructure;

NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;//串口1中断  //这里要选择一个中断,咱们说STM32F103有60个外部中断

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1 ;// 抢占优先级为1//然后设置抢占优先级

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;// 子优先级位2//再设置响应优先级

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//IRQ通道使能 //再使能对应的中断

NVIC_Init(&NVIC_InitStructure);  //根据上面指定的参数初始化NVIC寄存器 

再总结一下中断优先级的使用步骤

然后再看一下代码我们是如何使用的

可以看到这里,首先设置NVIC中断分组为2

然后有个EXTI.C这个文件,这里面每个对应的按键都做了优先级的配置.

后面还会有专门的优先级实验.

 

 

 

 

 

 

 

猜你喜欢

转载自blog.csdn.net/lidew521/article/details/108184970