共计 2070 个字符,预计需要花费 6 分钟才能阅读完成。
为什么需要霍尔编码器?
在电机控制领域,传统光电编码器容易受粉尘、油污影响导致信号丢失,而霍尔编码器采用磁性感应原理,具有:
- 全封闭结构防尘防水(IP67 级常见)
- 耐受 -40℃~125℃宽温范围
- 抗电磁干扰能力强(工业环境必备)
正交脉冲背后的方向秘密
AB 相输出两路方波信号,相位差 90°形成四种状态组合。当 A 相上升沿时:
- 若 B 相为低电平→正转
- 若 B 相为高电平→反转

(注:实际图片需替换为真实时序图)
STM32 硬件配置三步走
-
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); -
定时器编码器模式
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); -
启动计数器
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;
}
新手必踩的三大坑
- 电源噪声干扰
- 现象:静止时计数器自发跳动
-
解决:
- 硬件:编码器电源加 π 型滤波(10μF+0.1μF 并联)
- 软件:设置合理的输入捕获滤波器(TIMx_CCMRx 寄存器 ICxF 位)
-
机械安装偏差
- 现象:正反转计数不对称
-
解决:
- 调整传感器与磁环间距(0.5-2mm 典型值)
- 用示波器观察 AB 相信号占空比是否接近 50%
-
高速丢失脉冲
- 现象:转速超过 3000RPM 时计数不准
- 解决:
- 改用硬件编码器接口(TIMx_CNT 自动计数)
- 降低传感器输出上升时间(选择 100kHz 以上带宽型号)
实测验证方法论
- 示波器双通道捕获 AB 相信号
- 手动旋转电机轴观察:
- 正转时 A 相领先 90°
- 反转时 B 相领先 90°
- 对比 TIMx_CNT 寄存器值与理论值:
理论脉冲数 = (分辨率 × 4 倍频) × 转动圈数
进阶思考:多圈位置记忆
结合 Z 相(每转脉冲)可实现:
- Z 相上升沿触发中断
- 在中断内记录当前圈数
- 绝对位置 = 圈数×单圈分辨率 + 当前 CNT 值
注意:
– 需要备份寄存器 (BKP) 保存圈数防掉电丢失
– 机械回差需软件补偿
最后的小贴士
实际项目中遇到过最棘手的问题是一个接地不良导致的信号毛刺,后来用如下方法锁定问题:
- 用铜箔胶带加强传感器外壳接地
- 在信号线上串接 100Ω 电阻 +100pF 电容组成低通滤波
- 将示波器探头地线直接夹到编码器金属壳体
希望这篇笔记能帮你少走弯路!
正文完
