STM32 中断系统深度剖析

在嵌入式系统开发领域,STM32 系列微控制器凭借其强大的性能和丰富的资源被广泛应用。中断系统作为 STM32 的关键特性之一,能够极大地提升系统的实时响应能力和多任务处理效率。本文将基于 STM32F4 系列芯片,深入剖析中断与外设中断的原理、配置及应用,帮助开发者全面掌握这一核心技术。

一、中断简介

中断是指当 CPU 执行程序时,由于外部或内部随机事件的发生,导致 CPU 暂时停止正在运行的程序,转而执行一段特殊的服务程序(中断服务子程序或中断处理程序)。待事件处理完毕后,CPU 再返回被中断的程序继续执行,引发中断的事件源被称为中断源。

STM32 的中断功能极为强大,每个外设都具备产生中断的能力。其中,可屏蔽中断通道多达 82 个(外部),系统异常有 10 个,并且拥有 16 个可编程优先级(使用 4 位中断优先级) 。除个别异常优先级固定外,其他异常优先级均可编程。在标准库文件 stm32f4xx.h 的 IRQn_Type 结构体中,包含了 F4 系列全部的异常声明。以 STM32F405xx/07xx 和 STM32F415xx/17xx 为例,其向量表如下:

序号优先级类型名称说明地址
保留0x00000000
3固定Reset复位0x00000004
W固定NMI不可屏蔽中断,RCC 时钟安全系统(CSS)连接到此向量0x00000008
-1
0
固定
可设置
HardFault
MemManage
所有类型的错误
存储器管理
0x0000000C
0x00000010
1可设置BusFault预取指失败,存储器访问失败0x00000014
2可设置UsageFault未定义的指令或非法状态0x00000018
保留0x0000001C - 0x0000002B
3可设置SVCall通过 SWI 指令调用的系统服务0x0000002C
4可设置DebugMonitor调试监控器0x00000030
保留0x00000034
5可设置Pendsv可挂起的系统服务0x00000038
07
6
可设置
可设置
WWDG
SysTick
窗口看门狗中断
系统滴答定时器
0x00000040
0x0000003C
18可设置PVD连接到 EXTI 线的可编程电压检测0x00000044
29TAMPSTAMP(PVD)中断0x00000048
310可设置
可设置
RTC_WKUP连接到 EXTI 线的入侵和时间蔽中断
连接到 EXTI 线的 RTC 唤醒中断
0x0000004C
4
5
6
7
11
12
13
14
可设置
可设置
可设置
FLASH
RCC
EXTI0
EXTI1
FLASH 全局中断
RCC 全局中断
EXTI 线 0 中断
0x00000050
0x00000054
0x00000058
0x0000005C
8
9
10
15
16
17
可设置
可设置
可设置
EXTI2
EXTI3
EXTI4
EXTI 线 1 中断
EXTI 线 2 中断
EXTI 线 3 中断
EXTI 线 4 中断
0x00000060
0x00000064
0x00000068
...............
80
81
87
88
可设置
可设置
哈希和随机数发生器全局中断
FPU 全局中断
0x00000180
0x00000184

二、NVIC(Nested vectored interrupt controller)

NVIC 即嵌套向量中断控制器,在中断向量表中,优先级 7 - 88(中断号从 0 - 82)代表着 STM32F103 的 91 个中断 ,优先级号越小,优先级越高。当异常或中断被触发时,程序计数器指针(PC)会跳转到对应地址执行,该地址存放跳转指令,进而跳转到服务函数执行相应功能。

在 MDK 开发环境中,可使用标准的异常和中断向量表文件 startup_stm32f40_41xxx.s ,其中明确规定了中断处理函数的名称,开发者不可随意定义。

在 STM32 中,中断优先级由抢占式优先级和响应优先级共同决定,二者组成 4 位控制字,数值越小优先级越高。通过不同的优先级分组,可灵活配置抢占式优先级和子优先级的位数:

优先级分组抢占式优先级子优先级高 4 位使用情况描述
NVICPriorityGroup_00 级抢占优先级0 - 15 级子优先级4bit 全用于子优先级
NVICPriorityGroup_10 - 1 级抢占优先级0 - 7 级子优先级1bit 用于抢占优先级,3bit 用于子优先级
NVICPriorityGroup_20 - 3 级抢占优先级0 - 3 级子优先级2bit 用于抢占优先级,2bit 用于子优先级
NVICPriorityGroup_30 - 7 级抢占优先级0 - 1 级子优先级3bit 用于抢占优先级,1bit 用于子优先级
NVICPriorityGroup_40 - 15 级抢占优先级0 级子优先级4bit 全用于抢占优先级

具有高抢占式优先级的中断能够在低抢占式优先级中断服务程序执行过程中被响应,即支持中断嵌套;而在抢占式优先级相同的情况下,若多个子优先级不同的中断同时到来,高子优先级的中断优先被响应 。不过,子优先级不支持中断嵌套,当低子优先级中断正在执行时,高子优先级中断需等待其执行结束才能得到响应。此外,Reset、NMI、Hard Fault 的优先级为负数,高于普通中断优先级且不可配置。

NVIC 相关的库函数位于 misc.c 中:

  • NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);:用于设置抢占式优先级的位数。

  • NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct);:初始化配置函数,其中 NVIC_InitTypeDef 结构体定义如下:

typedef struct {uint8_t NVIC_IRQChannel; // 指定IRQ通道,可从IRQn_Type枚举中选择uint8_t NVIC_IRQChannelPreemptionPriority; // 抢占式优先级,取值0 - 15,值越小优先级越高uint8_t NVIC_IRQChannelSubPriority; // 子优先级,取值0 - 15,值越小优先级越高FunctionalState NVIC_IRQChannelCmd; // 使能或禁用IRQ通道,可设置为ENABLE或DISABLE
} NVIC_InitTypeDef;

三、外部中断

3.1 外部中断简介

外部中断 / 事件控制器(EXTI)负责管理控制器的 23 个中断 / 事件线 。每个中断 / 事件线都配备边沿检测器,可实现对输入信号的上升沿和下降沿检测。EXTI 能够对每条中断 / 事件线进行单独配置,可设置为中断或事件,并定义触发事件的属性。中断线路将输入信号传输至 NVIC,进而运行中断服务函数实现软件层面的功能;而事件线路则是向其他外设传输脉冲信号,属于硬件级别的电路信号传输。

STM32F4 的中断控制器支持 22 个外部中断 / 事件请求(中断线) 。对于每条中断线,开发者可设置相应的触发方式(上升沿触发、下降沿触发、边沿触发)并使能。各中断线的映射关系如下:

  • EXTI 线 0 - 15:对应外部 IO 口的输入中断。

  • EXTI 线 16:连接到 PVD 输出。

  • EXTI 线 17:连接到 RTC 闹钟事件。

  • EXTI 线 18:连接到 USB OTG FS 唤醒事件。

  • EXTI 线 19:连接到以太网唤醒事件。

  • EXTI 线 20:连接到 USB OTG HS(在 FS 中配置)唤醒事件。

  • EXTI 线 21:连接到 RTC 入侵和时间戳事件。

  • EXTI 线 22:连接到 RTC 唤醒事件。

系统配置控制器(SYSCFG)主要用于管理可执行代码存储区域的地址重映射、选择以太网 PHY 接口以及管理 GPIO 的外部中断线连接 。例如,SYSCFGEXTICR1 寄存器中的 EXTI0 [3:0] 位和 EXTI1 [3:0] 位分别用于映射 PA0 - PI0 和 PA1 - PI1 到相应的 EXTI 线。

3.2 配置流程

  1. 使能 GPIO 外设时钟:为使用的 GPIO 端口提供时钟,确保其正常工作。例如,若使用 PA0 和 PF9 端口,则需使能 GPIOA 和 GPIOF 的时钟:

    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOF, ENABLE);
    
  2. 配置外部中断占用的 GPIO:将用于外部中断的 GPIO 端口配置为输入模式,无需设置复用功能。例如,配置 PA0 为按键输入端口:

    GPIO_InitTypeDef gpio_struct;
    gpio_struct.GPIO_Pin = GPIO_Pin_0;
    gpio_struct.GPIO_Mode = GPIO_Mode_IN;
    gpio_struct.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_Init(GPIOA, &gpio_struct);
    
  3. 使能 SYSCFG 外设时钟:SYSCFG 用于处理外部中断映射,因此需要使能其时钟:

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
    
  4. 设置中断线与 IO 的映射关系:通过 SYSCFG_EXTILineConfig() 函数设置 GPIO 端口与 EXTI 中断线的映射。例如,将 PA0 映射到 EXTI0:

    SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource0);
    
  5. 配置外部中断参数:使用 EXTI_InitTypeDef 结构体配置外部中断的相关参数,如中断线、模式、触发方式和使能状态等。例如,配置 EXTI0 为上升沿触发的中断:

    EXTI_InitTypeDef EXTI_InitStructure;
    EXTI_InitStructure.EXTI_Line = EXTI_Line0;
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_Init(&EXTI_InitStructure);
    
  6. 设置中断优先级(NVIC):通过 NVIC_InitTypeDef 结构体设置外部中断的优先级,包括抢占式优先级和子优先级,并使能中断通道。例如,设置 EXTI0 的优先级:

    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
    NVIC_InitTypeDef mynvic;
    mynvic.NVIC_IRQChannel = EXTI0_IRQn;
    mynvic.NVIC_IRQChannelPreemptionPriority = 0;
    mynvic.NVIC_IRQChannelSubPriority = 3;
    mynvic.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&mynvic);
    
  7. 编写中断处理函数:中断处理函数的名称必须与启动代码向量表中定义的一致。在函数中,需检测中断标志位,处理完中断后清除标志位。例如,EXTI0 的中断处理函数:

void EXTI0_IRQHandler() {if(EXTI_GetFlagStatus(EXTI_Line0) == SET) {// 处理中断事件,如设置标志位led_flag = 1;EXTI_ClearFlag(EXTI_Line0);}
}

3.3 实战案例:按键控制 LED 闪烁

以按下按键使 D1 灯闪烁五次为例,完整代码如下:

#include "stm32f4xx.h"uint8_t led_flag = 0;// 配置GPIO端口
void config_port() {RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOF, ENABLE);// 配置LED1端口为推挽低速输出GPIO_InitTypeDef gpio_struct;gpio_struct.GPIO_Pin = GPIO_Pin_9;gpio_struct.GPIO_Mode = GPIO_Mode_OUT;gpio_struct.GPIO_OType = GPIO_OType_PP;gpio_struct.GPIO_PuPd = GPIO_PuPd_NOPULL;gpio_struct.GPIO_Speed = GPIO_Low_Speed;GPIO_Init(GPIOF, &gpio_struct);// 按键端口配置gpio_struct.GPIO_Pin = GPIO_Pin_0;gpio_struct.GPIO_Mode = GPIO_Mode_IN;gpio_struct.GPIO_PuPd = GPIO_PuPd_NOPULL;GPIO_Init(GPIOA, &gpio_struct); 
}// 设置外部中断(EXTI与syscfg)
void config_exti() {RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource0);EXTI_InitTypeDef EXTI_InitStructure;EXTI_InitStructure.EXTI_Line = EXTI_Line0;EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;EXTI_InitStructure.EXTI_LineCmd = ENABLE;EXTI_Init(&EXTI_InitStructure); 
}// 配置NVIC
void config_nvic() {NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);NVIC_InitTypeDef mynvic;mynvic.NVIC_IRQChannel = EXTI0_IRQn;mynvic.NVIC_IRQChannelPreemptionPriority = 0; mynvic.NVIC_IRQChannelSubPriority = 3;mynvic.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&mynvic);
}// 中断函数
void EXTI0_IRQHandler() {if(EXTI_GetFlagStatus(EXTI_Line0) == SET) {led_flag = 1;EXTI_ClearFlag(EXTI_Line0);}
}// 简单延时函数
void delay() {int i = 1000000;while(i--);
}int main() {config_port();config_exti();config_nvic();while(1) {if(led_flag == 1) {for(int i = 0; i < 5; i++) {GPIO_SetBits(GPIOF, GPIO_Pin_9);delay();delay();GPIO_ResetBits(GPIOF, GPIO_Pin_9);delay();delay();}led_flag = 0;}}
}

在上述代码中,首先通过 config_port() 函数配置了按键输入端口(PA0)和 LED 输出端口(PF9);接着在 config_exti() 函数中完成了外部中断的配置,将 PA0 映射到 EXTI0 并设置为上升沿触发;config_nvic() 函数则设置了 EXTI0 的中断优先级;最后在主函数中,根据按键触发的中断标志 led_flag 控制 LED 闪烁五次。

四、总结

本文全面深入地介绍了 STM32 中断系统中的中断基本概念、NVIC 的工作机制以及外部中断的详细原理和配置方法,并通过实际案例展示了外部中断在按键控制 LED 闪烁中的应用。掌握这些知识对于开发高效、稳定的 STM32 嵌入式系统至关重要。在实际项目中,开发者可根据具体需求灵活配置中断优先级、触发方式等参数,充分发挥 STM32 中断系统的强大功能,提升系统的性能和响应速度。希望本文能为广大嵌入式开发者在 STM32 中断开发方面提供有益的参考和帮助。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/77745.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

1.3 本书结构概览:从理论基础到实践案例的系统阐述

本书采用由浅入深、理论联系实践的结构设计&#xff0c;旨在为读者提供一个关于大模型与智能代理(Agent)技术的全面认知框架与实施路径。全书共分为十章&#xff0c;系统性地覆盖了从技术基础到企业落地的完整知识链条&#xff0c;现概述如下&#xff1a; 首先&#xff0c;第一…

小白训练日记——2025/4/22

实验描述 将GobalM模块加入到changerEx的stage2中。 下面展示一些内联片段&#xff1a; model dict(backbonedict(interaction_cfg(None,dict(typeGlobalM, embed_dim128,num_heads32,axial_strategyrow),dict(typeChannelExchange, p1/2),dict(typeChannelExchange, p1/2))…

【上位机——MFC】MFC入门

MFC库中相关类简介 CObject MFC类库中绝大部分类的父类&#xff0c;提供了MFC类库中一些基本的机制。 对运行时类信息的支持。对动态创建的支持。对序列化的支持。 CWinApp 应用程序类&#xff0c;封装了应用程序、线程等信息。 CDocument 文档类&#xff0c;管理数据 F…

代码随想录第三十七天|华为秋季笔试真题230823

刷题小记&#xff1a; 主要偏向扎实编码基础的考察&#xff0c;但貌似近些年题目难度有所提高&#xff0c;仅供参考。 卡码网136.获取连通的相邻节点列表&#xff08;卡码网136.获取连通的相邻节点列表&#xff09; 题目分析&#xff1a; 题目描述&#xff1a; 存在N个转发…

计算机视觉cv2入门之实时手势检测

前边我们已经讲解了使用cv2进行图像预处理以及针对实时视频流文件的操作方法&#xff0c;这里我们通过实时手势检测这一案例来学习和实操一下。 大致思路 根据手势的种类以及指定手势图片数量来构建一个自己的手势图片数据集CNN模型训练手势图片数据集使用训练好的模型进行实时…

Java 安全:如何防止 SQL 注入与 XSS 攻击?

Java 安全&#xff1a;如何防止 SQL 注入与 XSS 攻击&#xff1f; 在 Java 开发领域&#xff0c;安全问题至关重要&#xff0c;而 SQL 注入和 XSS 攻击是两种常见的安全威胁。本文将深入探讨如何有效防止这两种攻击&#xff0c;通过详细代码实例为您呈现解决方案。 一、SQL 注…

Itext进行PDF的编辑开发

这周写了一周的需求&#xff0c;是制作一个PDF生成功能&#xff0c;其中用到了Itext来制作PDF的视觉效果。其中一些功能不是很懂&#xff0c;仅作记录&#xff0c;若要学习请仔细甄别正确与否。 开始之前&#xff0c;我还是想说&#xff0c;这傻福需求怎么想出来的&#xff0c…

android编译使用共享缓存

注意 服务器端与客户端系统的版本号需为Ubuntu20.04ccache版本不能低于4.4执行用户需要为sudo权限服务器端nfs目录权限必须为nobody:nogroup 一、服务端配置&#xff1a; 在服务器192.168.60.142上配置 NFS 共享 1.安装 NFS 服务器&#xff1a; 1 sudo apt-get install nfs…

工作中sql总结

sql总结 场景1分组后失败的成功数据带入场景2完全性质的一对一匹配场景3虚拟户的特殊匹配场景4多对多匹配场景5一对一匹配场景6 一对多匹配 场景1分组后失败的成功数据带入 现有一批交易表的数据&#xff0c;根据户名&#xff0c;日期&#xff0c;金额分组&#xff0c;存在TRA…

QML FontDialog:使用FontDialog实现字体选择功能

目录 引言相关阅读FontDialog基本介绍字体属性 实例演示项目结构代码实现Main.qmlmain.cpp 代码解析运行效果 总结 引言 在桌面应用程序开发中&#xff0c;字体选择是一个常见的需求。Qt Quick提供了FontDialog组件来实现这一功能。本文将介绍如何在Qt Quick应用程序中使用Fon…

MCP(3):在CherryStudio中使用MCPServer

上一文章讲述了如何新建一个MCP Server&#xff0c;并在MCP Inspector完成测试。本文讲述如何在CherryStudio中进行测试。 Cherry Studio 是一款由 CherryHQ 开发的多模型支持的 AI 桌面助手&#xff0c;兼容 Windows、Linux 和 macOS 系统&#xff0c;旨在为用户提供更便捷、…

面试题-链表(2)

1.合并两个有序链表&#xff1a; 21. 合并两个有序链表 - 力扣&#xff08;LeetCode&#xff09; public ListNode mergeTwoLists(ListNode headA, ListNode headB){ListNode newheadnew ListNode(-1);ListNode curnewhead;while(headA!null&&headB!null){if(headA.va…

微软Entra新安全功能引发大规模账户锁定事件

误报触发大规模锁定 多家机构的Windows管理员报告称&#xff0c;微软Entra ID新推出的"MACE"&#xff08;泄露凭证检测应用&#xff09;功能在部署过程中产生大量误报&#xff0c;导致用户账户被大规模锁定。这些警报和锁定始于昨夜&#xff0c;部分管理员认为属于误…

【MATLAB第117期】#源码分享 | 基于MATLAB的SSM状态空间模型多元时间序列预测方法(多输入单输出)

【MATLAB第117期】#源码分享 | 基于MATLAB的SSM状态空间模型多元时间序列预测方法&#xff08;多输入单输出&#xff09; 引言 本文使用状态空间模型实现失业率递归预测&#xff0c;状态空间模型&#xff08;State Space Model, SSM&#xff09;是一种用于描述动态系统行为的…

谷歌浏览器搜索后的页面总是覆盖当前页面

最近将搜索引擎换为谷歌后&#xff0c;发现&#xff0c;每次搜索完的结果页面总是覆盖当前页面&#xff0c;非常不方便&#xff0c;在浏览器设置中又找不到类似设置的选项&#xff0c;然后终于在一个博主“如何设置使谷歌浏览器打开链接自动跳转到新标签页而不是覆盖当前页面?…

记录学习的第三十天

今天终于又开始写博客了。 还是滑动窗口问题&#xff0c;这段时间不出意外都是这了 上面的思路是我自己做的&#xff0c;但是不知道为什么不行&#xff0c;有没有大佬能指点一下我。 接下来这道题是进阶的。不过我之前的基础都做的很艰难&#xff0c;道阻且长啊。

QTextDocument 入门

一、QTextDocument QTextDocument 是 Qt 中用于处理富文本文档的核心类&#xff0c;支持文本格式、图片、表格等复杂内容。 1. QTextDocument 入门 1.1 基本概念 QTextDocument 是 Qt 中用于处理富文本内容的核心类&#xff0c;它提供了&#xff1a; 结构化文本存储&#x…

WebRTC服务器Coturn服务器相关测试工具

1、概述 在安装开源的webrtc服务器coturn服务器后&#xff0c;会附带安装coturn的相关工具&#xff0c;主要有以下几种工具 2、turnadmin工具 说明&#xff1a;服务器命令行工具&#xff0c;提供添加用户、添加管理员、生成TURN密钥等功能&#xff0c;turnadmin -h查看详细用…

如何创建Vue3工程

1.首先下载环境 &#xff08;默认下好了VS code&#xff09; Node.js: Node.js 中文网 — 下载 Node.js 选择要下载的版本 检查环境&#xff1a; 在命令行中输入 node ,检查版本号 2.创建工程 1.找到自己要创建工程的文件目录&#xff0c;右键打开打开终端 在终端输入创…

基于大模型的肛裂手术全流程预测与治疗方案研究报告

目录 一、引言 1.1 研究背景与意义 1.2 研究目标与创新点 1.3 研究方法与技术路线 二、肛裂概述与大模型技术原理 2.1 肛裂的医学定义与分类 2.2 肛裂的发病机制与临床症状 2.3 大模型技术简介 三、大模型在肛裂术前预测的应用 3.1 术前风险因素分析与数据收集 3.2 …