ESP32学习导航帖
目录
概述
功能概览
定时器配置
通道配置
改变 PWM 信号
参考链接
概述
LED 控制器 (LEDC) 主要用于控制 LED,也可产生 PWM 信号用于其他设备的控制。 该控制器有 16 路通道,可以产生独立的波形来驱动 RGB LED 等设备。
LEDC 通道共有两组,分别为 8 路高速通道和 8 路低速通道。高速通道模式在硬件中实现,可以自动且无干扰地改变 PWM 占空比。低速通道模式下,PWM 占空比需要由软件中的驱动器改变。每组通道都可以使用不同的时钟源。
LED PWM 控制器可在无需 CPU 干预的情况下自动改变占空比,实现亮度和颜色渐变。
功能概览
设置 LEDC 通道在 高速模式或低速模式 下运行,需要进行如下配置:
- 定时器配置 指定 PWM 信号的频率和占空比分辨率。
- 通道配置 绑定定时器和输出 PWM 信号的 GPIO。
- 改变 PWM 信号 输出 PWM 信号来驱动 LED。可通过软件控制或使用硬件渐变功能来改变 LED 的亮度。
另一个可选步骤是可以在渐变终端设置一个中断。
定时器配置
要设置定时器,可调用函数 ledc_timer_config(),并将包括如下配置参数的数据结构 ledc_timer_config_t 传递给该函数:
- 速度模式 ledc_mode_t
- 定时器索引 ledc_timer_t
- PWM 信号频率
- PWM 占空比分辨率
频率和占空比分辨率相互关联。PWM 频率越高,占空比分辨率越低,反之亦然。如果 API 不是用来改变 LED 亮度,而是用于其它目的,这种相互关系可能会很重要。更多信息详见 频率和占空比分辨率支持范围 一节。
通道配置
定时器设置好后,请配置所需的通道(ledc_channel_t 之一)。配置通道需调用函数 ledc_channel_config()。
通道的配置与定时器设置类似,需向通道配置函数传递包括通道配置参数的结构体 ledc_channel_config_t 。
此时,通道会按照 ledc_channel_config_t 的配置开始运作,并在选定的 GPIO 上生成由定时器设置指定的频率和占空比的 PWM 信号。在通道运作过程中,可以随时通过调用函数 ledc_stop() 将其暂停。
改变 PWM 信号
通道开始运行、生成具有恒定占空比和频率的 PWM 信号之后,有几种方式可以改变该信号。驱动 LED 时,主要通过改变占空比来变化光线亮度。
以下两节介绍了如何使用软件和硬件改变占空比。如有需要,PWM 信号的频率也可更改,详见 改变 PWM 频率 一节。
使用软件改变 PWM 占空比
调用函数 ledc_set_duty() 可以设置新的占空比。之后,调用函数 ledc_update_duty() 使新配置生效。要查看当前设置的占空比,可使用 _get_
函数 ledc_get_duty()。
另外一种设置占空比和其他通道参数的方式是调用 通道配置 一节提到的函数 ledc_channel_config()。
传递给函数的占空比数值范围取决于选定的 duty_resolution
,应为 0
至 (2 ** duty_resolution) - 1
。例如,如选定的占空比分辨率为 10,则占空比的数值范围为 0 至 1023。此时分辨率为 ~0.1%。
使用硬件改变 PWM 占空比
LED PWM 控制器硬件可逐渐改变占空比的数值。要使用此功能,需用函数 ledc_fade_func_install() 使能渐变,之后用下列可用渐变函数之一配置:
- ledc_set_fade_with_time()
- ledc_set_fade_with_step()
- ledc_set_fade()
最后用 ledc_fade_start() 开启渐变。
如不需要渐变和渐变中断,可用函数 ledc_fade_func_uninstall() 关闭。
改变 PWM 频率
LED PWM 控制器 API 有多种方式即时改变 PWM 频率:
- 通过调用函数 ledc_set_freq() 设置频率。可用函数 ledc_get_freq() 查看当前频率。
- 通过调用函数 ledc_bind_channel_timer() 将其他定时器绑定到该通道来改变频率和占空比分辨率。
- 通过调用函数 ledc_channel_config() 改变通道的定时器。
控制 PWM 的更多方式
有一些较底层的定时器特定函数可用于更改 PWM 设置:
- ledc_timer_set()
- ledc_timer_rst()
- ledc_timer_pause()
- ledc_timer_resume()
前两个功能可通过函数 ledc_channel_config() 在后台运行,在定时器配置后启动。
例程1
/*******************************************************
ESP32PWM呼吸灯
功能:实现LED呼吸灯
引脚:D2(GPIO2)
Designer: Code_Mouse
Date:2018-9-1
*******************************************************/
#define LED_PWM 5 //把调用的GPIO引脚进行了一个宏定义
int freq = 5000;
int ledChannel = 0;
int resolution = 8;
void setup() {
ledcSetup(ledChannel, freq, resolution);
ledcAttachPin(LED_PWM, ledChannel);
}
void loop() {
for (int dutyCycle = 0; dutyCycle <= 255; dutyCycle++) {
ledcWrite(ledChannel, dutyCycle);
delay(7);
}
for (int dutyCycle = 255; dutyCycle >= 0; dutyCycle--) {
ledcWrite(ledChannel, dutyCycle);
delay(7);
}
}
例程2
#include <Arduino.h>
#ifndef __AUTOPWM_H__
#define __AUTOPWM_H__
void PWM_Init(int PWM_Channel, int PWM_IO);
void PWM_Control(int PWM_Channel, int DutyA);
#endif
int light = 0;
int status = 0;//0是变量趋势,1是变暗趋势
// PWM频率,直接设置即可
int Motor_freq_PWM = 1000;
// PWM分辨率,取值为 0-20 之间,这里填写为10,那么后面的ledcWrite
// 这个里面填写的pwm值就在 0 - 2的10次方 之间 也就是 0-1024
int Motor_resolution_PWM = 10;
//频道0-16,不要和其他timer冲突,绑定io
void PWM_Init(int PWM_Channel, int PWM_IO)
{
pinMode(PWM_IO, OUTPUT);
ledcSetup(PWM_Channel, Motor_freq_PWM, Motor_resolution_PWM); // 设置通道
ledcAttachPin(PWM_IO, PWM_Channel);//将 LEDC 通道绑定到指定 IO 口上以实现输出
}
//pwm的占空比
void PWM_Control(int PWM_Channel, int DutyA)
{
ledcWrite(PWM_Channel, DutyA);
}
void setup() {
Serial.begin(9600);
PWM_Init(0, 5);//通道0-15,IO
}
void loop() {
PWM_Control(0, light);
if(status == 0){
light += 100;
if(light >= 1024){
light = 1024;
status = 1;
}
}else{
light -= 100;
if(light <= 0){
light = 0;
status = 0;
}
}
delay(100);
}
例程3
#include <Arduino.h>
#define LED 22
#define LED_OFF digitalWrite(LED,High) //关灯
#define LED_ON digitalWrite(LED, LOW) //开灯
int freq = 2000; //设置PWM波的频率
int channel = 0; //设置通道,共16个通道,0~15
int resolution = 10; //分辨率,取值0~20 duty的最大值为 2^resolution-1
bool val = 0;
void setup() {
// put your setup code here, to run once:
ledcSetup(channel,freq,resolution); //设置通道0
ledcAttachPin(LED,channel); //将通道0和gpio_pin连接起来
}
void loop() {
// put your main code here, to run repeatedly:
// led逐渐变暗
for (int i = 0; i < 1023; i=i+5)
{
ledcWrite(channel,i);
delay(5);
}
// led逐渐变亮
for (int i = 1023; i >= 0 ; i=i-5)
{
ledcWrite(channel,i);
delay(5);
}
}
参考链接
1.LED PWM 控制器 - ESP32 - — ESP-IDF 编程指南 latest 文档
2.https://www.qutaojiao.com/1444.html