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 三相接入驱动板,直流母线电压由稳压电源提供,电流传感器串联在母线上或使用相电流采样电阻。
执行步骤:
- 断开电机与负载的连接,确保转子可自由转动。
- 调用
Motor_Identify(),传入注入电压、目标稳态电流、PWM频率、占空比、拖转速度和反电动势峰峰值。 - 读取返回的
Motor_Identified_t结构体,检查数值合理性。 - 调用
Apply_Motor_Params()将参数写入 FOC 库配置。
通过条件:
- Rs 测量值与万用表直接测量误差 < 10%;
- Ls 测量值与 LCR 表测量误差 < 20%;
- Ke 测量值与电机手册标称值误差 < 10%;
- 写入参数后,电流环在 1A 阶跃指令下无振荡、无啸叫,稳态误差 < 5%。
常见问题
- 电感测量偏差大:确保注入PWM频率远高于电流环带宽(通常 > 10kHz),且采样同步在PWM中心对齐,避免开关噪声。
- Ke 测量不准:拖转速度需稳定,建议使用闭环速度控制的辅助电机;若极对数未知,可先通过反电动势过零次数与机械转数之比确定。
- 写入后电流环振荡:检查 Rs 是否偏小导致 PI 增益过大,可适当降低 Kp 或增加电流环采样滤波。