第 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 × 每脉冲距离 / ΔtPCNT 溢出处理
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/s6.5 课程总结
本章掌握了正交编码器的工作原理和 PCNT 外设的配置,实现了带溢出处理的精确脉冲计数和线速度计算。这是 PID 速度闭环控制的核心反馈环节。