KST-STM32学习之中断优先级与中断嵌套

举报
ReCclay 发表于 2022/02/21 23:52:22 2022/02/21
【摘要】 1、NIVC ARM Cortex-M3 内核搭载了一个强大而方便的中断系统,称之为 NVIC(嵌套向量中断控制器)。 Cortex-M3 支持 256 个“中断通道”(16 个异常+240 个中断...

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

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。