技术交流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寄存器,也就是设置中断的模式,
中断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这个文件,这里面每个对应的按键都做了优先级的配置.
后面还会有专门的优先级实验.