【STM32C5教程】(4)GPIO 外部中断实验
欢迎关注 youcansxidian【嵌入式软件AI编程】专栏【STM32C5教程】1STM32C5系列介绍【STM32C5教程】2STM32CubeMX2 安装与STM32C5闪灯【STM32C5教程】3GPIO 按键输入实验【STM32C5教程】4GPIO 外部中断实验1. 项目简介1.1 实验目标本实验在 NUCLEO-C542RC 开发板上将用户按键 B1PC13配置为外部中断输入按下按键触发中断在中断回调中切换板载 LEDPA5的状态掌握 STM32C5 系列 EXTI 外部中断的配置与使用方法。功能需求按下用户按键PC13时触发外部中断在中断回调中切换板载 LEDPA5状态消抖时间 20 ms开发板和 MCU 型号NUCLEO-C542RC 开发板搭载 STM32C542RCT6 MCU。1.2 实验条件硬件NUCLEO-C542RC 开发板支持数据传输的 USB Type-C 线用于连接 ST-LINK 接口软件STM32CubeMX2用于引脚、时钟配置与代码生成VS Code STM32Cube 插件用于编译、烧录、调试2. 硬件说明2.1 NUCLEO-C542RC 开发板NUCLEO-C542RC 是 ST 基于 STM32C542RCT6 推出的 Nucleo-64 开发板。主要特性MCUSTM32C542RCT6Arm Cortex-M33 内核最高主频 144 MHz256 KB Flash64 KB RAM调试器板载 STLINK-V3EC支持大容量存储、虚拟串口和调试端口三种功能用户 LEDLD1连接 PA5用户按键B1连接 PC13复位按键B2扩展接口Arduino Uno V3 和 ST morpho 连接器本实验使用板载的 LD1 和 B1无需额外外设。2.2 引脚说明引脚别名功能方向有效电平PA5LD1板载用户 LEDGPIO 输出高电平点亮PC13B1用户按键EXTI 中断输入按下为高电平松开为低电平PA5LD1配置为推挽输出输出高电平时 LED 点亮输出低电平时 LED 熄灭。复位后初始状态为低电平LED 熄灭。PC13B1配置为外部中断输入。按键按下时引脚为低电平松开时为高电平。本实验采用上升沿触发即中断发生在按键松开的瞬间。3. STM32CubeMX2 工程配置3.1 新建工程本实验采用 MCU 方式创建工程即以芯片型号 STM32C542RC 为起点而非开发板方式。进入 MCU 选择界面启动 STM32CubeMX2在首页点击 MCU进入芯片型号选择列表。搜索并选中芯片在 MCU name 输入框中输入 STM32C542RC或完整型号 STM32C542RCT6从筛选出的列表中选择对应型号。填写项目信息输入项目名称 GPIO_EXTI 和项目保存路径。项目名称避免使用特殊字符路径建议使用纯英文目录。3.2 基础配置工程创建后软件自动进入 Pinout 视图。时钟配置保持默认即可CubeMX2 创建工程后的默认系统主频为48 MHz时钟源为 HSI 分频本实验无需修改。注意本工程的系统时钟为 48 MHz这是 CubeMX2 的默认配置不影响 GPIO 功能。3.3 GPIO 配置1PA5 配置为输出在 Pinout 视图中找到PA5引脚。右键点击 PA5选择Assign signal→GPIO。再次右键点击 PA5选择Configure GPIO进入 GPIO 详细配置界面。将 PA5 的Mode设置为Output。保持默认参数Output level 为 LowOutput mode 为 Push PullPull-up/Pull-down 为 No pull-up and no pull-downMaximum output speed 为 Low。在User Label输入框中填入LD1。设置别名后CubeMX2 会自动生成宏定义LD1_PORT和LD1_PIN。2PC13 配置为外部中断在 Pinout 视图中找到PC13引脚。右键点击 PC13选择Assign signal→GPIO。再次右键点击 PC13选择Configure GPIO进入 GPIO 详细配置界面。将 PC13 的Mode设置为Interrupt。将Trigger detection设置为Rising edge上升沿触发。将Interrupt设置为Enabled启用中断CubeMX2 会自动选择 EXTI13。将Pull-up/Pull-down设置为No pull-up and no pull-down。PC13 外部已有下拉电阻 R13内部无需再设上下拉避免与外部电阻形成分压。在User Label输入框中填入B1。3.4 项目配置点击Project Settings进入工程设置页面。在IDE Format下拉选项中选择CMake。在CMake Toolchain下拉选项中选择GCC。确认配置无误后点击Generate Code。CubeMX2 会执行配置检查如果没有错误开始在指定路径下生成 CMake 工程文件。生成完成后项目路径下会出现标准 CMake 工程结构包含Core/、Drivers/、CMakeLists.txt等。4. 编程实现4.1 实现思路采用“EXTI 边沿中断 时间戳消抖 回调中翻转 LED”的方案用户操作 B1PC13 │ ├─ 按下 → 引脚由低变高 ──────┐ │ │ 硬件 EXTI13 检测到上升沿 │ ▼ │ EXTI13_IRQHandler() │ │ │ ▼ │ HAL_EXTI_IRQHandler() │ │ │ ▼ │ HAL_EXTI_TriggerCallback() │ │ │ ┌───────┴────────┐ │ │ 距上次响应 20ms? │ │ └───┬───────────┬───┘ │ │ 是 │ 否 有效触发 │ ▼ ▼ │ 视为抖动 更新 last_tick │ 忽略 翻转 LED │ └─ 松开 → 引脚由高变低 → 下降沿不配置触发无中断与轮询方案的区别轮询版在主循环while(1)中不停地读引脚判断是否按下本实验用硬件 EXTI 边沿产生中断由中断回调响应主循环保持空闲。中断中不能用HAL_Delay()阻塞延时会导致中断服务程序长时间占用 CPU影响系统实时性。本实验改用HAL_GetTick()时间戳比较实现非阻塞消抖。各步骤使用的 HAL 函数步骤HAL 函数作用中断入口HAL_EXTI_IRQHandler()清中断标志调用触发回调读当前时间HAL_GetTick()获取系统毫秒节拍用于消抖计时翻转 LEDHAL_GPIO_TogglePin(LD1_PORT, LD1_PIN)切换 PA5 输出电平4.2 关键代码在 VS Code 中打开生成的 CMake 工程找到Core/Src/main.c添加以下代码。1文件头部添加宏定义与变量/* Private define ------------------------------------------------------------*/#defineDEBOUNCE_TIME_MS20U/* 消抖时间毫秒 *//* Private variables ---------------------------------------------------------*/staticuint32_tlast_tick0U;/* 上一次有效按键触发时的系统时间戳用于消抖 *//* Private functions prototype -----------------------------------------------*/staticvoidhandle_key_press(void);2主函数intmain(void){if(mx_system_init()!SYSTEM_OK){return(-1);}else{/* 记录上电时刻作为消抖时间戳的初始化基准 */last_tickHAL_GetTick();/* 主循环空闲等待按键事件由 EXTI13 中断触发处理 */while(1){}}}3按键处理函数/** * brief: 按键有效按下时的处理函数。 * retval: 无 */staticvoidhandle_key_press(void){/* 切换板载 LEDPA5状态每次有效按下翻转一次 */HAL_GPIO_TogglePin(LD1_PORT,LD1_PIN);}4EXTI 触发回调函数/** * brief: EXTI 触发回调覆盖默认实现。 * 当 PC13B1 用户按键产生上升沿中断时被调用。 * PC13 外部下拉、空闲为低、按下为高一次上升沿对应一次按下动作。 * param: hexti EXTI 句柄 * param: trigger 触发沿本工程仅配置了上升沿 * retval: 无 */voidHAL_EXTI_TriggerCallback(hal_exti_handle_t*hexti,hal_exti_trigger_ttrigger){uint32_ttick;/* 仅处理上升沿触发本工程只有 PC13/B1 配置了 EXTI 上升沿 */if(trigger!HAL_EXTI_TRIGGER_RISING){return;}tickHAL_GetTick();/* 基于时基的软件消抖间隔小于消抖时间则视为抖动忽略本次触发 */if((tick-last_tick)DEBOUNCE_TIME_MS){return;}/* 更新最后一次有效触发时刻作为下一次消抖比较基准 */last_ticktick;/* 执行有效按键动作切换板载 LED */handle_key_press();/* 避免未使用形参的编译警告 */STM32_UNUSED(hexti);}代码说明LD1_PORT、LD1_PIN两个宏由 CubeMX2 生成在generated/hal/mx_gpio_default.h通过main.h链入在main.c中可直接使用。回调函数HAL_EXTI_TriggerCallback()是 HAL 驱动中已经声明好的回调入口。用户在自己的源文件中重写这个同名函数中断发生时 HAL 就会自动调用它无需修改驱动源码。回调中判断trigger ! HAL_EXTI_TRIGGER_RISING后提前返回。当前工程只配置了上升沿这个判断是防御性写法——如果将来同一个工程里还有其他触发边沿的 EXTI 配置这段代码可以保证只响应上升沿。消抖使用HAL_GetTick()获取当前毫秒时刻与上次有效触发时刻比较。时间差 20ms才判定为有效触发并更新时间戳。这是非阻塞消抖不会阻塞中断。STM32_UNUSED(hexti)用于避免未使用形参的编译告警工程开启了-Wall。5. 编译烧录与运行测试5.1 编译与烧录打开工程用 VS Code 打开 CubeMX2 生成的 CMake 工程文件夹如GPIO_EXTI_cmake。编译点击 VS Code 底部状态栏的Build按钮或使用命令面板执行 CMake 构建。编译完成后终端应输出Build finished with exit code 0无 error。连接开发板用支持数据传输的 USB Type-C 线连接 NUCLEO-C542RC 的 ST-LINK USB 口CN1。确认设备识别打开设备管理器在“端口 (COM 和 LPT)”下应能看到STLink COMx。烧录点击 VS Code 中的运行按钮将固件下载到开发板。5.2 运行与测试烧录完成后程序自动开始运行。依次验证以下功能测试 1初始状态复位开发板按下黑色复位按键 B2观察 LD1。复位后 LD1 应保持熄灭状态说明 GPIO 初始化正确空闲时没有误触发。测试 2按下触发按下 B1观察 LD1 是否翻转。由于配置为上升沿触发中断发生在按下的瞬间按下时 LD1 立即翻转松开时 LD1 状态不变。反复测试几次确认每次按下都能可靠触发翻转。测试 3消抖验证快速连续按下并松开 B1 多次观察 LED 响应。如果消抖正常每次有效触发只翻转一次不会因按键机械抖动产生多次翻转。测试结果复位后 LD1 保持熄灭无按键时不会误触发按下 B1 瞬间LD1 翻转一次松开 B1 时LD1 状态不变快速连按无重复误翻转20 ms 消抖生效编译、烧录、运行均正常功能正常。6. 小结本实验通过外部中断方式实现了按键控制 LED 状态翻转掌握了 STM32C5 EXTI 外部中断的配置与使用方法。核心逻辑可以概括为“EXTI 边沿触发 → 中断服务 → 回调消抖 → 翻转 LED”。有两点需要注意第一触发边沿的选择。本实验采用上升沿触发中断发生在按键按下瞬间。PC13 外部下拉空闲为低按下为高所以上升沿正好对应按下动作。如果希望松开瞬间触发应改为下降沿Falling edge。第二中断回调中不能用HAL_Delay()。阻塞式延时会导致中断服务程序长时间占用 CPU影响系统实时性。本实验改用HAL_GetTick()时间戳比较实现非阻塞消抖这是中断中处理消抖的标准做法。与上一篇轮询方案相比中断方案由硬件边沿触发响应、主循环保持空闲而轮询方案需要主循环持续读取引脚状态这是两者最本质的技术差异。版权声明欢迎关注 youcansxidian【嵌入式软件AI编程】专栏转发必须注明原文链接【STM32C5教程】4GPIO 外部中断实验Copyright by ai4mcuqq.com 2026Crated2026-10

相关新闻

Datawhale计算机中的数学#MCS #Mathematics #Maths #Yibo #翊博 #翊博在这里 #菲尔兹奖 #yibohere

Datawhale计算机中的数学#MCS #Mathematics #Maths #Yibo #翊博 #翊博在这里 #菲尔兹奖 #yibohere

计算机中的数学 📚 大学数学与工业实践深度解析(Part 1 结课篇)作业: 课后一定要去查阅今年的原论文,并尝试复现。 看不懂原论文,复现不了,对不起。一、 概率论与数理统计(从代码到理…

2026/10/13 3:22:49 阅读更多 →
网络IO与IO多路复用基础(上)

网络IO与IO多路复用基础(上)

网络IO与IO多路复用基础(上)网络IO 作用 : 解决数据的发送与接受总目标 : 实现一个TCPserver有多个client连接并发的传输信息 phase 1 一个server连接一个client 用到的工具 : 基础语法 实现一个简单server// 创建 net IOint sockfd socket(AF_INET, SOCK_STREAM, 0);// 服务器…

2026/10/13 3:22:49 阅读更多 →
langgraph4j原理源码分析图 II图编译

langgraph4j原理源码分析图 II图编译

​​​ 简介 langgraph4j是java技术栈ai agent框架,深入掌握其源码与原理,指导agent的开发,重构/改造框架,增加特性,快速定位和修复bug,发布私有版本 系列内容: > 架构,包括逻辑…

2026/10/13 3:22:49 阅读更多 →

最新新闻

Flask实战:从零搭建在线教育平台的核心实现与避坑指南

Flask实战:从零搭建在线教育平台的核心实现与避坑指南

去年做模拟项目X的时候,接了一个比较完整的活儿:从零搭一个python网络课程在线学习平台。这类项目听起来好像就是“课程列表视频播放”,但真正动手才发现,一个能被老师真正拿去用、学生愿意天天打开的平台,背后牵扯的模…

2026/10/13 4:06:00 阅读更多 →
工业条码打印机与云标签平台协同:标签模板、权限与数据对接的落地实践

工业条码打印机与云标签平台协同:标签模板、权限与数据对接的落地实践

很多人以为标签打印就是把标签纸塞进打印机,点一下打印就完事。真在企业里跑过一轮就明白,事情远没有这么简单:仓库要资产标签、生产线上要料号标签、电商发货要面单和合格证、行政固定资产要贴标……每套标签格式不一样,模板分散…

2026/10/13 4:06:00 阅读更多 →
热电堆太阳总辐射传感器:原理、选型与安装维护全解析

热电堆太阳总辐射传感器:原理、选型与安装维护全解析

聊到太阳总辐射测量,很多人第一反应是“用一个太阳能电池板读数不就行了”。这个想法听起来合理,但在气象观测、光伏电站评估和建筑节能计算这些正儿八经的场合,真正扛大梁的是一支乳白色圆顶的小传感器——热电堆太阳总辐射传感器。它输出只…

2026/10/13 4:06:00 阅读更多 →
Python实现共享单车管理系统:预约调度与路径规划实战

Python实现共享单车管理系统:预约调度与路径规划实战

共享单车管理系统,听起来就是个普通的企业级CRUD项目,但我做完这个项目之后最大的感受是:真正把“预约、报修、调度、线路规划”四个功能串起来做好,远没有表面上那么简单。它的复杂度不在于某个算法有多深,而在于业务…

2026/10/13 4:06:00 阅读更多 →
Linux下Oracle开机自启配置:systemd方案与避坑指南

Linux下Oracle开机自启配置:systemd方案与避坑指南

1. 开机自启这件事,为什么手动能跑通、重启就失效但凡在生产环境部署过Oracle数据库的人,几乎都经历过这个场景:数据库装好了,监听配好了,sqlplus / as sysdba能正常登录,业务跑得也挺稳。结果机房那边通知…

2026/10/13 4:06:00 阅读更多 →
外部AI服务封装为编码助手Skill:网关调度与配额缓存实战

外部AI服务封装为编码助手Skill:网关调度与配额缓存实战

在进行这类封装之前,我建议你先想清楚一个问题:为什么要费力气把一个外部AI服务变成本地编码工具的Skill?单纯为了好看肯定不值得,真正驱动这件事的痛点,大概率是配额不够用、调用不够顺、或者团队里多人共用一套能力时…

2026/10/13 4:04:59 阅读更多 →

日新闻

物联网系统集成避坑指南:从选型到验收的关键要点

物联网系统集成避坑指南:从选型到验收的关键要点

做了这么多年物联网系统集成的项目,我最大的感受是,大部分坑不是出在技术前沿,而是出在一些看起来很平常的地方。设备选了便宜的、协议没问清楚、现场没摸透、验收标准写得含糊——这些细枝末节,最后都会变成延期、超支和扯皮的大…

2026/10/13 0:00:57 阅读更多 →
ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

如果你玩ESP32有一阵子了,很难不碰到舵机控制这道坎。做智能小车要转方向,做机械臂要抬关节,做云台要偏航俯仰,背后都是同一个东西在干活:舵机。而我见过太多人卡在“代码能编译、舵机就是不听话”这个阶段&#xff0c…

2026/10/13 0:00:57 阅读更多 →
CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

1. 为什么CAN总线至今仍是工业现场的“硬通货”?——从汽车底盘到智能温室的真实需求你有没有拆过一辆老款燃油车的中控台?或者调试过某高校实验室里那台跑着Modbus协议却频频丢帧的PLC控制柜?又或者,在某个农业物联网项目里&…

2026/10/13 0:00:57 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/13 2:54:56 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/12 0:16:38 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/13 1:58:08 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 21:05:09 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 14:48:49 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 18:11:17 阅读更多 →