2. GPIO 中断概述:中断的作用、与轮询方式的对比、应用场景分析

在嵌入式系统中,GPIO(通用输入输出)引脚是微控制器与外界交互的最基本接口。当我们需要检测外部事件(如按键按下、传感器信号跳变、编码器脉冲)时,有两种主要的处理方式:轮询(Polling) 和 中断(Interrupt)。本章将深入剖析 GPIO 中断的核心作用,并通过对比与场景分析,帮助您理解为何中断是现代嵌入式系统设计的基石。

2.1 什么是 GPIO 中断?

GPIO 中断是一种硬件机制,允许微控制器在 GPIO 引脚上检测到特定事件(如电平变化、上升沿、下降沿)时,暂停当前正在执行的主程序,自动跳转到预先定义好的中断服务函数(ISR, Interrupt Service Routine)中执行处理逻辑,处理完成后返回主程序继续执行。

核心特征: 中断是事件驱动的,CPU 只在事件发生时介入,无需持续占用 CPU 资源进行查询。
GPIO 中断触发与处理流程 主程序循环 GPIO 中断事件 (边沿/电平触发) CPU 响应中断 中断服务函数 (ISR) 清除中断标志 / 处理事件 中断返回 说明:中断发生时,CPU 自动保存现场(PC、寄存器),跳转至 ISR,执行完毕后恢复现场并返回主程序断点处继续执行。

2.2 中断 vs 轮询:核心差异对比

轮询方式是指 CPU 在主循环中周期性地读取 GPIO 引脚电平,判断是否发生变化。下表从多个维度对比两种方式的优劣:

对比维度 轮询(Polling) 中断(Interrupt)
CPU 利用率 低效:CPU 被持续占用,即使无事件也要不断查询 高效:CPU 仅在事件发生时介入,其余时间可执行其他任务或进入低功耗模式
实时性 差:响应延迟取决于轮询周期,事件可能被错过(尤其短脉冲) 强:硬件触发,响应延迟通常为微秒级(取决于中断优先级和上下文切换)
功耗 高:CPU 必须保持活跃,无法深度睡眠 低:CPU 可进入睡眠模式,中断唤醒后处理事件
代码复杂度 低:简单的循环读取 + 判断逻辑 中等:需配置中断控制器、编写 ISR、处理临界区与重入问题
适用场景 事件频率极高、延迟要求宽松、系统简单 事件随机、低延迟要求、低功耗需求、多任务系统
关键陷阱: 轮询方式在处理 短脉冲信号(如编码器单步脉冲、红外接收头输出)时极易丢失事件。例如,一个 10 µs 的低电平脉冲,如果轮询周期为 100 µs,则几乎不可能被检测到。中断则能可靠捕获。

2.3 应用场景分析

GPIO 中断在嵌入式产品中无处不在。以下列出典型场景,帮助您建立直觉:

  • 按键/矩阵键盘检测: 使用下降沿或低电平中断,避免主循环持续扫描,实现按键唤醒与防抖处理。
  • 编码器脉冲计数: 使用双边沿中断(上升沿+下降沿)捕获电机或旋钮的精确位置变化,实现 4 倍频计数。
  • 传感器信号跳变: 如霍尔传感器、光电门、流量计脉冲输出,中断触发后立即累计计数值。
  • 通信协议辅助: 如 1-Wire、红外 NEC 协议,利用 GPIO 中断测量脉冲宽度,实现软件解码。
  • 唤醒源: 在低功耗产品中,GPIO 中断(通常为电平变化)可将 MCU 从 STOP/STANDBY 模式唤醒。
  • 故障检测与保护: 过流、过温信号通过 GPIO 中断快速触发,执行紧急关断逻辑。
GPIO 中断典型应用场景架构 微控制器 (MCU) GPIO 中断控制器 按键 / 键盘 下降沿 / 低电平 旋转编码器 双边沿触发 脉冲传感器 上升沿计数 低功耗唤醒 电平变化唤醒 故障保护 紧急关断 协议解码 脉冲宽度测量 所有外部事件通过 GPIO 引脚触发中断,MCU 在 ISR 中完成对应处理,无需轮询。

2.4 中断触发类型:边沿 vs 电平

GPIO 中断的触发条件分为两大类,理解其差异是配置正确的前提:

触发类型 触发条件 典型应用 注意事项
上升沿触发 引脚电平从低到高跳变瞬间 按键释放检测、正脉冲捕获 对毛刺敏感,需硬件去抖或软件滤波
下降沿触发 引脚电平从高到低跳变瞬间 按键按下检测、负脉冲捕获 同上,需注意信号完整性
双边沿触发 上升沿或下降沿均触发 编码器计数、频率测量 中断频率可能翻倍,ISR 需高效
高电平触发 引脚电平为高且持续 唤醒源、电平状态检测 电平未恢复时可能持续触发(需硬件配合)
低电平触发 引脚电平为低且持续 按键按下唤醒、故障信号 同上,需注意电平保持时间
实战建议: 对于机械按键,推荐使用 下降沿触发 + 软件去抖(延迟 10-20 ms 后再次读取电平确认)。对于传感器脉冲,优先使用 边沿触发,避免电平触发在信号抖动时产生大量冗余中断。

2.5 中断优先级与嵌套

现代 MCU 的中断控制器(如 NVIC)支持多级优先级配置。当多个 GPIO 中断同时发生时,优先级高的中断会优先执行;高优先级中断可以抢占正在执行的低优先级中断(中断嵌套)。

  • 抢占优先级: 决定是否打断当前 ISR。
  • 子优先级: 当抢占优先级相同时,决定 ISR 的执行顺序。
  • 注意事项: ISR 应尽量短小精悍,避免在 ISR 中执行耗时操作(如 printf、延时循环),否则会阻塞其他中断和主程序。