单片机
返回首页

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

2021-09-15 来源:eefocus

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);

    

...


小结

①、系统运行开始的时候设置中断分组。

确定组号,也就是确定抢占优先级和子优先级的分配位数。调用函数为 NVIC_PriorityGroupConfig();


②. 设置所用到的中断的中断优先级别。

对每个中断调用函数为 NVIC_Init();

进入单片机查看更多内容>>
相关视频
  • TI 新一代 C2000™ 微控制器:全方位助力伺服及马达驱动应用

  • MSP430电容触摸技术 - 防水Demo演示

  • 直播回放: Microchip Timberwolf™ 音频处理器在线研讨会

  • 新唐 8051单片机教程

  • 基于灵动MM32W0系列MCU的指夹血氧仪控制及OTA升级应用方案分享

  • 基于灵动MM32SPIN系列MCU的无感FOC便携冰箱应用方案分享

    相关电子头条文章