GPIO 基础与数字信号采集

这一章我们聊聊最基础、也最常用的东西——GPIO。说白了,就是芯片的那些引脚怎么用。我见过不少新手,上来就写代码,结果板子烧了还不知道怎么回事。嗯,咱们从根上捋一遍。

GPIO 模式配置:输入与输出

ESP32 的 GPIO 引脚,可以配置成输入,也可以配置成输出。但有个坑——不是所有引脚都能随便用。比如 GPIO6~GPIO11 被内部 Flash 占着,你碰都不能碰。

模式 方向 典型应用 注意事项
GPIO_MODE_OUTPUT 输出 控制 LED、继电器 注意驱动电流,别超过 12mA
GPIO_MODE_INPUT 输入 读取按键、传感器信号 浮空引脚容易误触发
GPIO_MODE_INPUT_OUTPUT 双向 I2C 数据线、单总线 开漏模式需要外部上拉

我个人习惯,配置引脚时一定先看 ESP32 的数据手册。有一次我图省事,直接用了 GPIO2 做输入,结果发现它默认接了板载 LED,电平一直拉高,读到的数据全是 1。折腾了半天才反应过来。

核心原则:输出引脚要限流,输入引脚要防浮空。上拉或下拉电阻不是摆设。

按键消抖:硬件与软件方案

按键按下那一下,你以为是一次干净的电平变化?其实不是。机械触点在闭合的瞬间会弹跳好几次,时间大概 5~20ms。如果不处理,一次按键可能被识别成十几次。

我最早做项目时,直接用 while 循环延时消抖。后来发现,延时期间 CPU 啥也干不了,太浪费了。现在我的做法是——状态机 + 定时器。

硬件消抖

加一个 RC 低通滤波器,电容 0.1μF,电阻 10kΩ。简单粗暴,但有效。不过会增加 BOM 成本,板子空间也占地方。

软件消抖

这是主流做法。核心思路:检测到电平变化后,等 20ms 再读一次,确认电平没变才算有效。

// 简易消抖函数
int debounce_read(gpio_num_t pin) {
    if (gpio_get_level(pin) == 0) {
        vTaskDelay(pdMS_TO_TICKS(20));  // 等 20ms
        if (gpio_get_level(pin) == 0) {
            return 0;  // 确认按下
        }
    }
    return 1;  // 未按下或抖动
}
我的经验:20ms 延时在 FreeRTOS 里用 vTaskDelay,别用 busy-wait。否则高优先级任务会被饿死。

人体红外传感器(PIR)数据读取

人体红外传感器,也叫 PIR 传感器。它检测的是人体发出的红外辐射变化。有人走过时,热释电元件会输出一个脉冲信号。

常用的型号是 HC-SR501。它有三个引脚:VCC、GND、OUT。输出是数字信号——有人就高电平,没人就低电平。

接线方式

  • VCC → 3.3V(注意不是 5V,ESP32 的 GPIO 耐受 3.3V)
  • GND → GND
  • OUT → GPIO4(随便选,避开受限引脚就行)
注意:HC-SR501 默认输出 3.3V,但有些模块输出 5V。如果接到 ESP32 上,必须加电平转换或分压电阻。我曾经直接接上去,烧了一个 GPIO 口,血的教训。

读取逻辑

PIR 输出是数字信号,直接用 GPIO 读就行。但有个细节——传感器上电后有 30~60 秒的稳定期,期间输出不稳定。代码里要加一个初始化延时。

#include "driver/gpio.h"

#define PIR_PIN  GPIO_NUM_4

void pir_init() {
    gpio_set_direction(PIR_PIN, GPIO_MODE_INPUT);
    gpio_set_pull_mode(PIR_PIN, GPIO_PULLDOWN_ONLY);
    vTaskDelay(pdMS_TO_TICKS(60000));  // 等传感器稳定
}

int pir_read() {
    return gpio_get_level(PIR_PIN);  // 1: 有人, 0: 无人
}

你想想看,如果没加这个 60 秒延时,上电后立刻读数据,大概率读到乱跳的电平。很多新手在这里踩坑,以为传感器坏了。

知识结构总览

下面这张图,把 GPIO 配置、按键消抖、PIR 读取串在了一起。你可以把它当作本章的思维导图。

GPIO 数字信号采集知识结构 GPIO 数字信号采集 GPIO 模式配置 输出模式 输入模式 双向模式 按键消抖 硬件消抖(RC) 软件消抖(延时) PIR 传感器读取 硬件接线 初始化延时 电平读取 避坑要点 避开受限引脚(GPIO6~11) | 输入引脚必须上拉/下拉 | PIR 上电后等 60 秒再读

实战建议

如果你刚开始学,我建议你从按键消抖入手。找一块面包板,接一个按键,用示波器看看按下时的波形。亲眼看到那个抖动,比看十遍理论都管用。

PIR 传感器这块,调试时注意环境温度。夏天室温高,人体和环境的温差小,传感器灵敏度会下降。我有个项目在海南测试,大中午的 PIR 死活不触发,后来发现是温差不够。解决办法是调高 HC-SR501 背面的灵敏度旋钮。

调试小技巧:用串口打印 GPIO 电平变化,配合 LED 指示,比纯看代码直观得多。我每次调传感器都这么干。

好了,这一章的内容就这些。GPIO 看似简单,但它是所有外设交互的基础。把这里搞扎实了,后面学 I2C、SPI 会轻松很多。