3、GPIO 基础与 LED 控制:ESP32 引脚功能、数字输出、点亮板载 LED、编写 Blink 程序
好,咱们正式开始动手了。这一章,我带你从最基础的东西开始——GPIO。说白了,就是让芯片的引脚听话,输出高电平或者低电平。你想想看,智能插座的核心不就是控制继电器通断吗?那背后就是 GPIO 在干活。
3.1 ESP32 的引脚功能概览
ESP32 芯片有 34 个 GPIO 引脚,编号从 GPIO0 到 GPIO33。但要注意,不是所有引脚都能随便用。我在项目里就吃过这个亏——选了 GPIO6 去接 LED,结果怎么都不亮,查了半天才发现它被内部 Flash 占用了。
这里我列个常用引脚表,你写代码时对照着看:
| 引脚编号 | 功能说明 | 注意事项 |
|---|---|---|
| GPIO0 | 普通 IO / 启动模式选择 | 低电平进入下载模式,慎用 |
| GPIO1 | UART0 TX(调试串口) | 用作普通 IO 时会影响串口输出 |
| GPIO2 | 普通 IO / 板载 LED | 大部分开发板板载 LED 接这个脚 |
| GPIO3 | UART0 RX(调试串口) | 同上,慎用 |
| GPIO4 | 普通 IO | 常用,无特殊限制 |
| GPIO5 | 普通 IO | 常用,无特殊限制 |
| GPIO6~GPIO11 | 连接内部 Flash | 不要用于普通 IO! |
| GPIO12 | 普通 IO / 电压选择 | 上电时高电平会降低 Flash 电压,小心 |
| GPIO13~GPIO19 | 普通 IO | 大部分可用,注意 GPIO14 是 JTAG 相关 |
| GPIO21~GPIO23 | 普通 IO | 常用,无特殊限制 |
| GPIO25~GPIO27 | 普通 IO / DAC | 也可用作模拟输出 |
| GPIO32~GPIO33 | 普通 IO | 常用,无特殊限制 |
3.2 数字输出:让引脚输出高/低电平
GPIO 的数字输出,说白了就是让引脚输出 3.3V(高电平)或者 0V(低电平)。在 Arduino 框架下,只需要两个函数:
pinMode(pin, OUTPUT)—— 把引脚设置为输出模式digitalWrite(pin, HIGH/LOW)—— 输出高电平或低电平
嗯,就这么简单。但有个细节我想提醒你:ESP32 的 GPIO 输出电流有限,大概 40mA 左右。直接驱动 LED 没问题,但要是想驱动继电器或者电机,必须加三极管或者 MOS 管驱动。我刚开始做智能插座时,直接拿 GPIO 去推继电器,结果芯片烧了……
3.3 点亮板载 LED
大部分 ESP32 开发板(比如 NodeMCU-32S、ESP32-DevKitC)都有一颗板载 LED,通常接在 GPIO2 上。这颗 LED 是低电平点亮,也就是说:
digitalWrite(2, LOW)—— LED 亮digitalWrite(2, HIGH)—— LED 灭
为什么会这样?因为厂家设计时,LED 的正极通过电阻接了 3.3V,负极接到 GPIO2。GPIO 输出低电平时,电流从 3.3V 流过 LED 再到 GPIO,LED 就亮了。你想想看,这其实挺常见的——很多开发板都这么干。
不过,不同开发板的板载 LED 引脚可能不一样。有的接 GPIO2,有的接 GPIO16,甚至有的接 GPIO5。我建议你拿到板子后,先查一下原理图或者看板子上的丝印。实在不行,拿万用表量一下——这是我个人的习惯,稳当。
3.4 编写 Blink 程序
好,咱们直接上代码。Blink 程序就是让 LED 一亮一灭,循环往复。这是嵌入式世界的 "Hello World"。
// Blink 程序 —— 点亮板载 LED
// 适用于大部分 ESP32 开发板
#define LED_PIN 2 // 板载 LED 通常接 GPIO2
void setup() {
pinMode(LED_PIN, OUTPUT); // 设置引脚为输出模式
}
void loop() {
digitalWrite(LED_PIN, LOW); // 点亮 LED(低电平有效)
delay(1000); // 等待 1 秒
digitalWrite(LED_PIN, HIGH); // 熄灭 LED
delay(1000); // 等待 1 秒
}
这段代码的逻辑很简单:
setup()里设置引脚模式,只执行一次。loop()里不断循环:亮 1 秒,灭 1 秒。delay(1000)就是让程序暂停 1000 毫秒。
你上传代码后,如果看到板载 LED 以 1 秒为周期闪烁,那就说明成功了。如果没亮,先检查一下 LED 引脚对不对。我遇到过好几次,学生拿着 GPIO2 的代码往 GPIO16 的板子上烧,结果跑来问我为什么灯不亮……
3.5 扩展:控制外部 LED
板载 LED 玩熟了,咱们试试外接 LED。你需要准备:
- 一个 LED(颜色随意,我习惯用红色)
- 一个 220Ω 电阻(限流用,别省)
- 两根杜邦线
接线方式:
- LED 长脚(正极)接 220Ω 电阻,电阻另一端接 GPIO4
- LED 短脚(负极)接 GND
代码只需要改一行:把 LED_PIN 从 2 改成 4。注意,外部 LED 是高电平点亮,所以 digitalWrite(4, HIGH) 是亮,LOW 是灭。
#define LED_PIN 4 // 外部 LED 接 GPIO4
void setup() {
pinMode(LED_PIN, OUTPUT);
}
void loop() {
digitalWrite(LED_PIN, HIGH); // 点亮(高电平有效)
delay(500);
digitalWrite(LED_PIN, LOW); // 熄灭
delay(500);
}
你看,代码几乎一样,只是引脚号和电平逻辑变了。这就是 GPIO 的灵活性——同一个函数,换个引脚就能控制不同的设备。
#define 或者 const int。这样以后改硬件时,只需要改一行,不用满篇找数字。这个习惯帮我省了不少事。
3.6 本章小结
这一章咱们干了三件事:
- 搞清楚了 ESP32 哪些引脚能用,哪些是坑
- 学会了用
pinMode和digitalWrite控制数字输出 - 亲手写了一个 Blink 程序,让 LED 闪了起来
嗯,别小看这个 Blink。它背后藏着嵌入式开发的核心逻辑:初始化硬件、循环执行任务、控制外设。咱们后面做智能插座,无非是把 LED 换成继电器,把延时换成定时器,把手动控制换成远程指令——本质是一样的。
下一章,咱们会深入按键输入和中断。到时候你就能用按键控制 LED 了,那才是真正的交互。先把这个 Blink 跑通,咱们下章见。