3、GPIO基础与LED控制:学习ESP32的GPIO引脚功能,编写程序控制板载LED闪烁,理解数字输出。
好,咱们开始第三章。这一章我带你上手第一个真正意义上的硬件控制——让LED灯亮起来、灭下去。听起来简单吧?但这里面藏着嵌入式开发最核心的概念:GPIO。
GPIO,全称是General Purpose Input Output,通用输入输出口。说白了,它就是芯片伸出来的一根根“手指头”。你可以命令它输出高电平(3.3V)或者低电平(0V),也可以读取外部信号是高还是低。嗯,就是这么朴实无华,但所有外设控制都靠它。
ESP32的GPIO引脚布局
ESP32芯片有34个GPIO引脚,编号从GPIO0到GPIO33。但要注意,不是所有引脚都能随便用。我在项目中就吃过这个亏——选了个内部已经接Flash的引脚,结果死活拉不高电平。
下面这张表是我整理的常用引脚功能,你最好收藏一下:
| 引脚编号 | 功能说明 | 注意事项 |
|---|---|---|
| GPIO0 | 下载模式选择 | 低电平进入下载模式,慎用 |
| GPIO1 | UART0 TX | 串口输出,调试用 |
| GPIO2 | 板载LED(大部分开发板) | 高电平点亮,低电平熄灭 |
| GPIO3 | UART0 RX | 串口输入 |
| GPIO4-5 | 普通IO | 可安全使用 |
| GPIO6-11 | Flash接口 | 内部已占用,不要用 |
| GPIO12 | 启动电压选择 | 上拉会改变Flash电压,小心 |
数字输出的本质
数字输出,其实就是让引脚输出高电平或低电平。高电平是3.3V,低电平是0V。你想想看,LED灯接在引脚和GND之间,引脚输出高电平,电流流过LED,它就亮了。输出低电平,两边电压一样,没电流,灯就灭了。
为什么会这样?因为LED是个二极管,单向导电。电流只能从正极流向负极。我们控制引脚输出高电平,就相当于给了它一个“正极”。
第一个程序:点亮板载LED
大部分ESP32开发板的板载LED都接在GPIO2上。我个人习惯先写一个最简单的点亮程序,验证硬件是否正常。
来看代码:
// 点亮板载LED
void setup() {
pinMode(2, OUTPUT); // 设置GPIO2为输出模式
digitalWrite(2, HIGH); // 输出高电平,点亮LED
}
void loop() {
// 什么都不做,灯一直亮着
}
这段代码很简单。setup()函数在芯片上电时执行一次,pinMode告诉芯片“这个引脚我要用来输出”,digitalWrite就是实际输出电平。
让LED闪烁起来
点亮只是第一步。闪烁才是真正理解“程序在跑”的感觉。闪烁的本质就是:亮一会儿,灭一会儿,再亮一会儿……循环往复。
代码是这样的:
// LED闪烁程序
void setup() {
pinMode(2, OUTPUT);
}
void loop() {
digitalWrite(2, HIGH); // 点亮
delay(500); // 等待500毫秒
digitalWrite(2, LOW); // 熄灭
delay(500); // 等待500毫秒
}
这里用到了delay()函数。它的单位是毫秒,500就是半秒。你想想看,半秒亮半秒灭,人眼就能看到明显的闪烁效果。
我建议你试试不同的延时值:
- 1000毫秒:一秒一闪,节奏舒缓
- 200毫秒:快速闪烁,像心跳
- 50毫秒:人眼就感觉一直亮着了,这叫“视觉暂留”
理解数字输出的电气特性
嗯,这里要注意一个关键点。ESP32的GPIO输出电流有限,每个引脚最大只能提供12mA左右。直接驱动一个LED没问题,但如果要驱动继电器、电机这类大功率器件,必须加驱动电路。
我曾经在项目里直接拿GPIO去驱动一个5V的蜂鸣器,结果芯片直接重启了。后来查手册才发现,总电流不能超过200mA,单个引脚最好控制在8mA以内。
所以驱动LED时,一定要串联一个限流电阻。一般用220Ω到1kΩ都行。电阻越大,灯越暗,但越安全。
- GPIO是芯片的“手指头”,可以输出高低电平
- 高电平=3.3V,低电平=0V
- pinMode设置模式,digitalWrite输出电平
- delay控制时间,单位毫秒
- 每个引脚输出电流不超过12mA
动手实验:呼吸灯效果
如果你觉得闪烁太简单,咱们来点进阶的——呼吸灯。就是灯从暗到亮,再从亮到暗,像呼吸一样。
这需要用到PWM(脉冲宽度调制)功能。ESP32有专门的LEDC外设来实现PWM。代码稍微复杂一点:
// 呼吸灯效果
int ledPin = 2;
int brightness = 0;
int fadeAmount = 5;
void setup() {
pinMode(ledPin, OUTPUT);
}
void loop() {
analogWrite(ledPin, brightness); // 输出PWM
brightness = brightness + fadeAmount;
if (brightness <= 0 || brightness >= 255) {
fadeAmount = -fadeAmount; // 到达边界就反向
}
delay(30); // 控制呼吸速度
}
这里analogWrite不是真正的模拟输出,而是PWM。它通过快速开关引脚,改变高电平占空比,让人眼感觉亮度变化了。占空比0%就是全灭,100%就是全亮。
常见问题与避坑指南
最后,我总结几个新手最容易踩的坑:
- 引脚没初始化: 忘记写pinMode,直接digitalWrite。这时候引脚可能是输入模式,输出无效。
- 引脚被占用: 用了GPIO6-11,或者GPIO0、GPIO12这些特殊引脚。程序能烧录,但运行不正常。
- 忘记接电阻: 直接驱动LED,电流过大可能烧坏引脚。虽然ESP32有保护,但长期超载会缩短寿命。
- delay阻塞: delay期间CPU啥也干不了。后面学多任务时,我会教你用定时器替代delay。
我曾经有个项目,客户说LED有时候亮有时候不亮。排查了两天,最后发现是GPIO引脚虚焊了。所以硬件问题也要考虑进去,别总盯着代码。
好了,这一章就到这里。你先把闪烁程序跑通,然后试试改延时值,感受一下不同频率的效果。下一章咱们讲GPIO输入——读取按键状态,那才是真正的人机交互入门。