当前位置: 首页 > news >正文

【STM32学习笔记】NVIC中断优先级管理

一.描述

什么是中断,我们可以理解为你正在打游戏,这个时候有人在敲门,你放下游戏去开门,开完门后你接着打游戏。那么开门这个事件就代表中断,接着打游戏就代表你完成中断事件接着运行主函数。

1.中断的类型

CM3内核支持256个中断,其中包含了16个内核中断和240个外部中断,并且具有256级的可编程中断设置。
STM32F10系列并没有使用CM3内核的全部东西,而是只用了它的一部分。
STM32F10系列有84个中断,包括16个内核中断和68个可屏蔽中断,具有16级可编程的中断优先级。
STM32F103系列上面,又只有60个可屏蔽中断(在107系列才有68个)。

这就是那60个外部中断的一部分,详细可以查看stm32中文参考手册9.1.2

2.中断优先级分组

 该分组的设置是由 SCB->AIRCR 寄存器的 bit10~8 来定义的。

AIRCR[108]

IP bit[74]分配情况

分配结果

0

111

04

0位抢占优先级,4位响应优先级

1

110

13

1位抢占优先级,3位响应优先级

2

101

22

2位抢占优先级,2位响应优先级

3

100

31

3位抢占优先级,1位响应优先级

4

011

40

4位抢占优先级,0位响应优先级

 

通过赋予SCB->AIRCR寄存器中第8位到第10位的值将这些中断类型分为5个组。
不同的分组中,AIRCR寄存器中的第4位到第8位管理优先级的情况不同。
比如常用的第2组,这4位中两位是管理抢占优先级的,两位是管理响应优先级的。按照从左到右的顺序。 

3.抢占优先级和响应优先级是什么 

抢占优先级:抢占优先级是指中断的打断优先级,抢占优先级高的中断可以打断正在执行的抢占优先级低的中断。

响应优先级:响应优先级是指中断的响应顺序,响应优先级只有在抢占优先级相同的情况下才有意义。当抢占优先级相同时,俩个中断同时发生,响应优先级高的中断先响应。

打个比方抢占优先级高的就可以直接把正在买饭的人丢到后面去,而响应优先级高的能插队到正在买饭人的后面,等他买完饭就可以执行。 

高优先级的抢占优先级是可以打断正在进行的低抢占优先级中断的。

抢占优先级相同的中断,高响应优先级不可以打断低响应优先级的中断。

抢占优先级相同的中断,当两个中断同时发生的情况下,哪个响应优先级高,哪个先执行。 如果两个中断的抢占优先级和响应优先级都是一样的话,则看哪个中断先发生就先执行; 

注意:俩个优先级中,数字越小表示的优先级越高。

4.中断优先级分组函数 

ST官方提供了设置分组的库函数,不用我们自己去挨个设置寄存器的值。

void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup)
{
  /* Check the parameters */
  assert_param(IS_NVIC_PRIORITY_GROUP(NVIC_PriorityGroup));
  
  /* Set the PRIGROUP[10:8] bits according to NVIC_PriorityGroup value */
  SCB->AIRCR = AIRCR_VECTKEY_MASK | NVIC_PriorityGroup;
}

这是那5个组的宏定义

#define NVIC_PriorityGroup_0         ((uint32_t)0x700) /*!< 0 bits for pre-emption priority
                                                            4 bits for subpriority */
#define NVIC_PriorityGroup_1         ((uint32_t)0x600) /*!< 1 bits for pre-emption priority
                                                            3 bits for subpriority */
#define NVIC_PriorityGroup_2         ((uint32_t)0x500) /*!< 2 bits for pre-emption priority
                                                            2 bits for subpriority */
#define NVIC_PriorityGroup_3         ((uint32_t)0x400) /*!< 3 bits for pre-emption priority
                                                            1 bits for subpriority */
#define NVIC_PriorityGroup_4         ((uint32_t)0x300) /*!< 4 bits for pre-emption priority
                                                            0 bits for subpriority */

配置的时候可以选择其中一个

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_3);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);

在ST官方的固件库的core_cm3.h中有几个库函数 

static __INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn);
static __INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn);
static __INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn); 

分别的作用是挂起某中断,读某中断状态,解除挂起的某中断。 

 5.中断优先级初始化函数

这是需要设置的成员变量

ypedef struct
{
  uint8_t NVIC_IRQChannel; //设置中断通道
  uint8_t NVIC_IRQChannelPreemptionPriority;//设置抢占优先级
  uint8_t NVIC_IRQChannelSubPriority; //设置响应优先级
  FunctionalState NVIC_IRQChannelCmd; //使能/使能
} NVIC_InitTypeDef;

 这样就完成了初始化的配置

总结

在使用中断的时候

系统运行后先设置中断优先级分组。
调用函数:void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup);整个系统执行过程中,只设置一次中断分组。

针对每个中断,设置对应的抢占优先级和响应优先级。
调用函数:void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct);如果需要挂起/解挂,查看中断当前激活状态,分别调用相关函数即可。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • STM32是使用的内部时钟还是外部时钟
  • ArchLinux部署waydroid
  • leetcode-148. 排序链表
  • 系统架构师考点--系统架构设计(下)
  • 【Vue3】watchEffect
  • 基于Netty服务端快速了解核心组件
  • PHP师生荣誉管理系统—计算机毕业设计源码10079
  • RuntimeError: No CUDA GPUs are available
  • 【Redis 初阶】初识 Redis
  • 设计模式7原则
  • linux练习2
  • magento2 安装win环境和linux环境
  • Hive之扩展函数(UDF)
  • 【设计模式】工厂模式详解
  • 宝塔安装mysql5.7无法通过远程连接
  • 【技术性】Search知识
  • 【跃迁之路】【585天】程序员高效学习方法论探索系列(实验阶段342-2018.09.13)...
  • Angularjs之国际化
  • axios 和 cookie 的那些事
  • crontab执行失败的多种原因
  • Invalidate和postInvalidate的区别
  • k个最大的数及变种小结
  • ng6--错误信息小结(持续更新)
  • scala基础语法(二)
  • Solarized Scheme
  • windows下mongoDB的环境配置
  • 安装python包到指定虚拟环境
  • 个人博客开发系列:评论功能之GitHub账号OAuth授权
  • 简单实现一个textarea自适应高度
  • 时间复杂度与空间复杂度分析
  • 适配mpvue平台的的微信小程序日历组件mpvue-calendar
  • 体验javascript之美-第五课 匿名函数自执行和闭包是一回事儿吗?
  • 与 ConTeXt MkIV 官方文档的接驳
  • 阿里云ACE认证学习知识点梳理
  • ​​​​​​​ubuntu16.04 fastreid训练过程
  • ​草莓熊python turtle绘图代码(玫瑰花版)附源代码
  • ​软考-高级-系统架构设计师教程(清华第2版)【第9章 软件可靠性基础知识(P320~344)-思维导图】​
  • ​探讨元宇宙和VR虚拟现实之间的区别​
  • # centos7下FFmpeg环境部署记录
  • (09)Hive——CTE 公共表达式
  • (19)夹钳(用于送货)
  • (6) 深入探索Python-Pandas库的核心数据结构:DataFrame全面解析
  • (8)STL算法之替换
  • (第三期)书生大模型实战营——InternVL(冷笑话大师)部署微调实践
  • (转)Groupon前传:从10个月的失败作品修改,1个月找到成功
  • (转)JVM内存分配 -Xms128m -Xmx512m -XX:PermSize=128m -XX:MaxPermSize=512m
  • (转)ORM
  • . ./ bash dash source 这五种执行shell脚本方式 区别
  • .net core Redis 使用有序集合实现延迟队列
  • .NET Core 成都线下面基会拉开序幕
  • .NET Framework 的 bug?try-catch-when 中如果 when 语句抛出异常,程序将彻底崩溃
  • .net 反编译_.net反编译的相关问题
  • .NET 分布式技术比较
  • .NET/C# 避免调试器不小心提前计算本应延迟计算的值
  • .Net的C#语言取月份数值对应的MonthName值