AB双相霍尔编码器实战指南:从原理到嵌入式应用避坑

1次阅读
没有评论

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

image.webp

背景痛点

在电机控制系统中,位置和速度的精确检测是核心需求。AB 双相霍尔编码器因其结构简单、成本低、抗污染能力强等优点被广泛应用,但在实际开发中常遇到以下问题:

AB 双相霍尔编码器实战指南:从原理到嵌入式应用避坑

  • 信号抖动 :霍尔元件受磁场干扰或机械振动影响,导致输出信号出现毛刺
  • 转速计算误差 :低速时脉冲间隔大,高速时易丢失脉冲,影响转速测量精度
  • 方向误判 :AB 相时序判断错误会导致位置累计误差越来越大

与光电编码器相比,霍尔编码器的优缺点非常明显:

  • 优点
  • 无需精密光栅,结构更坚固
  • 对灰尘、油污不敏感
  • 工作温度范围更宽(-40℃~150℃)

  • 缺点

  • 分辨率通常较低(每转几十到几百个脉冲)
  • 磁铁易受外部磁场干扰
  • 需要更严格的机械安装公差

硬件设计

STM32 定时器配置

使用 STM32 的编码器接口模式是最佳选择,以 TIM3 为例配置步骤:

  1. 配置 GPIO 为浮空输入模式(GPIO_MODE_INPUT)
  2. 设置 TIMx_CCMR1 寄存器为编码器模式 3(TIM_ENCODERMODE_TI12)
  3. 配置输入滤波器(TIM_IC_FILTER)根据信号质量设置 4 - 8 个时钟周期
  4. 开启计数溢出中断(TIM_IT_UPDATE)

硬件滤波设计

推荐使用二阶 RC 滤波电路:

 A 相 → 1kΩ → 100nF → MCU
          ↓
        100nF
          ↓
         GND

截止频率计算:

fc = 1/(2π√(R1R2C1C2)) ≈ 1.6kHz

抗干扰布线

  • 使用双绞线传输 AB 相信号
  • 编码器电源与 MCU 电源共地
  • 信号线远离电机驱动线至少 3cm
  • 在连接器处放置 TVS 二极管(如 SMBJ5.0CA)

核心实现

四倍频状态机

通过状态机实现 4 倍频解码的典型状态转移:

stateDiagram
    [*] --> State00
    State00 --> State01: A↑
    State00 --> State10: B↑
    State01 --> State11: B↑ (正向)
    State01 --> State00: A↓
    State11 --> State10: A↓ (正向)
    State11 --> State01: B↓
    State10 --> State00: B↓ (正向)
    State10 --> State11: A↑

中断服务函数示例

void EXTI9_5_IRQHandler(void) {
    static uint8_t last_state = 0;
    uint8_t current_state = (GPIOB->IDR >> 6) & 0x03; // PB6,PB7

    // 状态转移判断
    switch(last_state << 2 | current_state) {
        case 0b0001: case 0b0111: case 0b1110: case 0b1000:
            position++;
            break;
        case 0b0010: case 0b1011: case 0b1101: case 0b0100:
            position--;
            break;
    }

    // 软件消抖(3 次采样表决)static uint8_t filter_cnt = 0;
    if(current_state == last_state) {filter_cnt = 0;} else if(++filter_cnt >= 3) {
        last_state = current_state;
        filter_cnt = 0;
    }

    EXTI->PR = EXTI_PR_PR6 | EXTI_PR_PR7; // 清除中断标志
}

转速计算优化

采用移动平均滤波的微分算法:

#define SAMPLE_NUM 5

int32_t speed_calculate(int32_t positions[]) {
    static uint8_t idx = 0;
    positions[idx] = position;
    idx = (idx + 1) % SAMPLE_NUM;

    // 计算差分时处理计数器溢出
    int32_t diff = positions[idx] - positions[(idx+1)%SAMPLE_NUM];
    if(diff > 0x7FFFFFFF) diff -= 0xFFFFFFFF;
    else if(diff < -0x7FFFFFFF) diff += 0xFFFFFFFF;

    return diff * 1000 / (SAMPLE_NUM * control_period_ms);
}

性能测试

脉冲丢失率测试

  1. 使用可编程电机驱动器设定固定转速
  2. 记录 10 秒内编码器计数值 M1
  3. 读取驱动器反馈的实际转数 M2
  4. 计算丢失率:
     丢失率 = |(M1/PPR) - (M2* 传动比)| / (M2* 传动比) × 100%

逻辑分析仪验证

推荐使用 Saleae Logic Pro 8:

  • 连接 AB 相和 Z 相信号
  • 设置采样率≥10MHz
  • 添加协议分析器→正交编码器
  • 检查:
  • 相位差是否为 90°±10°
  • 上升 / 下降时间是否 <1μs
  • 有无振铃现象

避坑指南

常见故障排查

现象 可能原因 解决方法
计数方向随机变化 1.AB 相序接反
2. 磁极安装偏移
1. 交换 A / B 接线
2. 调整磁铁居中
高速时丢脉冲 1. 滤波器截止频率过低
2. 中断优先级不够
1. 减小 RC 值
2. 提升中断优先级
低速时计数跳变 1. 电源噪声大
2. 磁铁剩磁不足
1. 增加 LC 滤波
2. 更换 N52 钕磁铁

电源噪声处理

  • 在编码器供电端并联 100μF 电解电容 +100nF 陶瓷电容
  • 使用 LDO 而非开关电源供电
  • 对于长线传输,采用 RS422 差分传输

温度补偿

在 -20℃以下时:

  1. 降低采样频率(延长滤波器时间)
  2. 增加霍尔元件偏置电压(通过 DAC 调节)
  3. 采用温度查表法补偿转速计算系数

完整代码示例

基于 STM32CubeIDE 的 HAL 库实现:

/**
  * @brief  编码器初始化
  * @param  htim: 定时器句柄(需配置为 Encoder Mode)* @retval None
  */
void Encoder_Init(TIM_HandleTypeDef *htim) {TIM_Encoder_InitTypeDef sConfig = {0};

    sConfig.EncoderMode = TIM_ENCODERMODE_TI12;
    sConfig.IC1Polarity = TIM_ICPOLARITY_RISING;
    sConfig.IC1Selection = TIM_ICSELECTION_DIRECTTI;
    sConfig.IC1Prescaler = TIM_ICPSC_DIV1;
    sConfig.IC1Filter = 6;

    // 相同配置复制到 IC2...

    HAL_TIM_Encoder_Init(htim, &sConfig);
    HAL_TIM_Encoder_Start(htim, TIM_CHANNEL_ALL);
}

// 通过 DMA 读取计数值
void Encoder_StartDMA(TIM_HandleTypeDef *htim, uint32_t *pData) {HAL_TIM_Encoder_Start_DMA(htim, TIM_CHANNEL_1, pData, 1);
}

延伸思考

多编码器系统

  1. 使用 STM32 的多个定时器(如 TIM1+TIM8)
  2. 通过外部中断 +GPIO 扩展(需要软件解码)
  3. 专用芯片方案(如 LS7366R)

FOC 控制特殊处理

在磁场定向控制中需注意:

  • 机械角度与电角度的转换:
     电角度 = (机械角度 × 极对数) % 360
  • 换向时刻增加±5°的软件补偿
  • 采用滑模观测器补偿低速非线性误差
正文完
 0
评论(没有评论)