关于STM32 (Cortex-M3) 中NVIC的分析

发布时间:2022-12-26  

  一、STM32 (Cortex-M3) 中的优先级概念


  STM32(Cortex-M3)中有两个优先级的概念:抢占式优先级和响应优先级,也把响应优先级称作“亚优先级”或“副优先级”,每个中断源都需要被指定这两种优先级。


  1. 何为占先式优先级(pre-emption priority)


  高占先式优先级的中断事件会打断当前的主程序/中断程序运行—抢断式优先响应,俗称中断嵌套。


  2. 何为副优先级(subpriority)


  在占先式优先级相同的情况下,高副优先级的中断优先被响应;


  在占先式优先级相同的情况下,如果有低副优先级中断正在执行, 高副优先级的中断要等待已被响应的低副优先级中断执行结束后才能得到响应—非抢断式响应(不能嵌套)。


  3. 判断中断是否会被响应的依据


  首先是占先式优先级,其次是副优先级;


  占先式优先级决定是否会有中断嵌套;


  Reset、NMI、Hard Fault 优先级为负(高于普通中断优先级)且不可调整。


  4. 优先级冲突的处理


  具有高抢占式优先级的中断可以在具有低抢占式优先级的中断处理过程中被响应,即中断的嵌套,或者说高抢占式优先级的中断可以嵌套低抢占式优先级的中断。


  当两个中断源的抢占式优先级相同时,这两个中断将没有嵌套关系,当一个中断到来后,如果正在处理另一个中断,这个后到来的中断就要等到前一个中断处理完之后才能被处理。如果这两个中断同时到达,则中断控制器根据他们的响应优先级高低来决定先处理哪一个;如果他们的抢占式优先级和响应优先级都相等,则根据他们在中断表中的排位顺序决定先处理哪一个。


  5. Cortex-M3中对中断优先级的定义


  既然每个中断源都需要被指定这两种优先级,就需要有相应的寄存器位记录每个中断的优先级;在Cortex-M3中定义了8个比特位用于设置中断源的优先级,这8个比特位可以有8种分配方式,如下:


  所有8位用于指定响应优先级


  最高1位用于指定抢占式优先级,最低7位用于指定响应优先级


  最高2位用于指定抢占式优先级,最低6位用于指定响应优先级


  最高3位用于指定抢占式优先级,最低5位用于指定响应优先级


  最高4位用于指定抢占式优先级,最低4位用于指定响应优先级


  最高5位用于指定抢占式优先级,最低3位用于指定响应优先级


  最高6位用于指定抢占式优先级,最低2位用于指定响应优先级


  最高7位用于指定抢占式优先级,最低1位用于指定响应优先级


  这就是优先级分组的概念。


  6. STM32中对中断优先级的定义


  Cortex-M3允许具有较少中断源时使用较少的寄存器位指定中断源的优先级,因此STM32把指定中断优先级的寄存器位减少到4位,这4个寄存器位的分组方式如下:


  第0组:所有4位用于指定响应优先级


  第1组:最高1位用于指定抢占式优先级,最低3位用于指定响应优先级


  第2组:最高2位用于指定抢占式优先级,最低2位用于指定响应优先级


  第3组:最高3位用于指定抢占式优先级,最低1位用于指定响应优先级


  第4组:所有4位用于指定抢占式优先级

  AIRC(Application Interrupt and Reset Register)寄存器中有用于指定优先级的 4 bits。这4个bits用于分配preemption优先级和sub优先级,在STM32的固件库中定义如下:


  /* Preemption Priority Group */

  #define NVIC_PriorityGroup_0 ((u32)0x700) /* 0 bits for pre-emption  priority

  4 bits for subpriority */

  #define NVIC_PriorityGroup_1 ((u32)0x600) /* 1 bits for pre-emption  priority

  3 bits for subpriority */

  #define NVIC_PriorityGroup_2 ((u32)0x500) /* 2 bits for pre-emption  priority

  2 bits for subpriority */

  #define NVIC_PriorityGroup_3 ((u32)0x400) /* 3 bits for pre-emption  priority

  1 bits for subpriority */

  #define NVIC_PriorityGroup_4 ((u32)0x300) /* 4 bits for pre-emption  priority

  0 bits for subpriority */

  可以通过调用STM32的固件库中的函数NVIC_PriorityGroupConfig()选择使用哪种优先级分组方式,这个函数的参数有下列5种:


  NVIC_PriorityGroup_0 => 选择第0组

  NVIC_PriorityGroup_1 => 选择第1组

  NVIC_PriorityGroup_2 => 选择第2组

  NVIC_PriorityGroup_3 => 选择第3组

  NVIC_PriorityGroup_4 => 选择第4组

  接下来就是指定中断源的优先级,下面以一个简单的例子说明如何指定中断源的抢占式优先级和响应优先级:


  // 选择使用优先级分组第1组

  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);

  // 使能EXTI0中断

  NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQChannel;

  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; // 指定抢占式优先级别1

  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // 指定响应优先级别0

  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

  NVIC_Init(&NVIC_InitStructure);

  // 使能EXTI9_5中断

  NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQChannel;

  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; // 指定抢占式优先级别0

  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; // 指定响应优先级别1

  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

  NVIC_Init(&NVIC_InitStructure);

  要注意的几点是:


  1. 如果指定的抢占式优先级别或响应优先级别超出了选定的优先级分组所限定的范围,将可能得到意想不到的结果;


  2. 抢占式优先级别相同的中断源之间没有嵌套关系;


  3. 如果某个中断源被指定为某个抢占式优先级别,又没有其它中断源处于同一个抢占式优先级别,则可以为这个中断源指定任意有效的响应优先级别。


  二、开关总中断


  在STM32/Cortex-M3中是通过改变CPU的当前优先级来允许或禁止中断。


  PRIMASK位:只允许NMI和hard fault异常,其他中断/异常都被屏蔽(当前CPU优先级=0)。


  FAULTMASK位:只允许NMI,其他所有中断/异常都被屏蔽(当前CPU优先级=-1)。


  在STM32固件库中(stm32f10x_nvic.c和stm32f10x_nvic.h) 定义了四个函数操作PRIMASK位和FAULTMASK位,改变CPU的当前优先级,从而达到控制所有中断的目的。


  下面两个函数等效于关闭总中断:


  void NVIC_SETPRIMASK(void);

  void NVIC_SETFAULTMASK(void);

  下面两个函数等效于开放总中断:


  void NVIC_RESETPRIMASK(void);

  void NVIC_RESETFAULTMASK(void);

  上面两组函数要成对使用,但不能交叉使用。


  例如:


  第一种方法:


  NVIC_SETPRIMASK(); //关闭总中断

  NVIC_RESETPRIMASK();//开放总中断

  第二种方法:


  NVIC_SETFAULTMASK(); //关闭总中断

  NVIC_RESETFAULTMASK();//开放总中断

  常常使用:


  NVIC_SETPRIMASK(); // Disable Interrupts

  NVIC_RESETPRIMASK(); // Enable Interrupts

  补充:


  可以用:


  #define CLI() __set_PRIMASK(1)

  #define SEI() __set_PRIMASK(0)

  来实现开关总中断的功能。


文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

相关文章

    大概为370 uA,STM32H745在SMPS供电方式下,功耗为60 uA,如果使用STM32H7A3,功耗可达32 uA。 性价比之王:STM32H723/H733STM32H725/H735......
    uA,STM32H745在SMPS供电方式下,功耗为60 uA,如果使用STM32H7A3,功耗可达32 uA。 性价比之王:STM32H723/H733STM32H725/H735......
    上年同期5.9个百分点。其中,新能源商用车产销分别占商用车产销11.5%11.1%;新能源乘用车产销分别占乘用车销的34.9%34.7%。 中国新能源汽车保有量达2041万辆,新注册登记743万辆......
    充电基础设施总量达到992万台,同比大幅增长56%。 其中,公共充电设施为305万台,私人充电设施为687万台,分别增长46%61%。 为进一步提升充电网络的覆盖和服务质量,有关......
    覆盖设计及软件服务、原材料、精密部件、自动化制造设备、超精加工技术、合同制造、测试和认证、政策法规和市场咨询服务等21大品类,参观观众预计超80,000+人次。目前已经有超过743家企业和品牌确认参展,国际......
    领衔的顺为资本和及其生态链企业乘着智能硬件创业东风,开发出了品类繁多的智能硬件新品,为小米的高估值立下了汗马功劳。 在小米获得高估值的那一年,手机售出了6112万台,同比增长227%,含税销售额743亿元,同比增长135%。 但到......
    西门子1200与300的九大区别;一、硬件的区别 在硬件扩展方面,S7-300的主机架多支持八个扩展模块,而S7-1200支持扩展多八个信号模块和多三个通信模块。以S7-300 CPU313CS7......
    hc32stm32的区别;HC32STM32是两个不同的单片机系列。HC32是华大基础电子有限公司(Holtek)生产的单片机,而STM32是意法半导体(STMicroelectronics......
    ch32v307stm32的区别;ch32v307stm32的区别Ch32v307与STM32是两款不同的微控制器,它们在设计和功能上都存在一些区别。首先,Ch32v307是一......
    arm920t中S3C2440、S3C2450S3C6410的区别;  三星目前推出了S3C6400S3C6410,都是基于ARM架构的,而且硬件管脚兼容,应该说大致的功能基本相同,比较明显的区别......

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>