☰
6.STM32 GPIO 输入功能与按键消抖实战详解
2026/10/18 6:54:49 网站建设 项目流程

目录

  • 一、GPIO输入功能
  • 二、IO框图分析
    • a)框图分析
    • b)输入模式分类
  • 三、相关寄存器
    • 1.此处图片基于PD8引脚分析
    • 2.输入数据寄存器(IDR)框图
    • 3.端口输入数据寄存器配置方式
  • 四、程序编写
    • 生成代码简述:
      • 对地址进行宏定义
      • 按键初始化
      • 按键控制LED亮灭
      • 按了一下,keylog进位很多,表示按键检测进了很多次
      • 按键抖动原理

摘要:本文以 STM32 的 GPIO 输入功能为主线,从电平识别的基本原理出发,结合 IO 框图分析输入模式的分类,并讲解相关寄存器(ODR、IDR)的配置方式。随后通过按键控制 LED 亮灭的完整实战,介绍按键初始化、代码生成与调试过程,重点剖析按键抖动产生的原因,并对比硬件消抖与软件消抖的区别,详细说明延时消抖为何能有效去除抖动,帮助读者掌握 GPIO 输入与按键消抖的完整开发思路。

一、GPIO输入功能

1.什么作用:

比如说按下按键,引脚根据外部电路读取输入的是高/低电平;

TTL 在 STM32 内高电平 3.3V,低电平是 0V

识别的是电平信号的有和没有

二、IO框图分析

a)框图分析

b)输入模式分类

模拟输入

上拉输入

下拉输入

浮空输入

复用功能输入

三、相关寄存器

1.此处图片基于PD8引脚分析

PD8属于高位寄存器(引脚号8-15);

配置上下拉输入模式时,这两块是连在一起的;如果只配置高寄存器是不对的,还需要参考数据手册上其他内容;

根据端口位配置表:上下拉输入配置与PxODR寄存器有关;

找到对应端口的ODR寄存器,并为其置一操作就能实现上拉输入的配置;

此时才算配置为上拉输入;

2.输入数据寄存器(IDR)框图

便于理解,下方附上输入数据寄存器(IDR)框图

3.端口输入数据寄存器配置方式

四、程序编写

  • 按键控制灯亮灭

按键 PA0 低电平有效,LED 灯是 PC13

安装依赖包(记得 Keil 也需要安)

  • 选择型号

  • 配置烧录引脚及输入输出模式

  • 配置初始化功能

生成代码简述:

对地址进行宏定义

按键初始化

声明全局变量(用于检测按键抖动次数,在软件调试时便于观察按下次数与实际次数是否相等)

按键控制LED亮灭

if((KEY_GPIO_Port->IDR &(1<<0)) == 0) { HAL_Delay(100); if((KEY_GPIO_Port->IDR &(1<<0)) == 1){ if(keylog < 250){ keylog++; }else{ keylog = 0; } } LED_GPIO_Port->BSRR = (1<<13); } else { LED_GPIO_Port->ODR &= ~(1<<13); }

按了一下,keylog进位很多,表示按键检测进了很多次

按键抖动原理

按键抖动波形示意图:

理想情况下,按下按键时电平会瞬间从高电平跳变为低电平(低电平有效);但实际由于机械触点的弹性,按下瞬间电平会在高、低之间快速来回跳变数次,持续约 5~20ms 后才稳定为低电平。松开按键时同样会出现反向的抖动过程。这种在稳定电平出现之前的高频跳变,就是按键抖动。

硬件消抖与软件消抖的区别:

  • 硬件消抖:在按键引脚外部增加 RC 滤波电路(电阻 + 电容)或使用 RS 触发器、施密特触发器,利用电容的充放电特性吸收电平的快速跳变,从物理层面把抖动信号平滑掉。优点是消抖实时、不占用 CPU 时间;缺点是需要额外元器件,增加电路成本和 PCB 面积。
  • 软件消抖:不增加任何硬件,在程序中通过延时、循环检测或定时器扫描等方式,跳过按键按下瞬间的抖动区间,只认稳定后的电平。优点是零成本、修改灵活;缺点是会占用一定的 CPU 时间,且延时期间无法响应其他任务。

为什么延时消抖能有效去除抖动:

按键抖动只发生在按下或松开的瞬间,持续时间通常只有几毫秒到二十毫秒。延时消抖的思路是:第一次检测到按键电平变化后,不立即采信,而是先延时一段时间(例如 HAL_Delay(100),即 100ms),等抖动完全结束、电平稳定之后,再读取一次引脚电平。如果第二次读取到的电平与第一次一致,说明确实是有效按键,而不是抖动产生的毛刺,此时才执行按键对应的操作。这样就把抖动期间那些不稳定的电平跳变全部过滤掉了,从而保证一次按键只被识别一次。

  • 消抖后程序

延时消抖

  • 抬手监测消抖
if((KEY_GPIO_Port->IDR &(1<<0))==0) { HAL_Delay(100); if((KEY_GPIO_Port->IDR &(1<<0))==1) { LED_GPIO_Port->BSRR=(1<<13); } }else{ LED_GPIO_Port->ODR &=~(1<<13); }
if((KEY_GPIO_Port->IDR &(1<<0))==0) { HAL_Delay(100); if((KEY_GPIO_Port->IDR &(1<<0))==1) { LED_GPIO_Port->BSRR=(1<<13); } }else{ LED_GPIO_Port->ODR &=~(1<<13); }
  • 库函数方式
if(HAL_GPIO_ReadPin(KEY_GPIO_Port,KEY_Pin)==GPIO_PIN_RESET) { HAL_Delay(100); if(HAL_GPIO_ReadPin(KEY_GPIO_Port,KEY_Pin)==GPIO_PIN_RESET) { HAL_GPIO_TogglePin(LED_GPIO_Port,LED_Pin); } }
GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) { GPIO_PinState bitstatus; /* Check the parameters */ assert_param(IS_GPIO_PIN(GPIO_Pin));//检查是否合法 //PA0 GPIO_Pin=GPIO_PIN_0 也就是第0位为1 if((GPIOx->IDR & GPIO_Pin) != (uint32_t)GPIO_PIN_RESET)//如果不等于0 { bitstatus = GPIO_PIN_SET;//返回1 } else { bitstatus = GPIO_PIN_RESET;//返回0 } return bitstatus; }

五、总结

本文围绕 STM32 的 GPIO 输入功能,从电平识别、IO 框图、寄存器配置到按键实战,完整梳理了输入开发的核心链路。下面概括关键要点,并补充常见问题与调试建议。

核心要点

  • GPIO 输入功能:引脚根据外部电路读取高/低电平,STM32 内高电平为 3.3V,低电平为 0V,本质是识别电平信号的有和无。
  • 输入模式分类:包括模拟输入、上拉输入、下拉输入、浮空输入和复用功能输入。配置上下拉输入时,需要结合 PxODR 寄存器置一操作,才能正确实现上拉输入。
  • 寄存器配置:输入数据寄存器(IDR)用于读取引脚电平;配置上下拉输入时,高位寄存器与低位寄存器需要配合处理,并参考数据手册确认 ODR 寄存器的设置。
  • 按键消抖:机械按键按下瞬间会产生 5~20ms 的电平抖动。硬件消抖通过 RC 滤波或触发器从物理层面平滑信号;软件消抖通过延时、循环检测或定时器扫描跳过抖动区间。延时消抖的核心思路是第一次检测到电平变化后先延时,待电平稳定后再读取一次,两次一致才认定为有效按键。

常见问题与调试建议

  • 按键检测次数异常:按下一次 keylog 进位很多,说明没有消抖或消抖不充分,抖动被误判为多次按键。建议在检测到电平变化后加入 HAL_Delay(100) 延时,再二次确认电平状态。
  • 上拉输入配置无效:只配置高位寄存器往往不够,需要同时确认对应端口的 ODR 寄存器并置一,才能正确实现上拉输入。
  • 电平读取不稳定:检查外部电路是否接好上下拉电阻,确认引脚模式与外部电路匹配,避免浮空输入导致电平不确定。
  • 延时消抖影响响应:延时期间 CPU 被占用,若对实时性要求较高,可改用定时器扫描或状态机消抖,避免阻塞其他任务。
  • 调试建议:通过全局变量 keylog 观察按键按下次数,与实际按键次数对比,可快速判断消抖是否生效;同时结合示波器观察引脚波形,确认抖动区间和稳定电平。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询