你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】STM32 NVIC中断优先级管理

[复制链接]
STMCU小助手 发布时间:2022-5-9 19:00
前言
使用中断前,需了解中断优先级管理,
CM3 内核支持 256 个中断,其中包含了 16 个内核中断和 240 个外部中断,并且具有 256
级的可编程中断设置。但 STM32 并没有使用 CM3 内核的全部东西,而是只用了它的一部分。
STM32 有 84 个中断,包括 16 个内核中断和 68 个可屏蔽中断,具有 16 级可编程的中断优先级。
而我们常用的就是这 68 个可屏蔽中断,但是 STM32 的 68 个可屏蔽中断,在 STM32F103 系列
上面,又只有 60 个(在 107 系列才有 68 个)。因为我们开发板选择的芯片是 STM32F103 系列
的所以我们就只针对 STM32F103 系列这 60 个可屏蔽中断进行介绍。

一、STM32 NVIC 中断优先级管理
在 MDK 内,与 NVIC 相关的寄存器,MDK 为其定义了如下的结构体:

  1. typedef struct
  2. {
  3. __IO uint32_t ISER[8]; /*!< Interrupt Set Enable Register /
  4. uint32_t RESERVED0[24];
  5. __IO uint32_t ICER[8]; /!< Interrupt Clear Enable Register /
  6. uint32_t RSERVED1[24];
  7. __IO uint32_t ISPR[8]; /!< Interrupt Set Pending Register /
  8. uint32_t RESERVED2[24];
  9. __IO uint32_t ICPR[8]; /!< Interrupt Clear Pending Register /
  10. uint32_t RESERVED3[24];
  11. __IO uint32_t IABR[8]; /!< Interrupt Active bit Register /
  12. uint32_t RESERVED4[56];
  13. __IO uint8_t IP[240]; /!< Interrupt Priority Register, 8Bit wide /
  14. uint32_t RESERVED5[644];
  15. __O uint32_t STIR; /!< Software Trigger Interrupt Register */
  16. } NVIC_Type;
复制代码

ISER[8]: 中断使能寄存器组,使能某个中断,必须设置相应的 ISER 位为 1,使该中断被使能,配合中断分组、屏蔽、IO 口映射等设置。
ICER[8]: 中断除能寄存器组,用来清除某个中断的使能。
ISPR[8]: 中断挂起控制寄存器组,通过置 1,可以将正在进行的中断挂起,而执行同级或更高级别的中断。写 0 是无效的。
ICPR[8]: 中断解挂控制寄存器组,通过设置 1,可以将挂起的中断接挂。写 0 无效。
IABR[8]: 中断激活标志位寄存器组
IP[240]: 中断优先级控制的寄存器组,由 240 个 8bit 的寄存器组成,每个可屏蔽中断占用 8bit,240 个可屏蔽中断。只用了高 4 位,这 4 位,又分为抢占优先级和子优先级。抢占优先级在前,子优先级在后。而这两个优先级各占几个位又要根据 SCB->AIRCR 中的中断分组设置来决定。

二、STM32 的中断分组
STM32 将中断分为 5 个组,组 0~4。该分组的设置是由 SCB->AIRCR 寄存器的 bit10~8 来定义的。
@LL}[U520I)BX@M1XM7(RFR.png

每个中断,你可以设置抢占优先级为 0~7,响应优先级为 1 或 0。抢占优先级的级别高于响应优先级。而数值越小所代表的优先级就越高。

这里需要注意两点:第一,如果两个中断的抢占优先级和响应优先级都是一样的话,则看哪个中断先发生就先执行;第二,高优先级的抢占优先级是可以打断正在进行的低抢占优先级中断的。而抢占优先级相同的中断,高优先级的响应优先级不可以打断低响应优先级的中断。

中断优先级分组函数 NVIC_PriorityGroupConfig

void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup);

这个函数的作用是对中断的优先级进行分组,这个函数在系统中只能被调用一次,一旦分
组确定就最好不要更改。

  1. void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup)
  2. {
  3. assert_param(IS_NVIC_PRIORITY_GROUP(NVIC_PriorityGroup));
  4. SCB->AIRCR = AIRCR_VECTKEY_MASK | NVIC_PriorityGroup;
  5. }

  6. #define IS_NVIC_PRIORITY_GROUP(GROUP)
  7. (((GROUP) == NVIC_PriorityGroup_0) ||
  8. ((GROUP) == NVIC_PriorityGroup_1) ||
  9. ((GROUP) == NVIC_PriorityGroup_2) ||
  10. ((GROUP) == NVIC_PriorityGroup_3) ||
  11. ((GROUP) == NVIC_PriorityGroup_4))
复制代码

分组范围为 0-4

中断初始化函数 NVIC_Init

  1. void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct)
复制代码

NVIC_InitTypeDef 是一个结构体

  1. typedef struct
  2. {
  3. uint8_t NVIC_IRQChannel;
  4. uint8_t NVIC_IRQChannelPreemptionPriority;
  5. uint8_t NVIC_IRQChannelSubPriority;
  6. FunctionalState NVIC_IRQChannelCmd;
  7. } NVIC_InitTypeDef;
复制代码

NVIC_InitTypeDef 结构体中间有三个成员变量,这三个成员变量的作用是:
NVIC_IRQChannel:定义初始化的是哪个中断,这个我们可以在 stm32f10x.h 中找到每个中断对应的名字。
例如 USART1_IRQn。
NVIC_IRQChannelPreemptionPriority:定义这个中断的抢占优先级别。
NVIC_IRQChannelSubPriority:定义这个中断的子优先级别。
NVIC_IRQChannelCmd:该中断是否使能。

中断优先级设置的步骤:


系统运行开始的时候设置中断分组。确定组号,也就是确定抢占优先级和子优先级的
分配位数。调用函数为 NVIC_PriorityGroupConfig();
设置所用到的中断的中断优先级别。对每个中断调用函数为 NVIC_Init();



收藏 评论0 发布时间:2022-5-9 19:00

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版