Skip to content

第 3 章:PWM 舵机与 ESC 控制

3.1 知识要点

  • 标准 RC PWM 协议:50 Hz 周期,1000–2000 µs 脉宽
  • LEDC 14-bit 分辨率下的占空比计算
  • ESC 上电解锁流程(中立位保持 2 秒)
  • 双通道同步配置(油门 + 转向)

3.2 课程内容

电调(ESC)和舵机均使用标准 RC PWM 协议控制:50 Hz 重复频率,脉宽 1000 µs 对应最小值,1500 µs 对应中立,2000 µs 对应最大值。OSRCORE 使用 LEDC TIMER0 的两个通道分别驱动 GPIO1(油门)和 GPIO2(转向)。

3.3 基础学习

RC PWM 时序

周期 = 20 ms (50 Hz)
脉宽范围:1000 µs(最小)~ 2000 µs(最大)
中立位:1500 µs

14-bit 分辨率下的占空比计算

APB 时钟 80 MHz,14-bit 分辨率(16384 步):

period_ticks = 80_000_000 / 50 = 1_600_000
1 µs = 80 ticks
duty = pulse_us × 80

例:1500 µs → duty = 120000;2000 µs → duty = 160000。

宏定义:#define US_TO_DUTY(us) ((us) * 80)

ESC 解锁流程

大多数 ESC 上电后需要检测到中立位信号(1500 µs)才会解锁,通常需要保持 1–3 秒。未解锁的 ESC 不响应油门指令。

3.4 程序学习

定时器与双通道初始化:

c
ledc_timer_config_t timer = {
    .speed_mode      = LEDC_LOW_SPEED_MODE,
    .duty_resolution = LEDC_TIMER_14_BIT,
    .timer_num       = LEDC_TIMER_0,
    .freq_hz         = 50,
    .clk_cfg         = LEDC_AUTO_CLK,
};
ledc_timer_config(&timer);

ledc_channel_config_t ch_throttle = {
    .gpio_num = 1, .channel = LEDC_CHANNEL_0,
    .timer_sel = LEDC_TIMER_0, .duty = US_TO_DUTY(1500),
};
ledc_channel_config(&ch_throttle);

ledc_channel_config_t ch_steering = {
    .gpio_num = 2, .channel = LEDC_CHANNEL_1,
    .timer_sel = LEDC_TIMER_0, .duty = US_TO_DUTY(1500),
};
ledc_channel_config(&ch_steering);

设置脉宽与 ESC 解锁:

c
static void set_pulse(ledc_channel_t ch, uint32_t pulse_us)
{
    ledc_set_duty(LEDC_LOW_SPEED_MODE, ch, US_TO_DUTY(pulse_us));
    ledc_update_duty(LEDC_LOW_SPEED_MODE, ch);
}

// ESC 解锁:中立位保持 2 秒
set_pulse(CH_THROTTLE, 1500);
set_pulse(CH_STEERING, 1500);
vTaskDelay(pdMS_TO_TICKS(2000));

3.5 课程总结

本章掌握了 RC PWM 协议的原理和 LEDC 14-bit 精度配置,实现了 ESC 解锁和舵机扫描。US_TO_DUTY() 宏将物理脉宽直接映射为寄存器值,是后续 PID 控制输出的基础接口。


Built for OSRCORE robot development board.