Skip to content

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

6.1 知识要点

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

6.2 课程内容

OSRCORE 配备了一个带减速箱的直流电机,电机轴上安装了 512 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 × 减速比 = 512 × 10.55 = 5401.6
轮周长 = 2π × 0.0425 = 0.2670 m
每脉冲距离 = 0.2670 / 5401.6 = 4.943×10⁻⁵ m/pulse
速度 (m/s) = Δpulses × 每脉冲距离 / Δt

PCNT 溢出处理

PCNT 硬件计数器为 16-bit(-32768 ~ 32767),高速旋转时会溢出。通过注册 on_reach 回调,在达到上下限时将溢出量累加到软件计数器,实现无限范围计数。

6.4 程序学习

PCNT 初始化(单边沿模式):

c
pcnt_unit_config_t unit_cfg = {
    .low_limit  = -32768,
    .high_limit =  32767,
};
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 低:反方向

溢出回调与累积读取:

c
static bool IRAM_ATTR pcnt_overflow_cb(pcnt_unit_handle_t unit,
                                        const pcnt_watch_event_data_t *edata,
                                        void *user_ctx)
{
    int32_t *accum = (int32_t *)user_ctx;
    *accum += edata->watch_point_val;
    return false;
}

static int32_t encoder_get_count(void)
{
    int raw = 0;
    pcnt_unit_get_count(s_unit, &raw);
    return s_accum + 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 外设的配置,实现了带溢出处理的精确脉冲计数和线速度计算。这是 PID 速度闭环控制的核心反馈环节。


Built for OSRCORE robot development board.