PWM作为重要的IO输出功能,应用广泛,常见应用包括:
1. 电机控制(调速,调扭矩,恒压/恒流/恒扭矩控制等等)
2. 控制蜂鸣器输出音调
3. 播放声音文件
4. 呼吸灯
ESP32在arduino中没有提供PWM例程,也不想arduino标准板子有analogWrite方法,所以可以利用其LEDC的控制接口来输出PWM波,为了方便学习,可以配合逻辑分析仪软件来进行波形抓取和分析。
官网下载链接:
Logic analyzer software from Saleae
可以自定义插件,还可以用python来调用API,非常强大!页面也比老版本漂亮多了。
ESP32的LEDC接口用来生成PWM非常方便,详见下面这篇文章
ESP32学习笔记(15)——LEDC(PWM)接口使用 - 简书
LEDC接口函数方法
ESP32有一个LEDC,原本设计用来控制LED,可以作简单的PWM输出,可以指定输出到任一GPIO.
LEDC总共有16个路通道(0 ~ 15),分为高低速两组,高速通道(0 ~ 7)由80MHz时钟驱动,低速通道(8 ~ 15)由1MHz时钟驱动。
方法函数:
double ledcSetup(uint8_t channel, double freq, uint8_t resolution_bits)
channel为通道号,取值0 ~ 15;
freq,设置频率;
resolution_bits计数位数,取值0 ~ 20(该值决定后面ledcWrite方法中占空比的最大值,如该值写10,则占空比最大可写2^10-1=1023 ;
通道最终频率 = 时钟频率 / ( 分频系数 * ( 2^计数位数 ) );(分频系数最大为1024)
案例一,输出PWM方波
#include <Arduino.h>
int freq = 2000; // 频率
int channel = 0; // 通道
int resolution = 8; // 分辨率
int dutyCycle=100; //
const int led = 18; // define the pin
void setup()
{
ledcSetup(channel, freq, resolution); // 设置通道
ledcAttachPin(led, channel); // 将通道与对应的引脚连接
ledcWrite(channel, dutyCycle); // 输出PWM
}
void loop()
{
}
输出波形
从测量数据可以看到频率2K, 占空比接近40%(100/255也差不多)
案例二. 变化的PWM波--呼吸灯
#include <Arduino.h>
int freq = 1000; // 频率
int channel = 0; // 通道
int resolution = 8; // 分辨率
const int led = 18;
void setup()
{
ledcSetup(channel, freq, resolution); // 设置通道
ledcAttachPin(led, channel); // 将通道与对应的引脚连接
}
void loop()
{
// 逐渐变亮
for (int dutyCycle = 0; dutyCycle <= 255; dutyCycle = dutyCycle + 5)
{
ledcWrite(channel, dutyCycle); // 输出PWM
delay(20);
}
// 逐渐变暗
for (int dutyCycle = 255; dutyCycle >= 0; dutyCycle = dutyCycle - 5)
{
ledcWrite(channel, dutyCycle); // 输出PWM
delay(20);
}
}
观察呼吸灯的效果
案例三. 播放不同音调的声音,须配合带驱动的蜂鸣器或者带功放的喇叭,可惜手边没有