0%

ESP32_LEDC_PWM

LEDC(LED Control)是ESP32封装好的PWM定时器,可以产生16个通道,用于生成独立波形、驱动RGB灯、呼吸灯以及电机调速
本次Demo,使用LEDC控制LED作为呼吸灯。
呼吸灯原理分析:模拟人体呼吸,吸气和呼气各占1.5S,空气吸入量0%->100%,呼出量100%->0%变化。因此设计灯光占空比在3s内由0%->100%,然后下一个3s由100%->0%变化

0.程序设计

  • 使用Timer0作为LEDC的时钟源,频率为8KHz,定时器精度为13位
  • 设置初始占空比为0,变化时长为3S,设置占空比对应的计数为[0%:0,100%:(2^13-1)=8000]

API介绍

函数名 描述 案例
ledc_channel_config_t LEDC通道配置描述
speed_mode:输出速度
channel:0~7
intr_type:中断使能
通道占空比[0,2^bit_num-1]
constledc_channel_config_t ledc_timer;
esp_err_t ledc_channel_config(constledc_channel_config_t*ledc_conf) LEDC通道配置
ESP_OK:Success
ESP_ERR_INVALID_ARG:Parameter error
ledc_channel_config(&ledc_conf)
ledc_timer_config_t LEDC定时器配置描述
speed_mode:输出速度
bit_num:计数精度的位数
timer_num:定时器选择[0~2]
freq_hz:定时器频率
ledc_timer_config_t ledc_timer
esp_err_t ledc_fade_func_install(intintr_alloc_flags) 注册渐变服务
intr_alloc_flags:0:无中断 1:中断
ledc_fade_func_install(0)
esp_err_t ledc_fade_start(ledc_mode_t speed_mode,ledc_channel_t channel,ledc_fade_mode_t wait_done) 渐变开始
speed_mode:LEDC速度模式
channel:使用的通道号
wait_done:堵塞直到渐变完成
ledc_fade_start(ledc_channel[ch].speed_mode,ledc_channel[ch].channel, LEDC_FADE_NO_WAIT);
esp_err_t ledc_set_fade_with_time(ledc_mode_t speed_mode,ledc_channel_t channel,int target_duty, int max_fade_time_ms) 渐变动作值设定
speed_mode:LEDC速度模式
channel:使用的通道号
target_duty:目标占空比
max_fade_time_ms:渐变时间
ledc_fade_start(ledc_channel[ch].speed_mode,ledc_channel[ch].channel, LEDC_FADE_NO_WAIT);

1.引入必要头文件

1
2
#include "driver/ledc.h"
#include "driver/gpio.h"

2.LEDC硬件初始化

  • 配置Timer0~3作为PWM定时器的时钟源,包括分辨率、频率、输出模式等
  • 配置LEDC的输出通道,包括输出GPIO与CHANNEL的绑定、PWM时钟源绑定,占空比设置
  • 统一注册LEDC的输出通道配置信息
  • LEDC使能淡入淡出功能
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#define LEDC_TOTAL_NUM         1				    // PWM通道数,可以多个
#define LEDC_HS_TIMER LEDC_TIMER_0 // 选择PWM定时器0-3
#define LEDC_HS_MODE LEDC_HIGH_SPEED_MODE // PWM输出模式
#define LEDC_HS_CH0_GPIO 4 // LED控制器通道对应GPIO
#define LEDC_HS_CH0_CHANNEL LEDC_CHANNEL_0 // LED控制器通道号
#define LEDC_TARGET_DUTY 8191 // 渐增的最终目标占空比 2^13-1
#define LEDC_FADE_TIME 3000 // 渐变时间3000ms
#define LEDC_TIMER_FREQUENCT 8000 // 定时器计数频率

const char* TAG = "LED Breath";
ledc_channel_config_t ledc_channel[LEDC_TOTAL_NUM];
int ch=0;
void bsp_LEDCInit()
{
// 1.配置Timer0的作为PWM定时器
ledc_timer_config_t ledc_timer = {
.duty_resolution = LEDC_TIMER_13_BIT, // PWM占空比分辨率
.freq_hz = LEDC_TIMER_FREQUENCT, // PWM信号频率
.speed_mode = LEDC_HS_MODE, // 定时器模式
.timer_num = LEDC_HS_TIMER // 定时器序号
};

ledc_timer_config(&ledc_timer);

// 2.配置定时器的高速通道
// 2.1 设置通道配置信息

ledc_channel[0].channel = LEDC_HS_CH0_CHANNEL; // 使用的通道
ledc_channel[0].duty = 0; // 占空比
ledc_channel[0].gpio_num = LEDC_HS_CH0_GPIO; // 通道对应的GPIO
ledc_channel[0].speed_mode = LEDC_HS_MODE; // 定时器输出模式
ledc_channel[0].timer_sel = LEDC_HS_TIMER; // 使用的Timer0作为PWM定时器


// 2.2 注册设置通道配置信息
for (ch = 0; ch < LEDC_TOTAL_NUM; ch++) {
ledc_channel_config(&ledc_channel[ch]);
}

// 3. LEDC使能淡入淡出服务
ledc_fade_func_install(0); // 注册LEDC服务,在调用前使用,参数是作为是否允许中断

}

3.功能实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
void bsp_GpioInit(void)
{
ESP_LOGI(TAG, ">>>===== 1.GPIO初始化 =====<<<");
gpio_pad_select_gpio(LEDC_HS_CH0_GPIO); // 选择要操作的GPIO
gpio_set_direction(LEDC_HS_CH0_GPIO, GPIO_MODE_OUTPUT); // 设置GPIO为推挽输出模式
ESP_LOGI(TAG, ">>>===== GPIO初始化成功! =====<<<");
}


void bsp_LEDBreath(int target_duty)
{

ESP_LOGI(TAG,"PWM Duty From %d To %d",target_duty==0?0:100,target_duty==0?100:0);
for(ch=0;ch<LEDC_TOTAL_NUM;ch++)
{
ledc_set_fade_with_time(
ledc_channel[ch].speed_mode,
ledc_channel[ch].channel,
target_duty,
LEDC_FADE_TIME);
ledc_fade_start(
ledc_channel[ch].speed_mode,
ledc_channel[ch].channel,
LEDC_FADE_NO_WAIT); // 不堵塞
}
vTaskDelay(LEDC_FADE_TIME/portTICK_PERIOD_MS);

}

void app_main()
{
int duty = LEDC_TARGET_DUTY;
bsp_GpioInit();
bsp_LEDCInit();

for(;;)
{
bsp_LEDBreath(duty);
if(duty!=0)
{
duty=0;
}else
{
duty=LEDC_TARGET_DUTY;
}
}

}

效果

LED_Breath;