LEDC
- LED Control (LEDC)是ESP封装好的LED控制器
- 使用的是PWM定时器实现
- LEDC主要是为了调节LED的亮度而设计
LED PWM 控制器主要用于控制 LED,也可产生 PWM 信号用于其他设备的控制。该控制器有 8 路高速通道和 8 路低速通道,可以产生独立的波形来驱动 RGB LED 设备等。
LED PWM 控制器的高速通道和低速通道均支持硬件渐变功能,可在无需 CPU 干预的情况下自动改变 PWM 信号的占空比,也可由软件改变 PWM 信号的占空比,实现亮度和颜色渐变。此外,低速通道在 Sleep 模式下仍可运行。
配置
要让指定 LED PWM 控制器 高速模式或低速模式 通道运行,需进行如下配置:
-
配置定时器 指定 PWM 信号的频率和占空比分辨率。
-
配置通道 绑定定时器和输出 PWM 信号的 GPIO。
-
改变 PWM 信号 输出 PWM 信号来驱动 LED。可通过软件控制或使用硬件渐变功能来改变 LED 的亮度。
配置定时器
ledc_timer_config_t ledc_timer = {
.duty_resolution = LEDC_TIMER_13_BIT, // PWM占空比分辨率
.freq_hz = 5000, // PWM信号频率
.speed_mode = LEDC_HIGH_SPEED_MODE, // 定时器模式
.timer_num = LEDC_TIMER_0 // 定时器序号;使用哪个定时器0-3;
};
// 配置定时器0的高速通道
ledc_timer_config(&ledc_timer);
配置通道
ledc_channel_config_t ledc_channel = {
.channel = LEDC_CHANNEL_7, // LED控制器通道号,
.duty = 8191,
.gpio_num = 4, // LED控制器通道对应GPIO,
.speed_mode = LEDC_HIGH_SPEED_MODE, // 模式,
.timer_sel = LEDC_TIMER_0, // 使用哪个定时器0-3
};
// 配置LED控制器
ledc_channel_config(&ledc_channel);
改变 PWM 信号
- 通道开始运行、生成具有恒定占空比和频率的 PWM 信号
使用软件改变 PWM 占空比
- ledc_set_duty() 设置新的占空比
- ledc_update_duty() 使新配置生效
- ledc_get_duty() 查看当前的占空比
- 传递给函数的占空比数值范围取决于选定的 duty_resolution,应为 0 至 (2 ** duty_resolution) - 1。
while (1) {
ledc_set_duty(LEDC_HS_MODE,LEDC_HS_CH0_CHANNEL,0);
ledc_update_duty(LEDC_HS_MODE,LEDC_HS_CH0_CHANNEL);
vTaskDelay(1000 / portTICK_PERIOD_MS);
ledc_set_duty(LEDC_HS_MODE,LEDC_HS_CH0_CHANNEL,4000);
ledc_update_duty(LEDC_HS_MODE,LEDC_HS_CH0_CHANNEL);
vTaskDelay(1000 / portTICK_PERIOD_MS);
ledc_set_duty(LEDC_HS_MODE,LEDC_HS_CH0_CHANNEL,8191);
ledc_update_duty(LEDC_HS_MODE,LEDC_HS_CH0_CHANNEL);
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
使用硬件渐变改变 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_install(0);
while(1) {
for (ch = 0; ch < LEDC_TOTAL_NUM; ch++) {
ledc_set_fade_with_time(
ledc_channel.speed_mode,
ledc_channel.channel,
LEDC_TEST_DUTY,
LEDC_TEST_FADE_TIME);
ledc_fade_start(
ledc_channel.speed_mode,
ledc_channel.channel,
LEDC_FADE_NO_WAIT);
}
vTaskDelay(LEDC_TEST_FADE_TIME / portTICK_PERIOD_MS);
for (ch = 0; ch < LEDC_TOTAL_NUM; ch++) {
ledc_set_fade_with_time(
ledc_channel.speed_mode,
ledc_channel.channel,
0,
LEDC_TEST_FADE_TIME);
ledc_fade_start(
ledc_channel.speed_mode,
ledc_channel.channel,
LEDC_FADE_NO_WAIT);
}
vTaskDelay(LEDC_TEST_FADE_TIME / portTICK_PERIOD_MS);
}