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

1次阅读
没有评论

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

image.webp

为什么需要霍尔编码器?

在电机控制领域,传统光电编码器容易受粉尘、油污影响导致信号丢失,而霍尔编码器采用磁性感应原理,具有:

  • 全封闭结构防尘防水(IP67 级常见)
  • 耐受 -40℃~125℃宽温范围
  • 抗电磁干扰能力强(工业环境必备)

正交脉冲背后的方向秘密

AB 相输出两路方波信号,相位差 90°形成四种状态组合。当 A 相上升沿时:

  1. 若 B 相为低电平→正转
  2. 若 B 相为高电平→反转

AB 双相霍尔编码器入门指南:从工作原理到嵌入式应用实战
(注:实际图片需替换为真实时序图)

STM32 硬件配置三步走

  1. GPIO 初始化(以 TIM3_CH1/CH2 为例)

    GPIO_InitTypeDef GPIO_InitStruct = {0};
    GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_PULLUP; // 推荐上拉
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF2_TIM3; // 复用功能选择
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

  2. 定时器编码器模式

    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 = 0x0F; // 设置滤波系数(16 个时钟周期)
    // IC2 配置同理...
    HAL_TIM_Encoder_Init(&htim3, &sConfig);

  3. 启动计数器

    HAL_TIM_Encoder_Start(&htim3, TIM_CHANNEL_ALL);
    __HAL_TIM_SET_COUNTER(&htim3, 32768); // 初始值设为中值

状态机解码实战代码

// 四倍频计数状态表(A 相旧状态 | B 相旧状态 | A 相新状态 | B 相新状态)const int8_t state_table[16] = {
    0, -1, 1, 0,  // 状态 0 -3
    1, 0, 0, -1,  // 状态 4 -7
    -1, 0, 0, 1,  // 状态 8 -11
    0, 1, -1, 0   // 状态 12-15
};

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) {
    static uint8_t last_state = 0;
    uint8_t new_state = (HAL_GPIO_ReadPin(ENCODER_A_PORT, ENCODER_A_PIN) << 1) | 
                         HAL_GPIO_ReadPin(ENCODER_B_PORT, ENCODER_B_PIN);

    // 查表计算方向
    int8_t delta = state_table[(last_state << 2) | new_state];
    position += delta;

    // 噪声过滤:连续 3 次相同变化才生效
    static int8_t filter_cnt = 0;
    static int8_t last_delta = 0;
    if(delta == last_delta) {if(++filter_cnt >= 3) {
            filtered_position += delta;
            filter_cnt = 0;
        }
    } else {filter_cnt = 0;}
    last_delta = delta;
    last_state = new_state;
}

新手必踩的三大坑

  1. 电源噪声干扰
  2. 现象:静止时计数器自发跳动
  3. 解决:

    • 硬件:编码器电源加 π 型滤波(10μF+0.1μF 并联)
    • 软件:设置合理的输入捕获滤波器(TIMx_CCMRx 寄存器 ICxF 位)
  4. 机械安装偏差

  5. 现象:正反转计数不对称
  6. 解决:

    • 调整传感器与磁环间距(0.5-2mm 典型值)
    • 用示波器观察 AB 相信号占空比是否接近 50%
  7. 高速丢失脉冲

  8. 现象:转速超过 3000RPM 时计数不准
  9. 解决:
    • 改用硬件编码器接口(TIMx_CNT 自动计数)
    • 降低传感器输出上升时间(选择 100kHz 以上带宽型号)

实测验证方法论

  1. 示波器双通道捕获 AB 相信号
  2. 手动旋转电机轴观察:
  3. 正转时 A 相领先 90°
  4. 反转时 B 相领先 90°
  5. 对比 TIMx_CNT 寄存器值与理论值:
    理论脉冲数 = (分辨率 × 4 倍频) × 转动圈数

进阶思考:多圈位置记忆

结合 Z 相(每转脉冲)可实现:

  1. Z 相上升沿触发中断
  2. 在中断内记录当前圈数
  3. 绝对位置 = 圈数×单圈分辨率 + 当前 CNT 值

注意:
– 需要备份寄存器 (BKP) 保存圈数防掉电丢失
– 机械回差需软件补偿

最后的小贴士

实际项目中遇到过最棘手的问题是一个接地不良导致的信号毛刺,后来用如下方法锁定问题:

  1. 用铜箔胶带加强传感器外壳接地
  2. 在信号线上串接 100Ω 电阻 +100pF 电容组成低通滤波
  3. 将示波器探头地线直接夹到编码器金属壳体

希望这篇笔记能帮你少走弯路!

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