共计 1836 个字符,预计需要花费 5 分钟才能阅读完成。
背景痛点
在电机控制系统中,AB 相编码器如同 ” 运动感知的双眼 ”,其方向判断直接决定位置计算的准确性。一旦方向误判,每转一圈就会产生±1 圈的误差累积。想象一台 CNC 机床,若编码器方向信号反了,刀具路径将完全偏离预期——这种误差在闭环控制中是灾难性的。

硬件原理
正交编码器的核心在于两路信号的 90°相位差,这构成了方向判别的物理基础:
A 相 ____|‾‾|____|‾‾|____
B 相 ‾‾|____|‾‾|____|‾ ← B 相滞后 90°时为正向
当 A 相上升沿时:
– 若 B 相为低电平→正向旋转
– 若 B 相为高电平→反向旋转
实际电路中,信号抖动可能引发误判。某次实测发现,电机启停时信号边沿会出现约 200ns 的抖动(示波器截图),这要求硬件和软件必须协同处理。
STM32 实现
硬件接口配置
使用 TIM3 的 CH1/CH2 接口,关键配置步骤如下:
-
GPIO 初始化(以 PB4/PB5 为例):
GPIO_InitStruct.Pin = GPIO_PIN_4 | GPIO_PIN_5; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; // 复用推挽 GPIO_InitStruct.Pull = GPIO_PULLUP; // 使能上拉 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; 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.IC2Polarity = TIM_ICPOLARITY_RISING; sConfig.IC2Selection = TIM_ICSELECTION_DIRECTTI; HAL_TIM_Encoder_Init(&htim3, &sConfig);
方向判断逻辑
定时器会自动处理计数方向,通过以下代码获取:
int32_t GetEncDirection(void) {return (TIM3->CR1 & TIM_CR1_DIR) ? -1 : 1; // 读取 DIR 位
}
抗干扰设计
硬件防护
- 上拉电阻计算:根据编码器输出电流(通常 2 -10mA),选择 1 -10kΩ 电阻
- 推荐电路:
A 相 ——╱╲ 1kΩ —— 3.3V │ └── 100nF 电容接地
软件滤波
采用状态机消抖算法:
typedef enum {
STATE_STABLE,
STATE_DEBOUNCE
} EncState;
void EncoderDebounce(EncState* state) {
static uint8_t counter;
switch(*state) {
case STATE_STABLE:
if(A 相变化) {counter=0; *state=STATE_DEBOUNCE;}
break;
case STATE_DEBOUNCE:
if(++counter > 5) *state=STATE_STABLE; // 5 次采样稳定
break;
}
}
避坑指南
- 临界时刻规避 :
- 避免在 EXTI 中断中直接读取计数器
-
推荐在定时器溢出中断中批量处理数据
-
中断保护 :
void TIM3_IRQHandler(void) { uint32_t flags = TIM3->SR; if(flags & TIM_SR_UIF) {__disable_irq(); // 进入临界区 g_overflow_count += (TIM3->CR1 & TIM_CR1_DIR) ? -65536 : 65536; __enable_irq(); TIM3->SR = ~TIM_SR_UIF; // 清除标志 } }
验证方法
逻辑分析仪调试
建议捕获以下信号关联:
1. AB 相原始波形
2. 定时器 CNT 寄存器值
3. DIR 标志位状态
压力测试
突加负载时观察:
– 方向标志翻转频率(应 <1 次 / 秒)
– 计数器连续性(不应有跳变)
拓展思考
实现 4 倍频计数的关键点:
1. 利用双边沿触发(TI1/TI2 的上升 / 下降沿)
2. 在 X4 模式下,需注意计数器溢出频率变为 4 倍
3. 硬件滤波参数需相应调整
经过实际项目验证,这套方案在 3000RPM 的伺服电机上可实现±1LSB 的位置精度。建议初次使用时先用开发板连接编码器进行静态测试,逐步提升转速观察计数器变化规律。
