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 #define LEDC_HS_TIMER LEDC_TIMER_0 #define LEDC_HS_MODE LEDC_HIGH_SPEED_MODE #define LEDC_HS_CH0_GPIO 4 #define LEDC_HS_CH0_CHANNEL LEDC_CHANNEL_0 #define LEDC_TARGET_DUTY 8191 #define LEDC_FADE_TIME 3000 #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() { ledc_timer_config_t ledc_timer = { .duty_resolution = LEDC_TIMER_13_BIT, .freq_hz = LEDC_TIMER_FREQUENCT, .speed_mode = LEDC_HS_MODE, .timer_num = LEDC_HS_TIMER };
ledc_timer_config(&ledc_timer);
ledc_channel[0].channel = LEDC_HS_CH0_CHANNEL; ledc_channel[0].duty = 0; ledc_channel[0].gpio_num = LEDC_HS_CH0_GPIO; ledc_channel[0].speed_mode = LEDC_HS_MODE; ledc_channel[0].timer_sel = LEDC_HS_TIMER; for (ch = 0; ch < LEDC_TOTAL_NUM; ch++) { ledc_channel_config(&ledc_channel[ch]); } ledc_fade_func_install(0);
}
|
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_set_direction(LEDC_HS_CH0_GPIO, GPIO_MODE_OUTPUT); 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; } }
}
|
效果
;