KST-STM32学习之中断优先级与中断嵌套
1、NIVC
-
ARM Cortex-M3
内核搭载了一个强大而方便的中断系统,称之为NVIC
(嵌套向量中断控制器)。 -
Cortex-M3
支持256
个“中断通道”(16 个异常+240 个中断)以及对应的可编程 256 级中断优先级设置。 -
STM32
虽然采用Cortex-M3
内核,但是只使用了其中的84
个“中断通道”(16 个异常+68 个中断
)以及16 级
中断优先级设置。
同时也记录下自己当时的一个插曲。
这个
TIM6_IRQn
在《STM32固件库手册》
中查NVIC_IRQChannel
的取值是没有的,然后咨询下老师,如下回复
再拐回头看下教程,着实一不一样
看来要不看最新的手册,要不就是直接参考头文件才行!
2、优先级及中断嵌套
-
优先级分为
抢占优先级
和响应优先级
。 -
51所设置的优先级均属于抢占优先级,默认的便是响应优先级!
-
高抢占优先级可以嵌套低抢占优先级的中断。
-
两者抢占优先级相同,那么无论响应优先级是什么关系,这两者都没有嵌套关系。
当然不得不考虑以下极端情况:
若两个中断发生,抢占优先级相同,响应优先级不同,则根据响应优先级顺序执行(谁小谁先执行);
若两个中断发生,抢占优先级相同,响应优先级也相同,则根据中断清单表排位顺序执行(谁小谁先执行);
编程时需要注意:
首先要预先对程序的各个功能模块进行计算论证,开机初始化时一次性设置好优先级分组,以后就再也不动他了,避免同一个程序中使用多个优先级分组。
默认情况下,如何不设置中断优先级分组,则使用系统默认的优先级,即按照中断源清单的顺序执行。(没有抢占的概念,两者同时到来,谁的号小谁先执行!)。
具体的中断源清单可参考《STM32中文参考手册》9.1.2。
3、优先级分组
CM3内核中定义了8bit用于设置中断源的优先级,STM32F103只用到了其中的4个位,这4个位又被抢占优先级和响应优先级共同使用。而抢占优先级和响应优先级的级数是可以设置的,共分为5组,如下表所示。
怎么理解这五组呢?
这里我用**“阶级”和“阶层”**的概念进行类比抢占优先级和响应优先级。
阶级是大的分类,阶层是阶级里面的分类。
从这个概念上再来看,就不难理解了。
假如此时设置优先级分组为NVIC_PriorityGroup_4
,也就是说分成了16个阶级和0个阶层!高阶级的人可以打断低阶级正在做事的人(中断嵌套),而同一阶级内不能相互打断(这个例子没有阶层,一会有具体例子)对于这个分组而言可以完成1个中断和15级嵌套。
言语的描述可能还是会有点抽象,我们来看具体的例子。优先级分组为NVIC_PriorityGroup_4
,假如一个人叫TIM2_IRQn
我们设置它的阶级为0(即抢占优先级为0,0~15个等级可选择),另一个人叫TIM3_IRQn
我们设置它的优先级为1。按照前面所述高优先级可以打断低优先级,所以TIM2可打断TIM3!这便是嵌套的概念。
当然上面NVIC_PriorityGroup_4
的例子,只是涉及了抢占优先级,并没有响应优先级,现在我们来看看加入优先级分组设置为NVIC_PriorityGroup_3
会怎么样呢?按照前述的套路来分析分成了8个阶级和2个阶层!也就是说总共8个阶级,每个阶级又分两级称为阶层。还是举例来说吧,优先级分组设置为,此时有一个人叫TIM2_IRQn
,我们设置它的阶级为0(抢占优先级为0,可选0~7),阶层为0(响应优先级为0,可选0-1)。还有另外一个人叫TIM3_IRQn
,我们设置它的阶级为0,阶层为1。第三个人叫TIM4_IRQn
,阶级为1,阶层为0。
现有如下场景:TIM3_IRQn
已经发生了,然后TIM2_IRQn
发生了,两者阶级一样,阶层不一样,此时抢占优先级相同,不发生嵌套,等TIM3_IRQn
执行完方可再执行TIM2_IRQn
。
若TIM4_IRQn
发生了,然后TIM2_IRQn
发生了。两者阶级不同,阶层相同,即抢占优先级不同,且TIM2_IRQn
序号小,此时将打断TIM4_IRQn
执行,待执行完TIM2_IRQn
再回来执行TIM4_IRQn
。
其他三个分析也是一样的道理。。。
emmmm,可能用阶级和阶层的概念还是不太好理解,其实生活处处是例子,也可以类比我们火车站窗口买票,有普通,军人,学生窗口 - 等同与阶级(抢占优先级),而每个窗口排队顺序 - 等同阶层(响应优先级)。
大概就是这样吧,累、、、
最后再加一段配置NVIC的代码:TIM2分组为NVIC_PriorityGroup_3
,阶级为0,阶层为1。
...
NVIC_InitTypeDef NVIC_initstructure;
NVIC_initstructure.NVIC_IRQChannel = TIM2_IRQn; //选择TIM2中断通道
NVIC_initstructure.NVIC_IRQChannelCmd = ENABLE; //使能中断通道
NVIC_initstructure.NVIC_IRQChannelPreemptionPriority = 0; //设定抢占优先级为0
NVIC_initstructure.NVIC_IRQChannelSubPriority = 1; //设定响应优先级为1
NVIC_Init(&NVIC_initstructure);
...
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
小结
①、系统运行开始的时候设置中断分组。
确定组号,也就是确定抢占优先级和子优先级的分配位数。调用函数为 NVIC_PriorityGroupConfig();
②. 设置所用到的中断的中断优先级别。
对每个中断调用函数为 NVIC_Init();
文章来源: recclay.blog.csdn.net,作者:ReCclay,版权归原作者所有,如需转载,请联系作者。
原文链接:recclay.blog.csdn.net/article/details/81223849
- 点赞
- 收藏
- 关注作者
评论(0)