51编码器电机测速实战:基于STM32的高精度测速方案与避坑指南

1次阅读
没有评论

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

image.webp

背景痛点

在电机控制系统中,精准测速是实现闭环控制的关键。但在使用 51 编码器进行电机测速时,开发者常常会遇到以下三大挑战:

51 编码器电机测速实战:基于 STM32 的高精度测速方案与避坑指南

  • 脉冲边缘抖动 :由于机械振动或电气噪声,编码器输出的脉冲信号边缘可能出现抖动,导致计数不准确。
  • 低速采样误差 :在低速运行时,脉冲间隔较长,传统的定时采样方法容易遗漏脉冲,导致测速精度下降。
  • 高速脉冲丢失 :高速运行时,脉冲频率较高,软件计数可能无法及时响应,导致脉冲丢失。

为了解决这些问题,我们对比了软件计数和硬件捕获方案的优缺点:

  • 软件计数 :实现简单,但受限于 CPU 的中断响应速度和软件处理能力,容易在高速或高负载情况下丢失脉冲。
  • 硬件捕获 :利用 STM32 的定时器硬件编码器接口,能够自动捕获脉冲信号,大大减轻 CPU 负担,提高测速精度和可靠性。

技术方案

1. STM32 硬件编码器接口配置

STM32 的定时器(TIM)模块支持硬件编码器接口,可以自动识别编码器的 A / B 相脉冲信号,并实现四倍频计数。以下是关键参数配置:

  • ARR(自动重装载值):设置为编码器线数的 4 倍(四倍频计数)。
  • CCR(捕获 / 比较寄存器):用于捕获脉冲边沿时间。

配置示例(以 TIM2 为例):

TIM_Encoder_InitTypeDef encoderConfig;
encoderConfig.EncoderMode = TIM_ENCODERMODE_TI12; // 使用 A / B 相四倍频
encoderConfig.IC1Polarity = TIM_ICPOLARITY_RISING;
encoderConfig.IC1Selection = TIM_ICSELECTION_DIRECTTI;
encoderConfig.IC1Prescaler = TIM_ICPSC_DIV1;
encoderConfig.IC1Filter = 6; // 设置滤波器,抑制噪声
encoderConfig.IC2Polarity = TIM_ICPOLARITY_RISING;
encoderConfig.IC2Selection = TIM_ICSELECTION_DIRECTTI;
encoderConfig.IC2Prescaler = TIM_ICPSC_DIV1;
encoderConfig.IC2Filter = 6;
HAL_TIM_Encoder_Init(&htim2, &encoderConfig);
HAL_TIM_Encoder_Start(&htim2, TIM_CHANNEL_ALL);

2. 四倍频计数原理

四倍频计数通过对 A / B 相脉冲的上升沿和下降沿进行捕获,将原始编码器线数乘以 4,从而提高测速分辨率。例如,500 线的编码器在四倍频后等效于 2000 线。

3. 滑动平均滤波算法

为了进一步抑制噪声,可以采用滑动平均滤波算法。窗口大小的选择需要权衡响应速度和滤波效果:

  • 小窗口(如 5 -10):响应快,但滤波效果有限。
  • 大窗口(如 20-30):滤波效果好,但会引入延迟。

实现示例:

#define FILTER_WINDOW_SIZE 10

uint32_t filterBuffer[FILTER_WINDOW_SIZE];
uint32_t filterIndex = 0;
uint32_t filterSum = 0;

uint32_t slidingFilter(uint32_t newValue) {filterSum -= filterBuffer[filterIndex];
    filterBuffer[filterIndex] = newValue;
    filterSum += newValue;
    filterIndex = (filterIndex + 1) % FILTER_WINDOW_SIZE;
    return filterSum / FILTER_WINDOW_SIZE;
}

代码实现

1. 速度计算公式

电机转速(RPM)的计算公式如下:

RPM = (脉冲数 × 60) / (编码线数 × 采样周期)

其中,脉冲数为四倍频后的计数值,编码线数为编码器的物理线数,采样周期为测速的时间间隔(单位:秒)。

2. 中断服务程序中的临界区保护

在中断服务程序中,为了避免竞态条件,需要对关键数据进行保护。例如:

void TIM2_IRQHandler(void) {if (__HAL_TIM_GET_FLAG(&htim2, TIM_FLAG_UPDATE) != RESET) {__HAL_TIM_CLEAR_FLAG(&htim2, TIM_FLAG_UPDATE);
        uint32_t count = TIM2->CNT; // 读取当前计数值
        __disable_irq(); // 进入临界区
        pulseCount = count;
        __enable_irq(); // 退出临界区}
}

性能优化

1. 不同 PWM 频率下的测速误差

以下是不同 PWM 频率下的测速误差对比表:

PWM 频率 (kHz) 测速误差 (RPM)
1 ±0.5
5 ±0.2
10 ±0.1
20 ±0.1

2. 电源噪声抑制的 PCB 布局建议

  • 电源去耦 :在编码器电源引脚附近放置 0.1μF 和 10μF 的电容。
  • 信号走线 :尽量缩短编码器信号线的长度,避免与高频信号线平行走线。
  • 接地 :使用星型接地或单点接地,减少地环路干扰。

避坑指南

1. 常见配置错误

  • GPIO 模式设置不当 :编码器接口的 GPIO 应配置为复用推挽输出模式,而非普通输入模式。
  • 中断优先级冲突 :确保编码器中断的优先级高于其他可能阻塞的中断。

2. 过零检测的软件补偿

在低速运行时,编码器可能出现过零现象(计数值从 ARR 跳变到 0 或反之)。为了避免误判,可以在软件中检测计数值的跳变,并进行补偿。

思考题

  1. 如何扩展方案实现双向测速?
  2. 在无硬件编码器接口的 MCU 上如何实现类似功能?

希望这篇实战指南能帮助你在电机控制项目中实现高精度测速。如果有任何问题或建议,欢迎在评论区交流!

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