电机驱动开发学习7. 编码器的使用

电机驱动开发学习7. 编码器的使用

  • 一、编码器介绍
    • [1. 什么是编码器](#1. 什么是编码器)
      • [1.1 工作原理](#1.1 工作原理)
      • [1.2 在 BLDC 系统中的两类位置反馈](#1.2 在 BLDC 系统中的两类位置反馈)
      • [1.3 野火驱动板「编码器接口」](#1.3 野火驱动板「编码器接口」)
    • [2. 编码器的分类](#2. 编码器的分类)
      • [2.1 按工作原理分类](#2.1 按工作原理分类)
      • [2.2 霍尔传感器(换相用,本实验借其测速)](#2.2 霍尔传感器(换相用,本实验借其测速))
      • [2.3 本实验配置(霍尔测速,非外接编码器)](#2.3 本实验配置(霍尔测速,非外接编码器))
      • [2.4 测速的两种方式:M 法与 T 法](#2.4 测速的两种方式:M 法与 T 法)
        • [(1)M 法(频率法 / 测频法)](#(1)M 法(频率法 / 测频法))
        • [(2)T 法(周期法 / 测周法)](#(2)T 法(周期法 / 测周法))
  • 二、霍尔传感器测速与位置反馈原理
    • [1. 霍尔信号与换相状态](#1. 霍尔信号与换相状态)
    • [2. 转速测量原理](#2. 转速测量原理)
      • [2.1 从一次跳变到 RPM 的推导](#2.1 从一次跳变到 RPM 的推导)
      • [2.2 代入本工程参数](#2.2 代入本工程参数)
      • [2.3 公式中各因子的物理含义](#2.3 公式中各因子的物理含义)
    • [3. 位置与方向](#3. 位置与方向)
  • [三、TIM5 Hall 接口配置](#三、TIM5 Hall 接口配置)
    • [1. 引脚与定时器](#1. 引脚与定时器)
    • [2. Hall 模式工作机制](#2. Hall 模式工作机制)
  • 四、软件实现
    • [1. 关键宏定义(`bsp_motor_tim.h`)](#1. 关键宏定义(bsp_motor_tim.h))
    • [2. 霍尔反馈 API](#2. 霍尔反馈 API)
    • [3. 触发回调核心逻辑](#3. 触发回调核心逻辑)
    • [4. 波形帧扩展(`bsp_adc.c`)](#4. 波形帧扩展(bsp_adc.c))
    • [5. 主循环(`main.c`)](#5. 主循环(main.c))
  • 五、实验操作与现象
    • [1. 接线](#1. 接线)
    • [2. 串口控制](#2. 串口控制)
    • [3. 输出数据](#3. 输出数据)
    • [4. 调试提示](#4. 调试提示)
  • 六、小结

本系列教程学习资源来自野火官方电机教程,部分代码及博客内容摘自官方教程。本系列教程使用野火骄阳 F407 开发板及野火有刷/无刷驱动板。

在上一篇(lesson6)中,我们完成了三相电流采集、软件过流保护。本篇在 lesson6 基础上,利用 TIM5 霍尔接口 ,实现电机转速、位置、方向 的测量,并与温度、电压、电流合并为 22 字节同一帧输出。

概念说明

  • 霍尔传感器 :电机内部 U/V/W(HU/HV/HW) ,仅 6 个离散状态,首要用途是六步换相 ,精度远低于编码器。
    本实验配套电机只有霍尔、没有另装光电编码器 ;代码沿用野火官方例程,借霍尔跳变间隔估算转速,属于低成本速度反馈。下文先介绍真正的编码器,再说明本实验实际用的是霍尔。

一、编码器介绍

1. 什么是编码器

编码器(Encoder)是一种将机械位移(角位移或直线位移)转换为电信号的传感器,用于测量电机的转速、位置和方向。在伺服、FOC 等闭环控制中,专用编码器是核心反馈元件。

1.1 工作原理

编码器通过检测转轴旋转,输出脉冲或数字码。控制器可得到:

  • 转速:单位时间内的脉冲数(或捕获周期)
  • 位置:累计脉冲数(增量式)或绝对码(绝对式)
  • 方向:A/B 正交相位,或绝对码变化趋势

1.2 在 BLDC 系统中的两类位置反馈

类型 典型信号 分辨率 主要用途
增量式/绝对式编码器 A、B、Z(EA/EB/EZ) 高(数百~数千线/转) 速度环、位置环、FOC 电角度
霍尔传感器 HU、HV、HW 低(6 状态/电周期) 六步换相、堵转检测、粗测速

二者不要混称。霍尔不是编码器 ;口语里的「霍尔编码器」容易误导,工程上应称 霍尔位置传感器换相霍尔

1.3 野火驱动板「编码器接口」

驱动板编码器接口(J4)经光耦隔离后接到 MCU,原理图信号双命名

端子信号 接增量式编码器时 接本电机霍尔线时
EA A 相脉冲 HU
EB B 相脉冲 HV
EZ Z 相零位脉冲 HW

J3 跳线可选 5 V / 12 V 给外设供电。若外接 2500 线增量编码器 ,应使用 TIM 编码器模式 对 EA/EB 计数;本系列 lesson4~7 配套电机只接霍尔线,未使用外接编码器

2. 编码器的分类

2.1 按工作原理分类

(1)光电增量式编码器(本接口可外接的类型)
  • 原理:码盘透光/遮光,输出 A、B 正交方波 + Z 零位脉冲
  • 特点:分辨率高、适合速度/位置闭环
  • MCU 用法HAL_TIM_Encoder_Init(),对 A/B 边沿计数
  • 应用:野火 FOC 例程、伺服、CNC
(2)绝对式编码器
  • 每个机械角对应唯一码值,断电保持
  • 成本高,用于高精度定位
(3)磁编码器
  • 磁阻/霍尔阵列,精度介于霍尔开关与光电编码器之间
  • 与电机内 3 个换相霍尔不是同一类器件

2.2 霍尔传感器(换相用,本实验借其测速)

  • 原理:3 个开关型霍尔检测转子磁场,组合为 6 个有效状态(每 60° 电角度)
  • 首要作用:确定换相时刻(lesson4 已用)
  • 本实验附加作用:用 TIM5 Hall 模式捕获跳变间隔 → 估算 RPM、累计扇区位置
  • 局限 :机械一圈仅 12 次 跳变(2 对极 × 6 状态),不能做精确定位
  • 引脚:PH10(HU)、PH11(HV)、PH12(HW)

2.3 本实验配置(霍尔测速,非外接编码器)

参数 配置值
传感器 电机内置霍尔 HU/HV/HW(外接 EA/EB/EZ 编码器)
主要功能 换相 + 借跳变测速/方向/粗位置
定时器 TIM5(Hall Sensor 模式, Encoder 模式)
预分频系数 128
计数周期 0xFFFF (65535)
输入滤波 IC1Filter = 10
中断优先级 0 (最高)
换相状态数 6 个有效状态

霍尔 3 路组合成状态 1~6,既用于 bldcm_commutate() 换相,也在 HAL_TIM_TriggerCallback() 中更新 RPM/POS/DIR。

2.4 测速的两种方式:M 法与 T 法

无论信号来自光电编码器脉冲 还是霍尔跳变 ,测转速的常用思路都可以归纳为两类。野火《电机应用开发实战指南》编码器章节对二者有完整介绍;本实验的霍尔测速属于其中的 T 法

(1)M 法(频率法 / 测频法)

思路 :在固定时间窗口 (T_0) 内,统计传感器输出的脉冲(或霍尔跳变)个数 (M_0),用「单位时间内的脉冲数」换算转速。

对增量式编码器,设单圈总脉冲数为 (C)(含倍频后的计数,如 600 线 4 倍频则 (C=2400)),则:

n = 60 ⋅ M 0 C ⋅ T 0 n = \frac{60 \cdot M_0}{C \cdot T_0} n=C⋅T060⋅M0

对本电机霍尔,机械转一圈共 12 次 跳变((C_{hall}=12)),若在 ( T 0 = 0.05   s ) (T_0=0.05\,\text{s}) (T0=0.05s) 内测得 (M_0=5) 次跳变,则:

R P M = 60 × 5 12 × 0.05 = 500 RPM = \frac{60 \times 5}{12 \times 0.05} = 500 RPM=12×0.0560×5=500

特点

优点 缺点
实现简单,主循环里计数即可 低速时 (T_0) 内脉冲很少,误差大、波动大
高速时 (M_0) 大,相对平稳 结果有 (T_0) 量级的滞后(需等窗口结束才更新)

伪代码示例(本工程未采用,仅供对比):

c 复制代码
/* 每 50 ms 统计一次霍尔跳变次数 delta_pos */
rpm = (60UL * delta_pos) / (12UL * T0_SEC);
(2)T 法(周期法 / 测周法)

思路 :测量相邻两次传感器事件之间的时间间隔 (T_e)(或等价地,用定时器捕获计数值 (N)),由「转一圈需要多久」反推转速。

对编码器: ( n = 60 C ⋅ T e ) (n = \dfrac{60}{C \cdot T_e}) (n=C⋅Te60)。

对本实验霍尔:每次跳变对应 60° 电角度,相邻跳变间隔 (T_{step}) 与 CCR1 捕获值 (N) 的关系见 §2.1,最终:

R P M = 60 ⋅ f t i m 6 ⋅ P p ⋅ P S C ⋅ N RPM = \frac{60 \cdot f_{tim}}{6 \cdot P_p \cdot PSC \cdot N} RPM=6⋅Pp⋅PSC⋅N60⋅ftim

特点

优点 缺点
低速时 (T_e) 长,单次测量相对更准 高速时 (T_e) 极短,捕获分辨率受限,误差变大
每来一次跳变即可更新,响应快 对噪声、抖动更敏感,需滤波(如 IC1Filter、最小捕获阈值)

本工程在 HAL_TIM_TriggerCallback() 中读取 CCR1,即 T 法;TIM5 Hall 硬件在每次霍尔变化时自动锁存间隔,无需在主循环里开固定窗口。

二、霍尔传感器测速与位置反馈原理

1. 霍尔信号与换相状态

本电机内置 3 个霍尔传感器(HU、HV、HW),5V 供电,2 对极。三路信号按位组合成 6 个有效状态(排除 000 与 111):

状态值 HU HV HW 电角度区间
1 0 0 1 0° ~ 60°
3 0 1 1 60° ~ 120°
2 0 1 0 120° ~ 180°
6 1 1 0 180° ~ 240°
4 1 0 0 240° ~ 300°
5 1 0 1 300° ~ 360°

正转时状态按 1 → 3 → 2 → 6 → 4 → 5 → 1 循环;反转则相反。机械转一圈(360° 机械角)共产生 12 次霍尔跳变(6 状态 × 2 对极)。

2. 转速测量原理

STM32 的 Hall Sensor 模式 将 HU/HV/HW 异或后接入 TIM5 通道 1。每当霍尔组合变化,定时器将两次跳变之间的计数值 锁存到 CCR1 并清零计数器。该计数值对应 60° 电角度 的旋转时间。

2.1 从一次跳变到 RPM 的推导

第一步:确定单次跳变对应的时间

本工程 TIM5 配置为:

  • 定时器计数时钟 (f_{tim} = 84,\text{MHz})(系统 168 MHz,APB1 四分频得 42 MHz,定时器倍频后为 84 MHz)
  • 预分频寄存器写入 128 - 1,实际分频系数 (PSC = 128)
  • 每次霍尔跳变捕获到的计数值为 (N)(即 CCR1)

计数器每加 1 所需时间为:

T c n t = P S C f t i m T_{cnt} = \frac{PSC}{f_{tim}} Tcnt=ftimPSC

相邻两次霍尔跳变的时间间隔(即转子转过 60° 电角度所需时间)为:

T s t e p = N ⋅ T c n t = N ⋅ P S C f t i m T_{step} = N \cdot T_{cnt} = \frac{N \cdot PSC}{f_{tim}} Tstep=N⋅Tcnt=ftimN⋅PSC

第二步:电周期与电频率

BLDC 电机每 60° 电角度对应一次霍尔状态变化,一个完整电周期(360° 电角度)包含 6 次跳变:

T e = 6 ⋅ T s t e p = 6 ⋅ N ⋅ P S C f t i m T_e = 6 \cdot T_{step} = \frac{6 \cdot N \cdot PSC}{f_{tim}} Te=6⋅Tstep=ftim6⋅N⋅PSC

电频率(每秒转过的电周期数)为:

f e = 1 T e = f t i m 6 ⋅ N ⋅ P S C f_e = \frac{1}{T_e} = \frac{f_{tim}}{6 \cdot N \cdot PSC} fe=Te1=6⋅N⋅PSCftim

第三步:电频率换算为机械转速

本电机极对数 (P_p = 2),即转子机械转 1 圈,定子磁场完成 2 个电周期。因此:

f m = f e P p = f t i m 6 ⋅ P p ⋅ N ⋅ P S C f_m = \frac{f_e}{P_p} = \frac{f_{tim}}{6 \cdot P_p \cdot N \cdot PSC} fm=Ppfe=6⋅Pp⋅N⋅PSCftim

其中 (f_m) 为机械频率(单位:转/秒,rps)。

第四步:换算为 RPM

每分钟转数:

R P M = 60 ⋅ f m = 60 ⋅ f t i m 6 ⋅ P p ⋅ P S C ⋅ N RPM = 60 \cdot f_m = \frac{60 \cdot f_{tim}}{6 \cdot P_p \cdot PSC \cdot N} RPM=60⋅fm=6⋅Pp⋅PSC⋅N60⋅ftim

整理后可记为:

R P M = 10 ⋅ f t i m P p ⋅ P S C ⋅ N RPM = \frac{10 \cdot f_{tim}}{P_p \cdot PSC \cdot N} RPM=Pp⋅PSC⋅N10⋅ftim

对应代码中的实现(bsp_motor_tim.c):

c 复制代码
rpm = (60UL * MOTOR_HALL_TIMER_CLK_HZ) /
      (6UL * MOTOR_POLE_PAIRS * MOTOR_HALL_PRESCALER_COUNT * capture);

2.2 代入本工程参数

符号 本工程取值 含义
(f_{tim}) 84 000 000 Hz TIM5 计数时钟
(PSC) 128 预分频系数
(P_p) 2 极对数
(N) CCR1 捕获值 相邻两次霍尔跳变的计数值

验算示例:若 (N = 1094),则

R P M = 60 × 84 × 10 6 6 × 2 × 128 × 1094 ≈ 3017 RPM = \frac{60 \times 84\times10^6}{6 \times 2 \times 128 \times 1094} \approx 3017 RPM=6×2×128×109460×84×106≈3017

即约 3000 RPM,与空载运行时的观测值一致。

2.3 公式中各因子的物理含义

因子 含义
60 秒 → 分钟的单位换算
6 一个电周期(360° 电角度)内的霍尔跳变次数
(P_p) 极对数,将电频率降为机械频率
(PSC) 定时器预分频,降低计数频率以扩大可测最慢转速范围
(N) 两次跳变间隔的计数值,越大表示转速越慢

当 (N) 过小(本工程 < MOTOR_HALL_CAPTURE_MIN,即 10)时视为噪声不予计算;超过 200 ms 无新跳变则 RPM 归零(motor_hall_speed_poll())。

3. 位置与方向

  • 位置 :每次检测到合法的霍尔状态跳变,位置计数 ±1(正转 +1,反转 −1)。数值表示累计的霍尔扇区数,可换算为电角度:电角度 ≈ 位置 × 60° (mod 360°)
  • 方向 :比较相邻两次状态是否符合正转序列 1→3→2→6→4→5;符合则为正转(DIR=1),反之为反转(DIR=2)。超过 200 ms 无跳变则 DIR=0(停止)。
  • 当前霍尔状态:实时读取的 1~6 换相状态,便于调试换相是否正确。

三、TIM5 Hall 接口配置

1. 引脚与定时器

项目 配置
定时器 TIM5
霍尔 U/V/W PH10 / PH11 / PH12
复用功能 AF2_TIM5
预分频 128
计数周期 0xFFFF
输入滤波 IC1Filter = 10
捕获边沿 双边沿 TIM_ICPOLARITY_BOTHEDGE
中断优先级 0(换相最高优先级)

2. Hall 模式工作机制

HAL_TIMEx_HallSensor_Init() 配置 TIM5 为霍尔接口模式:

  1. 三路霍尔异或后接 TI1,任一霍尔变化产生触发中断;
  2. 触发时将 CCR1 锁存为上次跳变至本次跳变的计数值;
  3. HAL_TIM_TriggerCallback() 中读取 CCR1 计算转速,并执行六步换相。

与 lesson4 相同,换相逻辑仍在 bldcm_commutate() 中根据当前霍尔状态切换 TIM8 PWM 与下桥臂 GPIO。

四、软件实现

1. 关键宏定义(bsp_motor_tim.h

c 复制代码
#define MOTOR_HALL_TIMER_CLK_HZ         84000000UL
#define MOTOR_POLE_PAIRS                2U
#define MOTOR_HALL_CAPTURE_MIN          10U
#define MOTOR_RPM_MAX                   20000U
#define MOTOR_HALL_SPEED_TIMEOUT_MS     200U

#define MOTOR_HALL_DIR_STOP             0U
#define MOTOR_HALL_DIR_FWD              1U
#define MOTOR_HALL_DIR_REV              2U

2. 霍尔反馈 API

函数 说明
motor_hall_get_rpm() 机械转速(RPM)
motor_hall_get_position() 累计霍尔扇区位置(有符号,正转增)
motor_hall_get_direction() 0=停,1=正转,2=反转
motor_hall_get_state() 当前霍尔状态 1~6
motor_hall_speed_poll() 主循环调用,超时将 RPM/DIR 归零

3. 触发回调核心逻辑

HAL_TIM_TriggerCallback() 中:

c 复制代码
capture = __HAL_TIM_GET_COMPARE(&motor_htimx_hall, TIM_CHANNEL_1);
motor_hall_update_speed(capture);          /* 由 CCR1 计算 RPM */

delta = hall_transition_dir(prev, step);   /* 判断正/反转 */
if (delta > 0)  { motor_position++; motor_actual_dir = MOTOR_HALL_DIR_FWD; }
if (delta < 0)  { motor_position--; motor_actual_dir = MOTOR_HALL_DIR_REV; }

bldcm_commutate(step);                     /* 六步换相 */

正转序列表 fwd_next[]1→3→2→6→4→5 建立,用于判断跳变方向。

4. 波形帧扩展(bsp_adc.c

在 lesson6 的 12 字节帧基础上扩展为 22 字节,同一时刻输出全部观测量:

偏移 长度 字段 说明
0 2 帧头 0xAA 0x55
2 2 VBUS uint16,×100,单位 V
4 2 TEMP uint16,×10,单位 ℃
6 2 IU uint16,mA
8 2 IV uint16,mA
10 2 IW uint16,mA
12 2 RPM uint16,机械转速
14 4 POS int32 小端,霍尔累计位置
18 2 DIR uint16:0停 / 1正 / 2反
20 2 HALL uint16,当前状态 1~6

所有多字节字段均为小端序 。每 50 ms 调用 adc_send_waveform_frame() 发送一帧。

解析示例:24.5 V、25.3 ℃、U=120 mA、V=130 mA、W=110 mA、RPM=3000、POS=+42、DIR=1(正转)、HALL=3

复制代码
AA 55 92 09 FD 00 78 00 82 00 6E 00 B8 0B 2A 00 00 00 01 00 03 00

可用下面Python代码段辅助解析数据:

python 复制代码
import struct
data = bytes.fromhex("AA559209FD00780082006E00B80B2A00000001000300")
assert data[0:2] == b'\xAA\x55'
vbus, temp, iu, iv, iw, rpm, pos, dir_, hall = struct.unpack_from('<6H i 2H', data, 2)
print(vbus/100, temp/10, iu, iv, iw, rpm, pos, dir_, hall)

5. 主循环(main.c

在 lesson6 基础上增加 motor_hall_speed_poll(),其余逻辑不变(按键/串口控制、堵转检测、过流保护、50 ms 发帧):

c 复制代码
while (1)
{
    deal_key_input();
    deal_serial_data();
    motor_stall_poll();
    motor_hall_speed_poll();
    motor_overcurrent_poll();

    if (HAL_GetTick() % 50 == 0 && print_flag == 0) {
        print_flag = 1;
        adc_send_waveform_frame();
    } else if (HAL_GetTick() % 50 != 0 && print_flag == 1) {
        print_flag = 0;
    }
}

五、实验操作与现象

1. 接线

与 lesson4~6 相同:三相线 U/V/W、霍尔 HU/HV/HW(PH10~12)、SD(PE6)、TEMP/VBUS/IU/IV/IW 接驱动板接口 2。NTC 贴于电机表面。

2. 串口控制

指令 作用
d 0 正转
d 1 反转
v 1000 设置占空比/速度
v 0 停转

K1/K2 加减速,K3/K4 正反转(按下为高)。

3. 输出数据

设置查看串口数据:

通过串口输出速度波形:

可以看到转速并不稳定 。

查看霍尔值,即看转子位置:

4. 调试提示

  • 若 RPM 跳变过大:检查 MOTOR_POLE_PAIRS 是否与电机一致(本电机为 2 对极)。
  • 若 DIR 与指令相反:霍尔线序或 fwd_next[] 需按实际接线调整。
  • 若 HALL 只在 1~6 中某个值不变:检查 HU/HV/HW 接线或电机是否堵转。
  • 转速在停转后约 200 ms 自动归零,避免残留值。

六、小结

本实验使用电机内置霍尔(HU/HV/HW),在 lesson4 换相基础上复用 TIM5 Hall 接口实现:

  1. 转速:由霍尔跳变间隔(CCR1)估算机械 RPM(精度有限);
  2. 位置:累计霍尔扇区次数(粗位置,非编码器脉冲计数);
  3. 方向:由 6 状态序列判断正/反转;
  4. 统一输出:22 字节 HEX 帧同时携带 VBUS、温度、三相电流与霍尔观测量。

若需高精度速度/位置环或 FOC,应外接增量式编码器并使用 TIM 编码器模式;霍尔测速仅适合本阶段开环 + 粗反馈。下一篇可在霍尔 RPM 反馈基础上加入速度 PI 环,或另行实验外接编码器。