8. PWM
1. BiBoard(ESP32)PWM功能简介
BiBoard使用的ESP32和UNO用的328P有所不同。ESP32的PWM因为使用了矩阵总线的缘故,可以使用在非特定的引脚上。
ESP32的PWM被称作LED控制器(LEDC),LED PWM 控制器主要用于控制 LED,也可产生 PWM 信号用于其他设备的控制。该控制器有 8个定时器,对应8个高速通道和8个低速通道,合计16通道。

相比UNO直接使用“analogWrite()” 输入0-255之间任意的占空比。BiBoard上ESP32的PWM控制要略麻烦一些。需要控制的参数如下:
人工选择PWM通道(0-15),也提高了引脚的使用灵活性
PWM波形的位数,决定了PWM波形占空比的分辨率,位数越高精度越高。
PWM波形的频率,决定了PWM波形的速度,频率越高速度越快。
PWM波形的频率和位数是相对的,位数越高频率越低。以下例子引用自ESP32编程手册:
比如,PWM 频率为 5 kHz 时,占空比分辨率最大可为 13 位。这意味着占空比可为 0 至 100% 之间的任意值,分辨率为 ~0.012%(2 ** 13 = 8192 LED 亮度的离散电平)。
LED PWM 控制器可用于生成频率较高的信号,足以为数码相机模组等其他设备计时。此时,最大频率可为 40 MHz,占空比分辨率为 1 位。也就是说,占空比固定为 50%,无法调整。
LED PWM 控制器 API 可在设定的频率和占空比分辨率超过 LED PWM 控制器硬件范围时报错。例如,试图将频率设置为 20 MHz、占空比分辨率设置为 3 位时,串行端口监视器上会报错。
2. Arduino配置BiBoard频率
如上文所示,我们需要配置通道、频率和位数,同时选择输出引脚。
第一步:配置PWM控制器
const int freq = 5000; // PWM frequency
const int ledcChannel = 0; // ledc channel, 0-15
const int resolution = 8; // resolution of PWM,8bit(0~255)
ledcSetup(ledcChannel, freq, resolution);
第二步:配置PWM输出引脚
ledcAttachPin(ledPin, ledcChannel);
第三步:输出PWM波形
ledcWrite(ledcChannel, dutyCycle);
例程中我们选择IO2作为输出引脚,连接IO2至一个LED,可以观察到LED呼吸灯的效果。
3. 完整的代码:
/* In this demo, we show how to use PWM in BiBoard(ESP32)
* It's different from the Arduino UNO based on the ATMega328P
*/
// define the PWM pin
const int ledPin = 2; // 16 corresponds to GPIO16
// setting PWM properties
const int freq = 5000; // PWM frequency
const int ledcChannel = 0; // ledc channel, in ESP32 there're 16 ledc(PWM) channels
const int resolution = 8; // resolution of PWM
void setup(){
// configure ledc functionalitites
// channels 0-15, resolution 1-16 bits, freq limits depend on resolution
// ledcSetup(uint8_t channel, uint32_t freq, uint8_t resolution_bits);
ledcSetup(ledcChannel, freq, resolution);
// attach the channel to the GPIO to be controlled
ledcAttachPin(ledPin, ledcChannel);
}
void loop(){
// increase the LED brightness
for(int dutyCycle = 0; dutyCycle <= 255; dutyCycle++){
// changing the LED brightness with PWM
ledcWrite(ledcChannel, dutyCycle);
delay(15);
}
// decrease the LED brightness
for(int dutyCycle = 255; dutyCycle >= 0; dutyCycle--){
// changing the LED brightness with PWM
ledcWrite(ledcChannel, dutyCycle);
delay(15);
}
}
Last updated
Was this helpful?