ESP32 使用PWM控制板载的LED实现呼吸效果
目录
凌顺实验室(lingshunlab.com)分享如何在 ESP32 SoC 中使用 PWM。
PWM可用控制LED的亮度,舵机的角度,直流电机的速度等等。
ESP32 LED PWM 控制器 (LEDC)
ESP32 的 LEDC 外设由 16 个 PWM 通道组成,能够生成独立的波形,主要用于 RGB LED 控制,但也可用于其他目的。关于 ESP32 中的 LED PWM 控制器,您应该注意几个有趣的点。
- 16 个独立 PWM 通道,分为两组,每组 8 个通道。
- 1 位和 16 位之间的可编程分辨率。
- PWM波的频率取决于PWM的分辨率。
- 自动增加/减少占空比,无需处理器干预。
但在ESP32中使用PWM,并不像Arduino开发板的那么简单。需要一些配置才能生效。
配置ESP32的PWM通道
在Arduino 编程中的使用“analogWrite()”函数即可生成PWM信号。而 ESP32 的 LED PWM 中的几乎所有内容都是需要用户配置的(通道、分辨率和频率),因此我们将使用一组不同的(且专用的)函数来配置 ESP32 中的 PWM,而不是使用“analogWrite()”函数。
以下是驱动程序公开的所有 LEDC API 的列表。这些函数是为 ESP32 的 Arduino IDE 端口编写的。
- ledcSetup(通道、频率、分辨率位);
- ledcAttachPin(引脚,通道);
- ledcWrite(通道,占空比);
- ledcRead(通道);
- ledcWriteTone(通道,频率)
- ledcWriteNote(通道、音符、八度);
- ledcReadFreq(通道);
- ledcDetachPin(引脚);
在 8 个函数中,我们将重点关注前三个,因为它们对于生成 PWM 更有用(也是最低要求)。
在 ESP32 中配置 PWM 通道时需要记住的一些要点:
- 由于有 16 个 PWM 通道,因此“通道”参数可以采用 0 到 15 之间的任意值。
- 接下来是 PWM 信号的频率。您可以根据需要设置频率,例如 1 KHz、5 KHz、8 KHz 和 10 KHz。
- PWM 的分辨率也是可配置的,ESP32 PWM 可以在 1 位到 16 位分辨率之间的任何位置进行编程。
- PWM 频率和分辨率成反比,并且取决于时钟源。因此,选择频率和分辨率值时要小心。
- 最后,为 PWM 输出分配 GPIO 引脚。您可以分配任何 GPIO 引脚,但分配时要小心(不要使用已经使用的 GPIO 引脚,如UART、SPI 等)。
下表显示了一些常用的 PWM 频率和分辨率。
LEDC 时钟源 | LEDC 脉宽调制频率 | 脉宽调制分辨率 |
---|---|---|
80 MHz APB_CLK | 1KHz | 16位 |
80 MHz APB_CLK | 5KHz | 14位 |
80 MHz APB_CLK | 10KHz | 13位 |
8 MHz RTC8M_CLK | 1KHz | 13位 |
8 MHz RTC8M_CLK | 8KHz | 10位 |
1 MHz REF_Tick | 1KHz | 10位 |
实现效果
本次实验将使用的ESP32开发板上的LED灯作为受PWM控制的LED灯,从而实现呼吸的效果。
所以请确保你的ESP32开发板上有LED灯,并且可通过GPIO 2控制
BOM表
- ESP32 x1
(需要开发板上有LED灯,并且受GPIO 2控制)
程序代码
// welcome to lingshunlab.com
const int LEDPin = 2; /* GPIO16 */
int dutyCycle;
/* Setting PWM Properties */
const int PWMFreq = 5000; /* 5 KHz */
const int PWMChannel = 0;
const int PWMResolution = 10;
const int MAX_DUTY_CYCLE = (int)(pow(2, PWMResolution) - 1);
void setup()
{
// 配置PWM通道,频率,分辨率
ledcSetup(PWMChannel, PWMFreq, PWMResolution);
// 把配置好的PWM通道,分配引脚
ledcAttachPin(LEDPin, PWMChannel);
}
void loop()
{
// 用PWM增加LED亮度
for(dutyCycle = 0; dutyCycle <= MAX_DUTY_CYCLE; dutyCycle++)
{
ledcWrite(PWMChannel, dutyCycle);
delay(3);
}
// 用PWM降低LED亮度
for(dutyCycle = MAX_DUTY_CYCLE; dutyCycle >= 0; dutyCycle--)
{
ledcWrite(PWMChannel, dutyCycle);
delay(3);
}
}
在ESP32 中 PWM 的重要特性之一是所有 16 个通道都可以独立配置,即每个通道可以有自己的分辨率和频率。