ABZ编码器与RC滤波电路:从信号处理原理到嵌入式实践

1次阅读
没有评论

共计 2115 个字符,预计需要花费 6 分钟才能阅读完成。

image.webp

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

ABZ 编码器与 RC 滤波电路:从信号处理原理到嵌入式实践

一、为什么需要滤波?

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$)→ 实时性好但噪声多

在你们的具体项目中,是如何平衡这个矛盾的?欢迎在评论区分享经验!

正文完
 0
评论(没有评论)