共计 1542 个字符,预计需要花费 4 分钟才能阅读完成。
为什么需要关注 370 电机编码器?
在 DIY 平衡小车、3D 打印机或机械臂时,我们常发现普通直流电机无法反馈转速和位置。370 电机编码器就像电机的 ” 眼睛 ”,能实时告诉控制器:” 我现在转了多少圈,转速多少 ”。这种闭环控制让机器人动作更精准,比如保证机械臂每次都能停在相同位置。

增量式编码器工作原理
大多数 370 电机配备的是增量式编码器,核心会输出三组信号:
- A 相 / B 相信号:两个相位差 90°的方波(像 DNA 双螺旋结构),通过哪个信号先跳变判断转向
- Z 相信号(有些型号没有):每转一圈产生一个脉冲,用于绝对位置校准
举个例子:当电机正转时,A 相上升沿对应 B 相高电平;反转时则 A 相上升沿对应 B 相低电平。这种设计只用 2 根信号线就能同时获得转向和转速信息。
硬件连接实战
这里给出 STM32 的典型连接电路(示意图描述):
[编码器] [STM32]
A 相 -------- PA0 (TIM2_CH1)
B 相 -------- PA1 (TIM2_CH2)
VCC --[1kΩ]-- 3.3V
|
[0.1μF]电容到地
关键细节:
- 必须加上拉电阻(1kΩ-10kΩ),避免悬空状态误触发
- 信号线并联 0.1μF 电容过滤高频干扰
- 若传输距离超过 20cm,建议使用屏蔽线
软件配置三步走
使用 STM32CubeMX 快速配置编码器接口模式:
- 打开定时器(如 TIM2)
- 选择 Encoder Mode
- 设置计数方向(通常选 TI1 和 TI2 都计数)
附上关键代码片段(已简化):
// 初始化代码
TIM_Encoder_InitTypeDef encoder = {
.EncoderMode = TIM_ENCODERMODE_TI12,
.IC1Polarity = TIM_ICPOLARITY_RISING,
.IC2Polarity = TIM_ICPOLARITY_RISING
};
HAL_TIM_Encoder_Init(&htim2, &encoder);
HAL_TIM_Encoder_Start(&htim2, TIM_CHANNEL_ALL);
// 读取计数值(注意处理溢出)int32_t get_count() {
static uint16_t last_cnt = 0;
uint16_t current = TIM2->CNT;
int32_t delta = (int16_t)(current - last_cnt); // 处理 16 位溢出
last_cnt = current;
return total_count += delta;
}
转速计算技巧
不用复杂公式,记住这个经验算法:
- 每 100ms 读取一次计数器差值 ΔC
- 已知编码器线数 N(如 370 电机常用 13 线)
- 转速 RPM = (ΔC × 600) / (N × 4 × 0.1)
解释:乘以 4 是因为 AB 相各触发两次边沿,600 是把 0.1 秒换算成分钟。
新手常踩的坑
- 信号抖动:在中断服务函数里添加 20ms 延时去抖
- 计数溢出 :使用 int32_t 累加,并处理(uint16_t) 相减的符号问题
- 转速突变:采用滑动平均滤波(保留最近 5 次采样值)
- 电机反转读数错误:检查 CubeMX 中两个通道的极性是否都设为 RISING
进阶优化思路
当需要更高精度时:
- 将采样间隔从 100ms 缩短到 50ms(但会增加 CPU 负载)
- 使用硬件捕获功能测量脉冲间隔
- 对于高速电机,考虑 32 位定时器或外部计数器芯片
三个课后思考题
- 如果编码器线数标称 13 线,但实测每圈计数只有 52 次(不是 13×4=52),可能是什么原因?
- 当电机高速正反转切换时,为什么有时会出现转速计算为 0 的情况?
- 如何利用 Z 相实现长时间运行后的位置校准?
个人实践心得
刚开始用编码器时,我犯过一个低级错误——没加硬件滤波,结果电机一启动读数就乱跳。后来在信号线上并联了电容,又在软件里加了滑动滤波,终于获得稳定数据。建议新手先用示波器观察原始信号质量,这个步骤能避免很多后期调试的麻烦。
正文完
发表至: 未分类
近两天内
