• 正文
  • 相关推荐
申请入驻 产业图谱

STM32 电机测速实战:M 法 + T 法全覆盖,高速低速精准适配

13小时前
260
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

STM32 实现电机测速的核心方案是 “定时器编码器接口 + 双测速算法”:M 法通过固定时间计数脉冲,适合 146rpm 以上高速场景;T 法通过测量脉冲间隔,适合 35rpm 以下低速场景,结合 TIM3(编码器解码)、TIM2(脉冲捕获)、TIM6(定时中断)的硬件协作,可实现全转速范围精准测速。

资料获取:【实战经验】LAT1447 电机测速方法以及在STM32中的实现

1. 核心测速原理:M 法 vs T 法(清晰对比)

1.1 M 法测速(高速优选)

  • 核心逻辑:固定采样时间Ts,统计编码器输出脉冲数M1,换算转速。
  • 关键公式
    • 转速:n = (60 × M1) / (Z × Ts)(r/min),Z为编码器每圈 4x 脉冲数;
    • 分辨率:Q = 60 / (Z × Ts)(与转速无关);
    • 误差率:δ = 1/M1 × 100%(转速越高,误差越小)。
  • 特点:高速下脉冲数多,误差小;低速时脉冲数少,误差剧增(如 19rpm 时误差可达 5% 以上)。

1.2 T 法测速(低速优选)

  • 核心逻辑:测量编码器两个脉冲的间隔时间Tt(通过高频时钟脉冲数M2换算),反推转速。
  • 关键公式
    • 转速:n = (60 × ft) / (Z × M2)(r/min),ft为高频时钟频率;
    • 分辨率:Q = 60×ft / [Z×M2×(M2-1)](转速越低,M2越大,分辨率越高);
    • 误差率:δ = 1/(M2-1) × 100%(低速时误差极小,高速时误差增大)。
  • 特点:低速下脉冲间隔长,M2多,误差小;高速时间隔短,M2少,误差上升。

1.3 核心差异总结

对比维度 M 法 T 法
适用转速 中高速(≥146rpm) 中低速(≤292rpm)
误差特性 转速越高,误差越小 转速越低,误差越小
分辨率 固定(与转速无关) 动态(低速分辨率更高)
硬件依赖 定时器计数 + 定时中断 定时器捕获 + 编码器接口

2. STM32 硬件实现方案(定时器协作)

2.1 定时器分配(以 STM32F1/F4/H7 为例)

定时器 功能 核心配置
TIM3 编码器接口(4x 解码) 编码器模式(SMS=0011),映射 TRGO 输出
TIM2 脉冲间隔捕获(T 法核心) 输入捕获模式,触发源为 TIM3_TRGO
TIM6 定时中断(计算触发) 1ms 中断,读取计数 / 捕获值计算转速

2.2 关键配置步骤(CubeMX + 代码)

(1)TIM3 编码器接口配置

void MX_TIM3_Init(void) {
  TIM_Encoder_InitTypeDef sConfig = {0};
  htim3.Instance = TIM3;
  htim3.Init.Prescaler = 0; // 不分频
  htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim3.Init.Period = 0xFFFF; // 最大计数范围
  htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  sConfig.EncoderMode = TIM_ENCODERMODE_TI12; // 4x解码(TI1和TI2均计数)
  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);
  HAL_TIM_Start(&htim3); // 启动编码器计数
}

(2)TIM2 输入捕获配置(T 法)

void MX_TIM2_Init(void) {
  TIM_IC_InitTypeDef sConfigIC = {0};
  htim2.Instance = TIM2;
  htim2.Init.Prescaler = 71; // 假设APB1=72MHz,ft=1MHz
  htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim2.Init.Period = 0xFFFF;
  HAL_TIM_IC_Init(&htim2);
  sConfigIC.ICPolarity = TIM_ICPOLARITY_RISING;
  sConfigIC.ICSelection = TIM_ICSELECTION_TRC; // 触发源为TIM3_TRGO
  sConfigIC.ICPrescaler = TIM_ICPSC_DIV1;
  HAL_TIM_IC_ConfigChannel(&htim2, &sConfigIC, TIM_CHANNEL_1);
  HAL_TIM_IC_Start(&htim2, TIM_CHANNEL_1); // 启动捕获
}

(3)TIM6 定时中断配置(1ms)

void MX_TIM6_Init(void) {
  htim6.Instance = TIM6;
  htim6.Init.Prescaler = 71; // 72MHz时钟→1MHz计数
  htim6.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim6.Init.Period = 999; // 1ms中断(1MHz×1ms=1000计数)
  HAL_TIM_Base_Init(&htim6);
  HAL_TIM_Base_Start_IT(&htim6); // 启动定时中断
}

2.3 转速计算代码(中断服务函数)

#define Z 1024 // 编码器每圈4x脉冲数
uint32_t M1_prev = 0, speed_M = 0, speed_T = 0;

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {
  if (htim->Instance == TIM6) {
    // 1. M法计算:读取TIM3计数差值(M1)
    uint32_t M1_curr = __HAL_TIM_GET_COUNTER(&htim3);
    uint32_t M1 = M1_curr - M1_prev;
    M1_prev = M1_curr;
    speed_M = (60 * M1) / (Z * 0.001); // Ts=1ms=0.001s

    // 2. T法计算:读取TIM2捕获值(M2)
    uint32_t M2 = __HAL_TIM_GET_COMPARE(&htim2, TIM_CHANNEL_1);
    if (M2 != 0) {
      speed_T = (60 * 1000000) / (Z * M2); // ft=1MHz=1e6Hz
    }
  }
}

3. 测试结果验证(全转速覆盖)

3.1 高速场景(1460~2920rpm)

  • M 法:测速误差≤1%,与参考值高度吻合;
  • T 法:误差≥5%,脉冲间隔短导致M2少,精度下降。

3.2 中速场景(146~292rpm)

  • M 法误差≈2%,T 法误差≈1%,T 法略优。

3.3 低速场景(19~35rpm)

  • M 法误差≥5%,脉冲数过少导致计数偏差;
  • T 法误差≤0.5%,M2多,测量精准。

4. 实战选型与注意事项

4.1 算法选型建议

  • 单一转速场景:高速选 M 法,低速选 T 法;
  • 全转速场景:添加转速判断逻辑,自动切换算法(如转速>146rpm 用 M 法,≤146rpm 用 T 法)。

4.2 关键优化点

  • 编码器选型:Z越大,两种算法的分辨率和误差特性越好(推荐≥1024 脉冲 / 圈);
  • 时钟配置:T 法的ft越高,低速分辨率越高(推荐≥1MHz);
  • 计数溢出:采用 32 位定时器(如 TIM2/TIM5),避免高速时计数溢出。

4.3 避坑指南

  • 编码器接线:确保 TI1/TI2 引脚接线正确,避免解码错误导致计数不准;
  • 中断优先级:TIM6 中断优先级高于其他定时器,确保计数 / 捕获值及时读取;
  • 误差校准:实际应用中可通过多次采样平均,进一步降低随机误差。

STM32 电机测速的核心是 “算法适配转速 + 硬件定时器协作”:M 法靠固定时间计数适配高速,T 法靠脉冲间隔捕获适配低速,结合编码器接口和多定时器功能,无需额外硬件即可实现全转速精准测量。开发时只需按转速场景选型算法,配置好定时器参数,即可快速落地。

相关推荐