Skip to content

第 6 章:正交编码器速度测量(PCNT)

📂 示例代码06_encoder

6.1 知识要点

  • 正交编码器的工作原理(A/B 相,方向判断)
  • ESP-IDF PCNT(脉冲计数)新 API 的配置
  • 溢出回调与累积计数的实现
  • 脉冲数到线速度的换算公式

6.2 课程内容

OSRCORE 配备了一个带减速箱的直流电机,电机轴上安装了 1024 PPR 的正交编码器。通过 PCNT 外设对编码器脉冲计数,结合减速比(10.55)和轮径(42.5 mm),可以精确计算车轮线速度,为 PID 闭环控制提供反馈。

6.3 基础学习

正交编码器原理

正交编码器输出两路相位差 90° 的方波(A 相和 B 相):

  • 正转时:A 相超前 B 相 90°
  • 反转时:B 相超前 A 相 90°

通过检测 A 相边沿时 B 相的电平,可以判断旋转方向。

PCNT 配置为:A 相(EA)上升沿计数,B 相(EB)电平控制方向(高电平正计数,低电平反计数)。

速度换算公式

每转脉冲数 = PPR × 减速比 = 1024 × 10.55 = 10803.2
轮周长 = 2π × 0.0425 = 0.2670 m
每脉冲距离 = 0.2670 / 10803.2 = 2.471×10⁻⁵ m/pulse
速度 (m/s) = Δpulses × 每脉冲距离 / Δt

PCNT 硬件累加(accum_count)

pcnt_unit_config_t.flags.accum_count = 1 置位后,PCNT 硬件在计数器到达 watch point 时自动将溢出量累加到内部 64-bit 累加器。pcnt_unit_get_count() 直接返回真实累计值,无需软件溢出回调,代码更简洁,也不存在中断延迟导致的计数丢失风险。

6.4 程序学习

PCNT 初始化(accum_count 硬件累加模式):

c
pcnt_unit_config_t unit_cfg = {
    .low_limit  = -30000,
    .high_limit =  30000,
    .flags.accum_count = 1,  // 启用硬件级累加,无需软件溢出回调
};
pcnt_new_unit(&unit_cfg, &s_unit);

pcnt_chan_config_t chan_a = {
    .edge_gpio_num  = 3,   // EA
    .level_gpio_num = 9,   // EB
};
pcnt_channel_handle_t ch_a;
pcnt_new_channel(s_unit, &chan_a, &ch_a);
pcnt_channel_set_edge_action(ch_a,
    PCNT_CHANNEL_EDGE_ACTION_INCREASE,  // 上升沿 +1
    PCNT_CHANNEL_EDGE_ACTION_HOLD);     // 下降沿不计
pcnt_channel_set_level_action(ch_a,
    PCNT_CHANNEL_LEVEL_ACTION_KEEP,     // EB 高:正方向
    PCNT_CHANNEL_LEVEL_ACTION_INVERSE); // EB 低:反方向

/* watch point 供硬件累加器使用 */
pcnt_unit_add_watch_point(s_unit,  30000);
pcnt_unit_add_watch_point(s_unit, -30000);

pcnt_unit_enable(s_unit);
pcnt_unit_clear_count(s_unit);
pcnt_unit_start(s_unit);

直接读取累计计数(无需软件 accum 变量):

c
static int32_t encoder_get_count(void)
{
    int raw = 0;
    pcnt_unit_get_count(s_unit, &raw);
    return raw;  // 硬件已累加,直接返回真实计数
}

速度计算(20 ms 周期):

c
int32_t delta = encoder_get_count() - last_count;
float speed = delta * DIST_PER_PULSE / 0.020f;  // m/s

6.5 课程总结

本章掌握了正交编码器的工作原理和 PCNT 外设的配置,通过 accum_count=1 启用硬件级累加,消除了软件溢出回调的复杂性。PPR 从 512 更新为 1024,每转脉冲数 10803.2,线速度计算更精确。这是 PID 速度闭环控制的核心反馈环节。


Built for OSRCORE robot development board.