首先看 LEDC 硬件的组成:
1. LEDC Timer: 对 LEDC 时钟计数, 计数的范围是 0 ~ (2^n -1) (其中 n 通过 duty_resolution 寄存器来进行配置). 这也是 LEDC 输出信号的周期.
2. LEDC Channel: 将通道的 duty 值与 timer 中的计数值进行比较, 然后根据比较结果输出 PWM 信号.
在初始化 LEDC 时, 对 LEDC Timer 和 LEDC Channel 均需要进行配置. 但需要注意的是 LEDC Channel 配置, 需要等待 LEDC Timer 计数值溢出之后才会生效. 正常的初始化流程是先初始化 LEDC Timer, 接着初始化 LEDC Channel. e.g.:
Code: Select all
ledc_timer_config_t ledc_timer = {
.duty_resolution = LEDC_TIMER_13_BIT,
.freq_hz = 5000,
.speed_mode = LEDC_HIGH_SPEED_MODE,
.timer_num = LEDC_TIMER_0,
};
ledc_channel_config_t ledc_channel = {
.channel = LEDC_HS_CH0_CHANNEL,
.duty = 0x1 << (LEDC_TIMER_13_BIT),
.gpio_num = GPIO_NUM_18,
.speed_mode = LEDC_HIGH_SPEED_MODE,
.hpoint = 0,
.timer_sel = LEDC_TIMER_0,
};
ledc_timer_config(&ledc_timer);
ledc_channel_config(&ledc_channel);
上面提到过, LEDC Chennel 的配置需要等到 LEDC Timer 计数值溢出之后才会更新. 在配置完 LEDC Chennel 的时候, LEDC Timer 计数值并未溢出, 这个时候 LEDC 输出的将是 IDLE 电平(默认是 0), 等到 LEDC Timer 计数值溢出后, 再根据 LEDC Channel 的配置来输出电平.
解决方案是将 LEDC IDLE 电平配置成高电平.
Code: Select all
ledc_timer_config_t ledc_timer = {
.duty_resolution = LEDC_TIMER_13_BIT,
.freq_hz = 5000,
.speed_mode = LEDC_HIGH_SPEED_MODE,
.timer_num = LEDC_TIMER_0,
};
ledc_channel_config_t ledc_channel = {
.channel = LEDC_HS_CH0_CHANNEL,
.duty = 0x1 << (LEDC_TIMER_13_BIT),
.gpio_num = GPIO_NUM_18,
.speed_mode = LEDC_HIGH_SPEED_MODE,
.hpoint = 0,
.timer_sel = LEDC_TIMER_0,
};
ledc_timer_config(&ledc_timer);
ledc_stop(LEDC_HS_MODE, LEDC_HS_CH0_CHANNEL, 1); //主要的作用是将 IDLE 电平配置成高电平.
ledc_channel_config(&ledc_channel);
ledc_update_duty(LEDC_HS_MODE, LEDC_HS_CH0_CHANNEL);
这时候 LEDC 初始化时不会再出现低脉冲了.