共计 2115 个字符,预计需要花费 6 分钟才能阅读完成。
在嵌入式系统中,ABZ 编码器因其结构简单、可靠性高而广泛应用于电机控制、位置检测等场景。但在实际应用中,信号抖动和噪声干扰往往会导致计数错误,影响系统精度。今天我们就来聊聊如何通过合理的 RC 滤波设计,让 ABZ 编码器输出更干净、更稳定。

一、为什么需要滤波?
ABZ 编码器通过两路正交方波(A/ B 相)输出位置信息,Z 相作为零位参考。理想情况下,A/ B 相信号应该是完美的 90°相位差方波。但现实中,机械振动、电磁干扰等因素会导致信号出现:
- 上升沿 / 下降沿抖动(几十 ns 到 μs 级)
- 高频噪声毛刺
- 信号畸变(过冲、振铃)
这些问题如果直接送入 MCU 解码,轻则导致±1 计数误差,重则可能引发状态机错误跳转。
二、RC 滤波电路设计
2.1 无源 RC vs 有源滤波
无源 RC 滤波 (成本低、体积小):
– 优点:电路简单,无需额外供电
– 缺点:信号幅值会衰减,且无法调整截止频率
有源滤波 (运放实现):
– 优点:可设计高阶滤波,增益可调
– 缺点:需要供电,PCB 面积大
对于大多数编码器应用(通常 <10kHz 信号),一阶 RC 无源滤波已经足够。
2.2 参数计算
截止频率公式:
f_c = \frac{1}{2\pi RC}
设计步骤:
1. 确定编码器最高转速对应的信号频率 $f_{max}$
2. 取 $f_c = (3\sim5)\times f_{max}$(保留有用信号)
3. 选择标准电容值(如 100nF),反推电阻值
示例:某 1000PPR 编码器在 3000RPM 时:
f_{max} = \frac{1000\times3000}{60} = 50kHz \\
取 f_c=200kHz,C=100nF \Rightarrow R≈8Ω
三、STM32 硬件实现
3.1 电路设计要点
- 在编码器输出端就近放置 RC 滤波(距离 <2cm)
- GPIO 配置为浮空输入(不启用内部上拉)
- 并联 TVS 二极管防护 ESD
典型电路:
Encoder_A ────┬─────── GPIO_PA0
R=10Ω
C=100nF ─── GND
3.2 软件优化技巧
状态机解码(带消抖):
#define DEBOUNCE_US 5 // 消抖时间
typedef enum {
STATE_00,
STATE_01,
STATE_10,
STATE_11
} EncState;
void EXTI0_IRQHandler() {
static EncState lastState;
static uint32_t lastTime;
if((HAL_GetTick() - lastTime) < DEBOUNCE_US) return;
uint8_t a = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0);
uint8_t b = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1);
EncState newState = (a<<1) | b;
// 状态转移判断
if((lastState==STATE_00 && newState==STATE_01) ||
(lastState==STATE_01 && newState==STATE_11) ||
(lastState==STATE_11 && newState==STATE_10) ||
(lastState==STATE_10 && newState==STATE_00)) {counter++;}
// 反向旋转判断省略...
lastState = newState;
lastTime = HAL_GetTick();}
定时器编码器模式(推荐):
// 使用 TIM2 的编码器接口
TIM_Encoder_InitTypeDef enc = {
.EncoderMode = TIM_ENCODERMODE_TI12,
.IC1Filter = 6, // 数字滤波 (0-15)
.IC1Polarity = TIM_INPUTCHANNELPOLARITY_RISING,
.IC2Polarity = TIM_INPUTCHANNELPOLARITY_RISING
};
HAL_TIM_Encoder_Init(&htim2, &enc);
HAL_TIM_Encoder_Start(&htim2, TIM_CHANNEL_ALL);
// 读取计数值
int32_t pos = __HAL_TIM_GET_COUNTER(&htim2);
四、常见问题排查
4.1 PCB 设计错误
- 错误:滤波电路远离编码器接口
→ 高频噪声已耦合到信号线 - 错误:R/ C 值过大
→ 信号上升沿变缓,导致 MCU 误判
4.2 相位延迟问题
当 $f_c$ 设置过低时:
– A/ B 相信号延迟不同→破坏正交关系
– 解决方案:
1. 使用相同参数的 RC 网络
2. 改用四通道运放构建有源滤波
五、效果验证
测试方法:
1. 逻辑分析仪同时捕捉滤波前后的 A / B 相
2. 对比脉冲宽度抖动情况
3. 统计不同转速下的计数误差率
实测数据示例(1000RPM):
| 滤波方案 | 误差脉冲数 / 小时 |
|—————-|—————–|
| 无滤波 | 326 |
| RC 滤波 (f_c=200kHz) | 12 |
| 软件滤波 +RC | 3 |
六、开放思考
滤波本质上是在频域做权衡:
– 强滤波(低 $f_c$)→ 抗噪好但响应慢
– 弱滤波(高 $f_c$)→ 实时性好但噪声多
在你们的具体项目中,是如何平衡这个矛盾的?欢迎在评论区分享经验!
