2. 电机参数辨识与配置

任务目标

本案例完成对一台无刷直流电机(BLDC)或永磁同步电机(PMSM)的电气参数辨识:相电阻 Rs、相电感 Ls 和反电动势常数 Ke,并将辨识结果写入 FOC 库的电机配置结构体,使电流环 PI 参数能够依据真实电机参数进行整定。

辨识原理与所需设备

采用静态注入法:向电机任意两相之间注入直流电压,测量稳态电流得到相电阻;注入高频方波电压,测量电流纹波得到相电感;以恒定速度拖转电机,测量相反电动势幅值得到 Ke。所需设备:直流稳压电源(可编程限流)、电流探头或采样电阻、示波器、以及一个用于拖转电机的辅助电机或手摇柄。

关键完整代码

// motor_identify.h
#ifndef MOTOR_IDENTIFY_H
#define MOTOR_IDENTIFY_H

#include "foc_config.h"  // 包含 Motor_Params_t 结构体定义

typedef struct {
    float Rs;          // 相电阻,单位 Ohm
    float Ls;          // 相电感,单位 H
    float Ke;          // 反电动势常数,单位 V/(rad/s)
    float pole_pairs;  // 极对数(需人工输入或编码器测量)
} Motor_Identified_t;

// 辨识主函数:phase_pair 选择注入相(0=AB, 1=BC, 2=CA)
Motor_Identified_t Motor_Identify(float v_inject, float i_steady_max,
                                  float f_pwm, float duty_high,
                                  float speed_rad_s, float emf_pp_voltage);

#endif
// motor_identify.c
#include "motor_identify.h"
#include <math.h>

// 内部辅助:测量两相间稳态电阻
static float Measure_Rs(float v_inject, float i_steady) {
    // 两相串联电阻 = 2*Rs,因此 Rs = V/I / 2
    return (v_inject / i_steady) / 2.0f;
}

// 内部辅助:通过电流纹波计算电感
static float Measure_Ls(float v_bus, float duty, float f_pwm,
                        float di_peak, float rs_known) {
    // 施加在相绕组上的有效电压 V_eff = duty * V_bus - I*Rs(忽略时取近似)
    // 电感 L = V_eff * dt / di,其中 dt = duty / f_pwm(导通时间)
    float dt = duty / f_pwm;
    float v_eff = duty * v_bus;  // 忽略电阻压降的简化计算
    float l_series = v_eff * dt / di_peak;  // 两相串联电感 = 2*Ls
    return l_series / 2.0f;
}

Motor_Identified_t Motor_Identify(float v_inject, float i_steady_max,
                                  float f_pwm, float duty_high,
                                  float speed_rad_s, float emf_pp_voltage) {
    Motor_Identified_t result = {0};

    // 1. 相电阻测量(注入直流,等待电流稳定后读取)
    // 实际代码中此处应通过ADC读取稳态电流 i_steady
    float i_steady = i_steady_max;  // 由外部测量传入
    result.Rs = Measure_Rs(v_inject, i_steady);

    // 2. 相电感测量(高频PWM注入,测量电流纹波峰峰值)
    // 实际代码中 di_peak 由电流传感器在PWM周期内采样获得
    float di_peak = 0.15f;  // 示例值,实际需采样
    result.Ls = Measure_Ls(v_inject, duty_high, f_pwm, di_peak, result.Rs);

    // 3. 反电动势常数测量(外力拖转,测量线反电动势峰值)
    // emf_pp_voltage 为示波器读取的线间反电动势峰峰值
    // 相电动势峰值 = 线电动势峰值 / sqrt(3)
    float emf_phase_peak = emf_pp_voltage / sqrtf(3.0f);
    // Ke = 相电动势峰值 / 电角速度,电角速度 = 极对数 * 机械角速度
    // 此处极对数默认为1,实际需根据电机调整
    result.Ke = emf_phase_peak / speed_rad_s;

    // 极对数需外部输入,此处默认1
    result.pole_pairs = 1.0f;

    return result;
}

// 将辨识结果写入FOC库配置
void Apply_Motor_Params(Motor_Params_t* foc_params, Motor_Identified_t* id) {
    foc_params->Rs = id->Rs;
    foc_params->Ls = id->Ls;
    foc_params->Ke = id->Ke;
    foc_params->pole_pairs = (uint8_t)id->pole_pairs;
}

运行与验证方法

硬件连接:将电机 U、V、W 三相接入驱动板,直流母线电压由稳压电源提供,电流传感器串联在母线上或使用相电流采样电阻。

执行步骤:

  1. 断开电机与负载的连接,确保转子可自由转动。
  2. 调用 Motor_Identify(),传入注入电压、目标稳态电流、PWM频率、占空比、拖转速度和反电动势峰峰值。
  3. 读取返回的 Motor_Identified_t 结构体,检查数值合理性。
  4. 调用 Apply_Motor_Params() 将参数写入 FOC 库配置。

通过条件:

  • Rs 测量值与万用表直接测量误差 < 10%;
  • Ls 测量值与 LCR 表测量误差 < 20%;
  • Ke 测量值与电机手册标称值误差 < 10%;
  • 写入参数后,电流环在 1A 阶跃指令下无振荡、无啸叫,稳态误差 < 5%。
电机参数辨识流程 1. 直流注入 测稳态电流 2. 高频PWM 测电流纹波 3. 外力拖转 测反电动势 4. 写入 FOC配置 计算公式 Rs = V_inject / (2 × I_steady) Ls = (duty × V_bus × dt) / (2 × di_peak),dt = duty / f_pwm Ke = V_emf_phase_peak / (pole_pairs × ω_mech) 注:V_emf_phase_peak = V_emf_line_peak / √3 验证:与万用表/LCR表/手册值对比,误差在允许范围内

常见问题

  • 电感测量偏差大:确保注入PWM频率远高于电流环带宽(通常 > 10kHz),且采样同步在PWM中心对齐,避免开关噪声。
  • Ke 测量不准:拖转速度需稳定,建议使用闭环速度控制的辅助电机;若极对数未知,可先通过反电动势过零次数与机械转数之比确定。
  • 写入后电流环振荡:检查 Rs 是否偏小导致 PI 增益过大,可适当降低 Kp 或增加电流环采样滤波。