GPIO基础与LED控制:数字输出、GPIO模式配置、LED闪烁实验、PWM调光原理
各位同学,欢迎来到第二章。上一章我们把ESP32的开发环境搭好了,也跑了第一个Hello World。这一章咱们来点看得见摸得着的东西——控制LED。
别小看LED,它背后藏着嵌入式开发最核心的概念:GPIO。说白了,GPIO就是芯片伸出来的那些“手脚”,你可以让它们输出高电平、低电平,或者读取外部信号。我做了这么多年硬件,可以说90%的传感器交互,底层都是GPIO在干活。
2.1 认识ESP32的GPIO
ESP32有34个GPIO引脚,但不是所有引脚都能随便用。嗯,这里要注意:有些引脚有特殊功能,比如接Flash、接晶振,你拿来当普通IO用可能会出问题。
| 引脚范围 | 可用性 | 注意事项 |
|---|---|---|
| GPIO0-19 | 大部分可用 | GPIO6-11用于Flash,不建议使用 |
| GPIO21-23 | 完全可用 | 常用作I2C、SPI |
| GPIO25-27 | 完全可用 | 内置DAC,也可做普通IO |
| GPIO32-39 | 完全可用 | GPIO34-39只能输入,不能输出 |
我个人习惯,做实验时优先用GPIO2、GPIO4、GPIO5、GPIO18、GPIO19这几个。它们没有特殊限制,接个LED、按键什么的很稳。
2.2 数字输出与GPIO模式配置
要让GPIO输出高低电平,你得先做两件事:
- 设置引脚模式:告诉芯片这个引脚是输出还是输入。
- 写入电平值:输出高电平(3.3V)或低电平(0V)。
在Arduino框架下,代码极其简单:
void setup() {
pinMode(2, OUTPUT); // 设置GPIO2为输出模式
digitalWrite(2, HIGH); // 输出高电平,LED亮
}
void loop() {
// 暂时空着
}
你想想看,这背后芯片干了什么?它其实配置了GPIO内部的推挽输出电路。高电平时,上拉MOS管导通,引脚被拉到VCC;低电平时,下拉MOS管导通,引脚被拉到GND。
#define LED_PIN 2,后期改硬件时改一行就行。
2.3 LED闪烁实验
闪烁实验就是让LED交替亮灭。核心逻辑是:输出高电平→延时→输出低电平→延时→循环。
代码示例:
#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
}
上传到ESP32,你应该能看到板载LED(通常接GPIO2)以0.5秒间隔闪烁。
2.4 从闪烁到呼吸:PWM调光原理
闪烁实验只能让LED全亮或全灭。那怎么让LED半亮呢?你可能会想:输出一个中间电压,比如1.65V。但ESP32的数字GPIO只能输出0V或3.3V,没有中间值。
这时候就要请出PWM了。
PWM(脉冲宽度调制),说白了就是快速开关。开关速度快到人眼反应不过来,LED看起来就像在“半亮”。
PWM有三个关键参数:
| 参数 | 说明 | 常见值 |
|---|---|---|
| 频率 | 每秒开关次数 | 5000Hz(5kHz) |
| 占空比 | 高电平时间占整个周期的比例 | 0%~100% |
| 分辨率 | 占空比可调节的精细程度 | 8位(0-255)或16位(0-65535) |
举个例子:频率5000Hz,周期就是200微秒。如果占空比50%,就是高电平100微秒、低电平100微秒。人眼看到的亮度大约是最大亮度的一半。
ESP32的PWM实现代码:
#define LED_PIN 2
#define PWM_CH 0 // PWM通道
#define PWM_FREQ 5000 // 5kHz
#define PWM_RES 8 // 8位分辨率
void setup() {
ledcSetup(PWM_CH, PWM_FREQ, PWM_RES);
ledcAttachPin(LED_PIN, PWM_CH);
}
void loop() {
// 从暗到亮
for (int duty = 0; duty <= 255; duty++) {
ledcWrite(PWM_CH, duty);
delay(5);
}
// 从亮到暗
for (int duty = 255; duty >= 0; duty--) {
ledcWrite(PWM_CH, duty);
delay(5);
}
}
这段代码会让LED像呼吸一样慢慢变亮再慢慢变暗,这就是“呼吸灯”效果。
2.5 本章知识体系
下面这张图把本章的核心逻辑串起来了:
这张图把本章内容分成了两条主线:左边是数字输出,右边是PWM输出。数字输出只能控制亮灭,PWM能控制亮度。两条线最终都服务于同一个目标——控制LED。
2.6 动手实验:组合挑战
学完理论,我建议你动手做个小实验:用两个LED,一个做闪烁(数字输出),一个做呼吸(PWM输出)。看看它们同时运行的效果。
接线图很简单:
- LED1:正极接GPIO2(串220Ω电阻),负极接GND
- LED2:正极接GPIO4(串220Ω电阻),负极接GND
代码思路:
#define LED_BLINK 2
#define LED_BREATHE 4
#define PWM_CH 0
#define PWM_FREQ 5000
#define PWM_RES 8
void setup() {
pinMode(LED_BLINK, OUTPUT);
ledcSetup(PWM_CH, PWM_FREQ, PWM_RES);
ledcAttachPin(LED_BREATHE, PWM_CH);
}
void loop() {
// LED1闪烁
digitalWrite(LED_BLINK, HIGH);
delay(300);
digitalWrite(LED_BLINK, LOW);
delay(300);
// LED2呼吸一次
for (int d = 0; d <= 255; d++) {
ledcWrite(PWM_CH, d);
delay(3);
}
for (int d = 255; d >= 0; d--) {
ledcWrite(PWM_CH, d);
delay(3);
}
}
好了,这一章的内容就到这里。GPIO是嵌入式开发的基石,数字输出和PWM是控制外设最常用的两种手段。你把这些搞明白了,后面接传感器、控制电机都会轻松很多。