2. GPIO基础与LED控制:数字输出、GPIO库函数、LED闪烁、呼吸灯效果实现
各位同学,欢迎来到第二章。这一章我们直接上手硬件控制——GPIO。说白了,就是让ESP32的引脚听话,输出高电平或低电平,去点亮或熄灭一个LED。
我刚开始学单片机时,第一个实验就是点灯。别小看这个动作,它背后藏着数字输出的全部逻辑。你搞懂了GPIO,后面控制继电器、蜂鸣器、电机,甚至通信协议,都是这个思路的延伸。
2.1 什么是GPIO?
GPIO,全称General-Purpose Input/Output,通用输入输出口。你可以把它想象成芯片伸出来的“触手”。
- 输出模式:芯片主动拉高(3.3V)或拉低(0V),驱动外部设备。
- 输入模式:读取外部电平,比如按键按下还是松开。
ESP32有34个GPIO引脚,但不是所有引脚都能随便用。有些引脚内部接了Flash,有些有特殊功能。我踩过这个坑——第一次用GPIO6去点灯,死活不亮,查了半天才发现它被Flash占用了。
2.2 数字输出:点亮一个LED
先看最简单的电路。一个LED,一个220Ω限流电阻,串联到GPIO和GND之间。LED长脚接GPIO,短脚接电阻再到GND。
代码怎么写?我习惯用Arduino框架,因为上手快,生态好。ESP-IDF当然也行,但咱们课程先以Arduino为主,后面再深入IDF。
// 点亮LED示例
#define LED_PIN 2 // 大多数ESP32开发板,板载LED接在GPIO2
void setup() {
pinMode(LED_PIN, OUTPUT); // 设置引脚为输出模式
digitalWrite(LED_PIN, HIGH); // 输出高电平,LED亮
}
void loop() {
// 什么都不做,LED一直亮
}
这里有两个核心函数:pinMode() 和 digitalWrite()。前者配置引脚方向,后者设置电平状态。HIGH是3.3V,LOW是0V。
2.3 GPIO库函数详解
Arduino框架的GPIO函数不多,但每个都很重要。我整理了一张表,方便你对照查阅。
| 函数 | 功能 | 参数说明 |
|---|---|---|
pinMode(pin, mode) |
设置引脚模式 | mode: OUTPUT, INPUT, INPUT_PULLUP, INPUT_PULLDOWN |
digitalWrite(pin, value) |
输出数字电平 | value: HIGH (3.3V) 或 LOW (0V) |
digitalRead(pin) |
读取引脚电平 | 返回 HIGH 或 LOW |
analogWrite(pin, value) |
输出PWM模拟信号 | value: 0-255(ESP32需用ledc库) |
注意最后一行。ESP32的analogWrite()和Arduino Uno不一样,它底层用的是LEDC(LED Control)外设。我们做呼吸灯时会详细讲。
2.4 LED闪烁:经典入门实验
闪烁就是让LED亮一段时间,灭一段时间,循环往复。核心是delay()函数,但我要提醒你——delay会阻塞程序,后面学多任务时你就知道它的坏处了。不过初学阶段,先用它理解逻辑。
#define LED_PIN 2
void setup() {
pinMode(LED_PIN, OUTPUT);
}
void loop() {
digitalWrite(LED_PIN, HIGH); // 亮
delay(500); // 保持500ms
digitalWrite(LED_PIN, LOW); // 灭
delay(500); // 保持500ms
}
上传代码后,LED会以1秒周期闪烁(0.5秒亮,0.5秒灭)。你可以改delay的值,调整闪烁频率。
2.5 呼吸灯效果:PWM与LEDC
呼吸灯,就是LED从暗到亮,再从亮到暗,像呼吸一样平滑变化。这需要PWM(脉冲宽度调制)。
PWM的原理很简单:快速切换高低电平,通过改变高电平占整个周期的比例(占空比),来模拟不同的电压。占空比0%就是灭,100%就是最亮,50%就是半亮。
ESP32用LEDC外设实现PWM。它比Arduino Uno的analogWrite()灵活得多——你可以设置频率、分辨率、通道数。
#define LED_PIN 2
#define LEDC_CHANNEL 0
#define LEDC_RESOLUTION 8 // 8位分辨率,占空比0-255
#define LEDC_FREQ 5000 // 5kHz PWM频率
void setup() {
ledcSetup(LEDC_CHANNEL, LEDC_FREQ, LEDC_RESOLUTION);
ledcAttachPin(LED_PIN, LEDC_CHANNEL);
}
void loop() {
// 从暗到亮
for (int dutyCycle = 0; dutyCycle <= 255; dutyCycle++) {
ledcWrite(LEDC_CHANNEL, dutyCycle);
delay(5);
}
// 从亮到暗
for (int dutyCycle = 255; dutyCycle >= 0; dutyCycle--) {
ledcWrite(LEDC_CHANNEL, dutyCycle);
delay(5);
}
}
这段代码里,ledcSetup()配置PWM参数,ledcAttachPin()把通道绑定到引脚,ledcWrite()设置占空比。两个for循环分别实现渐亮和渐暗,delay(5)控制变化速度。
2.6 本章知识结构图
下面这张SVG图,把本章的核心知识点串起来了。从GPIO基础出发,分支出数字输出和PWM输出两条线,最后汇聚到LED控制这个实战目标。
2.7 常见问题与调试技巧
写代码容易,调硬件难。我总结几个新手常遇到的问题,你遇到了可以对照排查。
- LED不亮:先检查接线,正负极有没有反?电阻有没有接?再用万用表量GPIO引脚电压,如果没输出,检查代码里引脚号对不对。
- LED微亮但不闪烁:可能是引脚模式没设对,或者代码里只写了一次digitalWrite,没有在loop里切换。
- 呼吸灯闪烁不均匀:PWM频率太低。LEDC频率建议设在1kHz以上,人眼就感觉不到闪烁了。
- 上传失败:按住开发板上的BOOT键,再点上传。ESP32进入下载模式需要这个操作。
好了,这一章的内容就到这里。你学会了GPIO的数字输出和PWM输出,从简单的点灯到呼吸灯,算是迈出了硬件控制的第一步。这些基础打牢了,后面学传感器读取、外设驱动就会轻松很多。