初学stm32 --- NVIC中断
目录
STM32 NVIC 中断优先级管理
NVIC_Type:
ISER[8]:
ICER[8]:
ISPR[8]:
ICPR[8]:
IABR[8]:
IP[240]:
STM32 的中断分组:
中断优先级分组函数 NVIC_PriorityGroupConfig
中断初始化函数 NVIC_Init
总结
STM32 NVIC 中断优先级管理
CM3 内核支持 256 个中断,其中包含了 16 个内核中断和 240 个外部中断,并且具有 256级的可编程中断设置。但 STM32 并没有使用 CM3 内核的全部东西,而是只用了它的一部分。STM32 有 84 个中断,包括 16 个内核中断和 68 个可屏蔽中断,具有 16 级可编程的中断优先级。
而我们常用的就是这 68 个可屏蔽中断, 但是 STM32 的 68 个可屏蔽中断,在 STM32F103 系列上面,又只有 60 个(在 107 系列才有 68 个)。因为我们开发板选择的芯片是 STM32F103 系列的,所以我们就只针对 STM32F103 系列这 60 个可屏蔽中断进行介绍。
在 MDK 内,与 NVIC 相关的寄存器, MDK 为其定义了如下的结构体:
NVIC_Type:
typedef struct
{
__IO uint32_t ISER[8]; /*!< Interrupt Set Enable Register */
uint32_t RESERVED0[24];
__IO uint32_t ICER[8]; /*!< Interrupt Clear Enable Register */
uint32_t RSERVED1[24];
__IO uint32_t ISPR[8]; /*!< Interrupt Set Pending Register */
uint32_t RESERVED2[24];
__IO uint32_t ICPR[8]; /*!< Interrupt Clear Pending Register */
uint32_t RESERVED3[24];
__IO uint32_t IABR[8]; /*!< Interrupt Active bit Register */
uint32_t RESERVED4[56];
__IO uint8_t IP[240]; /*!< Interrupt Priority Register, 8Bit wide */
uint32_t RESERVED5[644];
__O uint32_t STIR; /*!< Software Trigger Interrupt Register */
} NVIC_Type;
STM32 的中断在这些寄存器的控制下有序的执行的。 只有了解这些中断寄存器,才能方便的使用 STM32 的中断。下面重点介绍这几个寄存器:
ISER[8]:
全称是: Interrupt Set-Enable Registers,这是一个中断使能寄存器组。上面说了 CM3 内核支持 256 个中断,这里用 8 个 32 位寄存器来控制,每个位控制一个中断。但是STM32F103 的可屏蔽中断只有 60 个,所以对我们来说,有用的就是两个(ISER[0]和 ISER[1]),总共可以表示 64 个中断。而 STM32F103 只用了其中的前 60 位。 ISER[0]的 bit0~bit31 分别对应中断 0~31。 ISER[1]的 bit0~27 对应中断 32~59;这样总共 60 个中断就分别对应上了。 你要使能某个中断,必须设置相应的 ISER 位为 1,使该中断被使能(这里仅仅是使能,还要配合中断分组、屏蔽、 IO 口映射等设置才算是一个完整的中断设置)。具体每一位对应哪个中断,请参考 stm32f10x.h 里面的第 140 行处(针对编译器 MDK5 来说)。
#ifdef STM32F10X_HDADC1_2_IRQn = 18, /*!< ADC1 and ADC2 global Interrupt */USB_HP_CAN1_TX_IRQn = 19, /*!< USB Device High Priority or CAN1 TX Interrupts */USB_LP_CAN1_RX0_IRQn = 20, /*!< USB Device Low Priority or CAN1 RX0 Interrupts */CAN1_RX1_IRQn = 21, /*!< CAN1 RX1 Interrupt */CAN1_SCE_IRQn = 22, /*!< CAN1 SCE Interrupt */EXTI9_5_IRQn = 23, /*!< External Line[9:5] Interrupts */TIM1_BRK_IRQn = 24, /*!< TIM1 Break Interrupt */TIM1_UP_IRQn = 25, /*!< TIM1 Update Interrupt */TIM1_TRG_COM_IRQn = 26, /*!< TIM1 Trigger and Commutation Interrupt */TIM1_CC_IRQn = 27, /*!< TIM1 Capture Compare Interrupt */TIM2_IRQn = 28, /*!< TIM2 global Interrupt */TIM3_IRQn = 29, /*!< TIM3 global Interrupt */TIM4_IRQn = 30, /*!< TIM4 global Interrupt */I2C1_EV_IRQn = 31, /*!< I2C1 Event Interrupt */I2C1_ER_IRQn = 32, /*!< I2C1 Error Interrupt */I2C2_EV_IRQn = 33, /*!< I2C2 Event Interrupt */I2C2_ER_IRQn = 34, /*!< I2C2 Error Interrupt */SPI1_IRQn = 35, /*!< SPI1 global Interrupt */SPI2_IRQn = 36, /*!< SPI2 global Interrupt */USART1_IRQn = 37, /*!< USART1 global Interrupt */USART2_IRQn = 38, /*!< USART2 global Interrupt */USART3_IRQn = 39, /*!< USART3 global Interrupt */EXTI15_10_IRQn = 40, /*!< External Line[15:10] Interrupts */RTCAlarm_IRQn = 41, /*!< RTC Alarm through EXTI Line Interrupt */USBWakeUp_IRQn = 42, /*!< USB Device WakeUp from suspend through EXTI Line Interrupt */TIM8_BRK_IRQn = 43, /*!< TIM8 Break Interrupt */TIM8_UP_IRQn = 44, /*!< TIM8 Update Interrupt */TIM8_TRG_COM_IRQn = 45, /*!< TIM8 Trigger and Commutation Interrupt */TIM8_CC_IRQn = 46, /*!< TIM8 Capture Compare Interrupt */ADC3_IRQn = 47, /*!< ADC3 global Interrupt */FSMC_IRQn = 48, /*!< FSMC global Interrupt */SDIO_IRQn = 49, /*!< SDIO global Interrupt */TIM5_IRQn = 50, /*!< TIM5 global Interrupt */SPI3_IRQn = 51, /*!< SPI3 global Interrupt */UART4_IRQn = 52, /*!< UART4 global Interrupt */UART5_IRQn = 53, /*!< UART5 global Interrupt */TIM6_IRQn = 54, /*!< TIM6 global Interrupt */TIM7_IRQn = 55, /*!< TIM7 global Interrupt */DMA2_Channel1_IRQn = 56, /*!< DMA2 Channel 1 global Interrupt */DMA2_Channel2_IRQn = 57, /*!< DMA2 Channel 2 global Interrupt */DMA2_Channel3_IRQn = 58, /*!< DMA2 Channel 3 global Interrupt */DMA2_Channel4_5_IRQn = 59 /*!< DMA2 Channel 4 and Channel 5 global Interrupt */
#endif /* STM32F10X_HD */
ICER[8]:
全称是: Interrupt Clear-Enable Registers,是一个中断除能寄存器组。该寄存器组与 ISER 的作用恰好相反,是用来清除某个中断的使能的。其对应位的功能,也和 ICER 一样。这里要专门设置一个 ICER 来清除中断位,而不是向 ISER 写 0 来清除,是因为 NVIC 的这些寄存器都是写 1 有效的,写 0 是无效的。具体为什么这么设计,请看《CM3 权威指南》第 125 页, NVIC 概览一章。
ISPR[8]:
全称是: Interrupt Set-Pending Registers,是一个中断挂起控制寄存器组。每个位对应的中断和 ISER 是一样的。通过置 1,可以将正在进行的中断挂起,而执行同级或更高级别的中断。写 0 是无效的。
ICPR[8]:
全称是: Interrupt Clear-Pending Registers,是一个中断解挂控制寄存器组。其作用与 ISPR 相反,对应位也和 ISER 是一样的。通过设置 1,可以将挂起的中断接挂。写 0 无效。
IABR[8]:
全称是: Interrupt Active Bit Registers,是一个中断激活标志位寄存器组。对应位所代表的中断和 ISER 一样,如果为 1,则表示该位所对应的中断正在被执行。这是一个只读寄存器,通过它可以知道当前在执行的中断是哪一个。在中断执行完了由硬件自动清零。
IP[240]:
全称是: Interrupt Priority Registers,是一个中断优先级控制的寄存器组。这个寄存器组相当重要! STM32 的中断分组与这个寄存器组密切相关。 IP 寄存器组由 240 个 8bit 的寄存器组成,每个可屏蔽中断占用 8bit,这样总共可以表示 240 个可屏蔽中断。 而 STM32 只用到了其中的前 60 个。 IP[59]~IP[0]分别对应中断 59~0。 而每个可屏蔽中断占用的 8bit 并没有全部使用,而是 只用了高 4 位。这 4 位,又分为抢占优先级和子优先级。抢占优先级在前,子优先级在后。而这两个优先级各占几个位又要根据 SCB->AIRCR 中的中断分组设置来决定。
STM32 的中断分组:
STM32 将中断分为 5 个组,组 0~4。该分组的设置是由 SCB->AIRCR 寄存器的 bit10~8 来定义的。具体的分配关系如表1 所示:

通过这个表,我们就可以清楚的看到组 0~4 对应的配置关系,例如组设置为 3,那么此时所有的 60 个中断,每个中断的中断优先寄存器的高四位中的最高 3 位是抢占优先级,低 1 位是响应优先级。每个中断,你可以设置抢占优先级为 0~7,响应优先级为 1 或 0。抢占优先级的级别高于响应优先级。而数值越小所代表的优先级就越高。
这里需要注意两点:
第一,如果两个中断的抢占优先级和响应优先级都是一样的话,则看哪个中断先发生就先执行;
第二,高优先级的抢占优先级是可以打断正在进行的低抢占优先级中断的。而抢占优先级相同的中断,高优先级的响应优先级不可以打断低响应优先级的中断,当两个中断同时发生的时候响应优先级高的先执行中断。
结合实例说明一下:
假定设置中断优先级组为 2,然后设置中断 3(RTC 中断)的抢占优先级为 2,响应优先级为 1。中断 6(外部中断 0)的抢占优先级为 3,响应优先级为 0。中断 7(外部中断 1) 的抢占优先级为 2,响应优先级为 0。那么这 3 个中断的优先级顺序为:中断 7>中断 3>中断 6。
上面例子中的中断 3 和中断 7 都可以打断中断 6 的中断。而中断 7 和中断 3 却不可以相互打断!
接下来我们介绍如何使用库函数实现以上中断分组设置以及中断优先级管理。 NVIC 中断管理函数主要在 misc.c 文件里面
中断优先级分组函数 NVIC_PriorityGroupConfig
void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup);
这个函数的作用是对中断的优先级进行分组,这个函数在系统中只能被调用一次,一旦分组确定就最好不要更改。这个函数我们可以找到其实现:
void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup)
{assert_param(IS_NVIC_PRIORITY_GROUP(NVIC_PriorityGroup));SCB->AIRCR = AIRCR_VECTKEY_MASK | NVIC_PriorityGroup;
}
从函数体可以看出,这个函数唯一目的就是通过设置 SCB->AIRCR 寄存器来设置中断优先级分组。
#define IS_NVIC_PRIORITY_GROUP(GROUP)
(((GROUP) == NVIC_PriorityGroup_0) ||
((GROUP) == NVIC_PriorityGroup_1) || \
((GROUP) == NVIC_PriorityGroup_2) || \
((GROUP) == NVIC_PriorityGroup_3) || \
((GROUP) == NVIC_PriorityGroup_4))
这也是我们上面表1 讲解的,分组范围为 0-4。比如我们设置整个系统的中断优先级分组值为 2,那么方法是:
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
这样就确定了一共为“2 位抢占优先级, 2 位响应优先级”。
中断初始化函数 NVIC_Init
void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct)
其中 NVIC_InitTypeDef 是一个结构体,我们可以看看结构体的成员变量:
typedef struct
{uint8_t NVIC_IRQChannel;uint8_t NVIC_IRQChannelPreemptionPriority;uint8_t NVIC_IRQChannelSubPriority;FunctionalState NVIC_IRQChannelCmd;
} NVIC_InitTypeDef;
NVIC_InitTypeDef 结构体中间有四个成员变量,这四个成员变量的作用是:
- NVIC_IRQChannel:定义初始化的是哪个中断,这个我们可以在 stm32f10x.h 中找到每个中断对应的名字。例如 USART1_IRQn。
- NVIC_IRQChannelPreemptionPriority:定义这个中断的抢占优先级别。
- NVIC_IRQChannelSubPriority:定义这个中断的子优先级别。
- NVIC_IRQChannelCmd:该中断是否使能。
比如我们要使能串口 1 的中断,同时设置抢占优先级为 1,子优先级位 2,初始化的方法是:
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;//串口 1 中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1 ;// 抢占优先级为 1
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;// 子优先级位 2
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ 通道使能
NVIC_Init(&NVIC_InitStructure); //根据上面指定的参数初始化 NVIC 寄存器
总结
- 系统运行开始的时候设置中断分组。 确定组号,也就是确定抢占优先级和子优先级的分配位数。 调用函数为 NVIC_PriorityGroupConfig();
- 设置所用到的中断的中断优先级别。 对每个中断调用函数为 NVIC_Init();
相关文章:

初学stm32 --- NVIC中断
目录 STM32 NVIC 中断优先级管理 NVIC_Type: ISER[8]: ICER[8]: ISPR[8]: ICPR[8]: IABR[8]: IP[240]: STM32 的中断分组: 中断优先级分组函数 NVIC_PriorityGroupConfig 中断初始化函…...

Jest 入门指南:从零开始编写 JavaScript 单元测试
前言 在前端开发中,单元测试已经成为确保代码质量和稳定性的关键步骤。Jest 作为由 Facebook 开发和维护的功能强大的 JavaScript 测试框架,以其易于配置、丰富的功能和开箱即用的特性,成为众多开发者的首选工具。本文旨在引导你从零开始&am…...

【Java Web】Axios实现前后端数据异步交互
目录 一、Promise概述 二、Promise基本用法 三、async和await关键字 四、Axios介绍 4.1 Axios基本用法 4.2 Axios简化用法之get和post方法 五、Axios拦截器 六、跨域问题处理 一、Promise概述 axios是代替原生的ajax实现前后端数据交互的一套新解决方案,而…...

React 第十七节 useMemo用法详解
概述 useMemo 是React 中的一个HOOK,用于根据依赖在每次渲染时候缓存计算结果; 大白话就是,只有依赖项发生变化时候,才会重新渲染为新计算的值,否则就还是取原来的值,有点类似 vue 中的 computed 计算属性…...

鸿蒙项目云捐助第十五讲云数据库的初步使用
鸿蒙项目云捐助第十五讲云数据库的初步使用 在华为云技术使用中,前面使用了云函数,接下来看一下华为云技术中的另外一个技术云数据库的使用。 一、云数据库的创建 这里使用华为云数据库也需要登录到AppGallery Connect平台中,点击进入到之…...

如何构建一个可信的联邦RAG系统。
今天给大家分享一篇论文。 题目是:C-RAG:如何构建一个可信的联邦检索RAG系统。 论文链接:https://arxiv.org/abs/2412.13163 论文概述 尽管大型语言模型 (LLM) 在各种应用中展现出令人印象深刻的能力,但它们仍然存在可信度问题ÿ…...

【深度学习之三】FPN与PAN网络详解
FPN与PAN:深度学习中的特征金字塔网络与路径聚合网络 在深度学习的领域里,特征金字塔网络(Feature Pyramid Networks,简称FPN) 和 路径聚合网络(Path Aggregation Network,简称PAN)…...

Qt学习笔记第71到80讲
第71讲 事件过滤器的方式实现滚轮按键放大 事件体系(事件派发 -> 事件过滤->事件分发->事件处理)中,程序员主要操作的是事件分发与事件处理。我们之前已经通过继承QTextEdit来重写事件实现Ctrl加滚轮的检测,还有一种处理…...

以管理员身份运行
同时按下Ctrl Shift Esc键打开任务管理器,在任务管理器的左上角,点击“文件”菜单,在下拉菜单中选择“新建任务” 在弹出的对话框中,输入您想要运行的程序的名称。如果您不确定程序的确切名称,可以点击“浏览”来找到…...

用 Python 实现井字棋游戏
一、引言 井字棋(Tic-Tac-Toe)是一款经典的两人棋类游戏。在这个游戏中,玩家轮流在 3x3 的棋盘上放置自己的标记,通常是 “X” 和 “O”,第一个在棋盘上连成一线(横、竖或斜)的玩家即为获胜者。…...

06 实现自定义AXI DMA驱动
为什么要实现自定义AXI DMA驱动 ZYNQ 的 AXI DMA 在 Direct Register DMA (即 Simple DMA)模式下可以通过 AXIS 总线的 tlast 提前结束传输,同时还可以在 BUFFLEN 寄存器中读取到实际传输的字节数,但是通过 Linux 的 DMA 驱动框架…...

SpringBoot集成ENC对配置文件进行加密
在线MD5生成工具 配置文件加密,集成ENC 引入POM依赖 <!-- ENC配置文件加密 --><dependency><groupId>com.github.ulisesbocchio</groupId><artifactId>jasypt-spring-boot-starter</artifactId><version>2.1.2</ver…...

初学stm32 ——— 串口通信
目录 STM32的串口通信接口 UART异步通信方式特点: 串口通信过程 STM32串口异步通信需要定义的参数: USART框图: 常用的串口相关寄存器 串口操作相关库函数 编辑 串口配置的一般步骤 STM32的串口通信接口 UART:通用异步收发器USART&am…...

qwt 多Y轴 项目效果
项目场景: 在做一个半导体上位机软件项目实践中,需要做一个曲线展示和分析界面,上位机主题是用qt框架来开发,考虑到目前qt框架的两种图标库,一个是qcustomplot 一个是 qwt。之所以采用qwt ,根本原因是因为…...

Java中通过ArrayList扩展数组
在Java中,ArrayList 是一个动态数组实现,能够根据需要自动调整其大小。与传统的数组不同,ArrayList 不需要预先指定大小,并且提供了许多方便的方法来操作集合中的元素。下面将详细介绍如何使用 ArrayList 进行数组的扩展ÿ…...

Java:链接redis报错:NoSuchElementException: Unable to validate object
目录 前言报错信息排查1、确认redis密码设置是否有效2、确认程序配置文件,是否配置了正确的redis登录密码3、检测是否是redis持久化的问题4、确认程序读取到的redis密码没有乱码 原因解决 前言 一个已经上线的项目,生产环境的redis居然没有设置密码&…...

datasets库之load_dataset
目录 问题解决方案 问题 使用peft用lora微调blip2时用到了一个足球数据集,如下: 原始代码如下 dataset load_dataset("ybelkada/football-dataset", split"train")然而这需要梯子才能下载,服务器较难用VPN所以使用au…...

React Router常见面试题目
1. React Router 支持哪几种模式? React Router 支持以下两种主要模式: BrowserRouter (基于 HTML5 History API 的模式) 原理: 利用 history.pushState 和 history.replaceState 操作浏览器历史栈,无需重新加载页面。URL 看起来像传统 URL…...

sequelize-cli 封装登录接口
node ORM (sequelize)使用、查询、验证及express 基础框架的搭建及实例的使用 一、思路 第一步:肯定是用户要向接口传递邮箱、账号和密码了。 第二步:接口这边,先要验证。因为这里不是往数据库里存储数据,…...

使用 Elasticsearch 查询和数据同步的实现方法
在开发过程中,将数据从数据库同步到 Elasticsearch (ES) 是常见的需求之一。本文将重点介绍如何通过 Python 脚本将数据库中的数据插入或更新到 Elasticsearch,并基于多字段的唯一性来判断是否执行插入或更新操作。此外,我们还将深入探讨如何…...

QTday1作业设置简易登录界面
代码 #include "mywidget.h"MyWidget::MyWidget(QWidget *parent): QWidget(parent) {//创建一个标签QLabel *lab1 new QLabel(this);//重新设置大小lab1->resize(1925,1080);//用动图类QMovie实例化一个动图QMovie *mv new QMovie("C:\\Users\\MR\\Deskto…...

RC低通滤波器和LR低通滤波器,LC低通滤波器该怎么选择
这是RC低通滤波器利用电容两端的电压不能突变可以滤除高频噪声 这是LR低通滤波器利用流过电感的电流不能突变也可以滤除高频噪声 那么问题来了两个低通滤波器,该怎么选择呢还是随便选一个就好? RC电路:因为电流电阻会发热耗能,所…...

芯旺微KF32A156芯片ADC配置
使用芯旺微KF32A156的芯片做预研项目,使用了ADC0外设,根据芯片规格书中的描述进行了配置: /*** brief: Configure ADC.** param[in] none.* param[in] none.* param[out] None* retval: None*/ static void adc_peripheral_init(void) …...

【Token】校验、会话技术、登录请求、拦截器【期末实训】实战项目学生和班级管理系统\Day15-后端Web实战(登录认证)\讲义
登录认证 在前面的课程中,我们已经实现了部门管理、员工管理的基本功能,但是大家会发现,我们并没有登录,就直接访问到了Tlias智能学习辅助系统的后台。 这是不安全的,所以我们今天的主题就是登录认证。 最终我们要实现…...

[Unity Shader] 【游戏开发】【图形渲染】Shader数学基础3:矢量与标量的乘法与除法详解
在计算机图形学和Shader编程中,矢量(Vector)运算是非常基础的数学知识。其中,矢量与标量(Scalar)的乘法与除法是常见的操作。本篇文章将通过详细分析,以及实例讲解矢量和标量的乘除法运算,帮助大家更好地理解并应用到实际开发中。 什么是矢量与标量? 在开始具体运算之…...

javalock(四)AQS派生类之Semphore逐行注释
简单概括: Semphore是一把共享锁(即读锁),即实现了AQS的tryAcquireShared&&tryReleaseShared函数Semphore的逻辑是这样: 创建semphore的时候会初始化一个锁容量即permits,即最多同时允许permits个…...

【C语言】头文件”“和<>的详解
前言 作者在刚开始学C语言的时候,都是用的< >去引用头文件,但在学习STM32的时候发现,程序中大量使用" "去引用双引号。 那么二者有什么区别呢? 无论使用哪种方式,头文件的目的都是为了引用你需要的文件供你编程使…...

Elasticsearch:什么是信息检索?
信息检索定义 信息检索 (IR) 是一种有助于从大量非结构化或半结构化数据中有效、高效地检索相关信息的过程。信息(IR)检索系统有助于搜索、定位和呈现与用户的搜索查询或信息需求相匹配的信息。 作为信息访问的主要形式,信息检索是每天使用…...

Spark-Streaming容错语义
一、背景 为了理解Spark Streaming提供的语义,我们先回顾西Spark RDD的基本容错语义学。 RDD是一个不可变的、确定性可重新计算的分布式数据集。每个RDD都记住在容错输入数据集上用于创建它的确定性操作的沿袭。如果RDD的任何分区由于工作节点故障而丢失ÿ…...

2024年12月陪玩系统-仿东郊到家约玩系统是一种新兴的线上预约线下社交、陪伴系统分享-优雅草央千澈-附带搭建教程
2024年12月陪玩系统-仿东郊到家约玩系统是一种新兴的线上预约线下社交、陪伴系统分享-优雅草央千澈-附带搭建教程 产品介绍 仿东郊到家约玩系统是一种新兴的线上预约,线下社交、陪伴、助娱、助攻、分享、解答、指导等服务模式,范围涉及电竞、运动、音乐…...