1. STM32G431无感FOC驱动方案概述
在电机控制领域,无感FOC(Field-Oriented Control,磁场定向控制)技术已经成为高性能电机驱动的标配方案。相比传统的有传感器控制方式,无感FOC省去了机械位置传感器,不仅降低了系统成本,还提高了可靠性。STM32G431作为STMicroelectronics推出的高性能微控制器,其丰富的外设资源和强大的运算能力,使其成为实现无感FOC的理想平台。
本方案采用HFI(High-Frequency Injection,高频注入)与SMO(Sliding Mode Observer,滑模观测器)相结合的混合控制策略。这种组合方案完美解决了无感FOC在不同速度区间的控制难题:在零速和低速阶段,通过方波高频注入获取转子位置信息;在中高速阶段,则切换到滑模观测器进行位置估算。这种混合策略既保证了零速带载启动能力,又实现了全速域的高性能控制。
2. 硬件平台搭建与配置
2.1 STM32G431核心硬件选型
STM32G431系列MCU搭载Cortex-M4内核,主频高达170MHz,内置数学加速器和丰富的定时器资源,特别适合电机控制应用。在硬件设计时,我们需要重点关注以下几个部分:
-
功率驱动电路:采用典型的三相全桥拓扑结构,MOSFET选型需考虑电机额定电流和开关频率。对于中小功率应用(如500W以下),IR2104驱动芯片配合N沟道MOSFET(如IRF540N)是性价比很高的选择。
-
电流采样电路:推荐使用低边采样电阻配合运算放大器的方案。采样电阻值通常在5-20mΩ之间,需根据电机额定电流选择合适功率等级的电阻。运算放大器可选择专用电流检测放大器如INA240,其共模抑制比高,能有效抑制PWM开关噪声。
-
电源系统设计:需要提供稳定的3.3V数字电源和12-15V的栅极驱动电源。建议使用DC-DC降压芯片(如LM2596)为栅极驱动供电,再通过LDO(如AMS1117)为MCU提供干净的3.3V电源。
2.2 CubeMX基础配置
使用STM32CubeMX工具可以快速完成项目的基础配置。以下是几个关键配置点:
2.2.1 时钟树配置
c复制RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
// 使用8MHz外部晶振作为时钟源
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
// PLL配置:8MHz输入,340倍频,2分频输出170MHz
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = 8;
RCC_OscInitStruct.PLL.PLLN = 340;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 2;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
Error_Handler();
}
2.2.2 PWM定时器配置
高级定时器TIM1用于生成三相PWM信号,配置要点包括:
- 计数模式:中心对齐模式(更适合FOC控制)
- PWM频率:通常设置在10-20kHz之间
- 死区时间:根据MOSFET开关特性设置,通常100-500ns
c复制TIM_HandleTypeDef htim1;
htim1.Instance = TIM1;
htim1.Init.Prescaler = 0;
htim1.Init.CounterMode = TIM_COUNTERMODE_CENTERALIGNED1;
htim1.Init.Period = PWM_PERIOD; // 根据PWM频率计算
htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim1.Init.RepetitionCounter = 0;
htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
// 死区时间配置
TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = {0};
sBreakDeadTimeConfig.DeadTime = DEAD_TIME_NS; // 根据MOSFET特性设置
sBreakDeadTimeConfig.BreakState = TIM_BREAK_ENABLE;
sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH;
sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_ENABLE;
3. 高频注入算法实现
3.1 高频注入原理
高频注入技术通过在电机定子绕组中注入高频信号(通常为1-10kHz),然后检测响应信号来估算转子位置。在零速和低速区域,电机反电动势很小,传统观测器难以工作,而高频注入法却能提供可靠的位置信息。
方波高频注入相比正弦波注入有以下优势:
- 实现简单,计算量小
- 对电机参数变化不敏感
- 更适合低成本MCU实现
3.2 代码实现
高频注入的核心代码包括信号生成和位置提取两部分:
c复制// 高频注入参数配置
#define HF_FREQ 10000 // 10kHz注入频率
#define HF_AMP 0.1f // 注入幅值(标幺值)
#define HF_PHASE_SHIFT PI/2 // 90度相位差
// 高频信号生成
void HFI_GenerateInjection(float theta_elec, float* u_alpha, float* u_beta)
{
static uint32_t hf_counter = 0;
float hf_signal = HF_AMP * ((hf_counter++ % 2) ? 1.0f : -1.0f); // 方波信号
// 在alpha轴注入高频信号
*u_alpha += hf_signal;
*u_beta += hf_signal * sinf(HF_PHASE_SHIFT);
}
// 位置信息提取
float HFI_ExtractPosition(float i_alpha, float i_beta)
{
static float last_i_alpha = 0;
float delta_i_alpha = i_alpha - last_i_alpha;
last_i_alpha = i_alpha;
// 使用锁相环(PLL)提取位置信息
static float est_angle = 0;
static float est_speed = 0;
float error = delta_i_alpha * cosf(est_angle) - i_beta * sinf(est_angle);
// PLL参数
float kp = 0.1f;
float ki = 0.01f;
est_speed += ki * error;
est_angle += (est_speed + kp * error) * CONTROL_PERIOD;
return est_angle;
}
3.3 参数调试技巧
高频注入效果很大程度上取决于参数选择,以下是几个调试要点:
-
注入频率选择:
- 通常设置为PWM频率的1/5~1/2
- 过高会导致电流采样困难
- 过低会影响控制带宽
-
注入幅值调整:
- 从0.05标幺值开始尝试
- 太小会导致信噪比不足
- 太大会引起电机振动和噪声
-
位置观测器带宽:
- 通过PLL的kp和ki参数调整
- 带宽过高容易引入噪声
- 带宽过低会导致响应慢
调试提示:可以先在开环状态下观察高频响应信号,确保注入信号能够被正确检测到,再闭环调试位置观测器参数。
4. 滑模观测器设计与实现
4.1 滑模观测器原理
滑模观测器是一种非线性状态观测器,通过构造滑模面使系统状态在有限时间内收敛到期望值。在电机控制中,滑模观测器利用电机反电动势来估算转子位置,具有以下特点:
- 对参数变化鲁棒性强
- 动态响应快
- 实现相对简单
4.2 SMO核心代码
c复制// 滑模观测器参数
#define SMO_K_SLIDE 50.0f // 滑模增益
#define SMO_LPF_CUTOFF 100.0f // 低通滤波器截止频率(Hz)
typedef struct {
float alpha; // alpha轴反电动势估计值
float beta; // beta轴反电动势估计值
float angle; // 估算的电角度
float speed; // 估算的电转速(rad/s)
float lpf_coef; // 低通滤波器系数
} SMO_TypeDef;
void SMO_Update(SMO_TypeDef* smo, float i_alpha, float i_beta,
float v_alpha, float v_beta, float Rs, float Ls)
{
// 电流误差计算
static float i_alpha_est = 0, i_beta_est = 0;
float e_alpha = i_alpha - i_alpha_est;
float e_beta = i_beta - i_beta_est;
// 滑模控制量
float z_alpha = (e_alpha > 0) ? SMO_K_SLIDE : -SMO_K_SLIDE;
float z_beta = (e_beta > 0) ? SMO_K_SLIDE : -SMO_K_SLIDE;
// 反电动势观测
smo->alpha = z_alpha;
smo->beta = z_beta;
// 低通滤波
smo->alpha = smo->alpha * smo->lpf_coef + z_alpha * (1 - smo->lpf_coef);
smo->beta = smo->beta * smo->lpf_coef + z_beta * (1 - smo->lpf_coef);
// 位置估算
smo->angle = atan2f(-smo->alpha, smo->beta);
// 速度估算(可选)
static float last_angle = 0;
smo->speed = (smo->angle - last_angle) / CONTROL_PERIOD;
last_angle = smo->angle;
// 电流观测器更新
float dt = CONTROL_PERIOD;
i_alpha_est += dt * ((v_alpha - Rs*i_alpha - smo->alpha) / Ls);
i_beta_est += dt * ((v_beta - Rs*i_beta - smo->beta) / Ls);
}
4.3 参数整定方法
滑模观测器性能取决于以下几个关键参数:
-
滑模增益(SMO_K_SLIDE):
- 通常设置为反电动势幅值的2-3倍
- 增益过小会导致收敛慢
- 增益过大会引入高频抖动
-
低通滤波器截止频率:
- 建议设置为电机基波频率的5-10倍
- 太高不能有效滤除开关噪声
- 太低会延迟位置信号
-
电机参数准确性:
- 定子电阻(Rs)和电感(Ls)需要准确测量
- 参数误差会导致位置估算偏差
调试技巧:可以先固定速度运行,观察反电动势波形是否平滑,再逐步调整滑模增益和滤波器参数。
5. 混合控制策略实现
5.1 速度区间划分与切换逻辑
为了实现全速域的无感控制,需要合理划分速度区间并设计平滑的切换策略:
c复制#define SPEED_THRES_LOW 0.1f // 低速阈值(pu)
#define SPEED_THRES_HIGH 0.3f // 高速阈值(pu)
typedef enum {
CONTROL_MODE_HFI, // 高频注入模式
CONTROL_MODE_TRANS, // 过渡模式
CONTROL_MODE_SMO // 滑模观测器模式
} ControlMode_t;
ControlMode_t SelectControlMode(float speed_pu)
{
static ControlMode_t current_mode = CONTROL_MODE_HFI;
if(current_mode == CONTROL_MODE_HFI && speed_pu > SPEED_THRES_HIGH) {
current_mode = CONTROL_MODE_TRANS;
}
else if(current_mode == CONTROL_MODE_TRANS) {
// 过渡模式持续时间(约100ms)
static uint32_t trans_counter = 0;
if(++trans_counter > TRANSITION_TIME) {
current_mode = CONTROL_MODE_SMO;
trans_counter = 0;
}
}
else if(current_mode == CONTROL_MODE_SMO && speed_pu < SPEED_THRES_LOW) {
current_mode = CONTROL_MODE_HFI;
}
return current_mode;
}
5.2 混合控制实现框架
c复制void FOC_ControlLoop(void)
{
// 1. 获取当前状态
float i_alpha, i_beta = Get_Currents();
float v_alpha, v_beta = Get_Voltages();
float speed_pu = Get_Speed();
// 2. 选择控制模式
ControlMode_t mode = SelectControlMode(speed_pu);
// 3. 执行对应的控制策略
float angle_est;
switch(mode) {
case CONTROL_MODE_HFI:
// 高频注入模式
HFI_GenerateInjection(angle_est, &v_alpha, &v_beta);
angle_est = HFI_ExtractPosition(i_alpha, i_beta);
break;
case CONTROL_MODE_TRANS:
// 过渡模式:同时运行两种观测器
HFI_GenerateInjection(angle_est, &v_alpha, &v_beta);
angle_est = HFI_ExtractPosition(i_alpha, i_beta);
SMO_Update(&smo, i_alpha, i_beta, v_alpha, v_beta, Rs, Ls);
break;
case CONTROL_MODE_SMO:
// 滑模观测器模式
SMO_Update(&smo, i_alpha, i_beta, v_alpha, v_beta, Rs, Ls);
angle_est = smo.angle;
break;
}
// 4. 执行FOC控制
FOC_Run(angle_est, i_alpha, i_beta, speed_ref);
}
5.3 平滑过渡实现技巧
模式切换时的平滑过渡对系统稳定性至关重要,以下是几个实用技巧:
-
重叠运行:在过渡区间让两种观测器同时运行一段时间(如100ms),逐步切换权重。
-
角度对齐:在切换前比较两种观测器的角度差,必要时进行补偿。
-
速度匹配:确保两种模式估算的速度值接近时才进行切换。
-
抗扰动处理:切换后短时间内降低电流环带宽,减少扰动。
6. 系统调试与性能优化
6.1 调试工具与方法
-
实时数据监测:
- 使用STM32的DAC输出关键变量(如角度、速度)到示波器
- 通过SWD接口实时读取内部变量
- 使用串口发送调试数据到上位机
-
关键信号观察点:
- PWM输出波形(死区时间是否正确)
- 相电流波形(是否正弦、有无畸变)
- 估算角度与实际角度对比
-
调试步骤建议:
- 先开环运行,验证硬件和基础驱动
- 单独调试高频注入模式,验证零速启动
- 单独调试滑模观测器模式,验证中高速性能
- 最后调试模式切换逻辑
6.2 常见问题与解决方案
| 问题现象 | 可能原因 | 解决方案 |
|---|---|---|
| 零速启动失败 | 高频注入信号幅值不足 | 逐步增加注入幅值,观察电流响应 |
| 低速抖动大 | 位置观测器带宽过高 | 降低PLL的kp/ki参数 |
| 中高速失步 | 滑模增益设置不当 | 根据反电动势幅值调整滑模增益 |
| 模式切换振荡 | 角度未对齐 | 在切换前进行角度补偿 |
| 电流采样噪声大 | 采样时机不当 | 调整ADC采样点在PWM周期中的位置 |
6.3 性能优化技巧
-
计算效率优化:
- 使用STM32的硬件数学加速器(CORDIC)
- 将三角函数计算改为查表法
- 优化中断服务程序,减少计算量
-
控制性能优化:
- 采用变参数PI调节器(不同速度区间用不同参数)
- 增加前馈补偿,提高动态响应
- 实现参数自整定功能
-
代码结构优化:
- 将关键算法放在RAM中运行
- 使用DMA传输ADC数据
- 合理分配中断优先级
7. 实际应用案例
7.1 无人机电调应用
在某型无人机电调中应用本方案,实现了以下性能指标:
- 零速启动负载能力:可达额定扭矩的80%
- 速度控制精度:±0.5%额定转速
- 模式切换时间:<50ms
- 最高效率:92%@额定工况
7.2 工业伺服应用
在工业伺服系统中,该方案表现出色:
- 位置控制精度:±1个编码器脉冲(17位)
- 速度波动率:<0.1%
- 响应带宽:>500Hz
- 过载能力:300%额定电流,持续2s
7.3 家电应用
在家用电器(如空调风机)中,方案优势明显:
- 启动静音:高频注入频率超出人耳听觉范围
- 低速稳定性:可在5%额定转速下稳定运行
- 成本优势:省去了位置传感器和相关线缆
8. 开发经验分享
在实际项目开发中,有几个特别值得注意的经验点:
-
电流采样校准:
电流采样通道的偏移和增益误差会直接影响控制性能。建议在上电时自动校准偏移量,并定期检查增益误差。一个实用的校准方法是让电机在静止状态下,对所有采样通道进行多点采样平均。 -
死区补偿:
PWM死区时间虽然能防止上下管直通,但会导致输出电压失真。可以在软件中实现死区补偿,根据电流方向动态调整占空比。补偿量需要根据具体MOSFET的开关特性实验确定。 -
参数自动识别:
实现电机参数的自动识别功能可以大大提高产品适用性。通过施加特定的测试信号,可以测量出定子电阻、电感和反电动势常数等关键参数。将这些参数保存在Flash中,下次上电时直接调用。 -
故障保护机制:
完善的故障保护是产品可靠性的保证。需要实现过流、过压、欠压、过热等多重保护,并��保护阈值应根据工作状态动态调整。保护触发后应有明确的故障代码指示,方便问题排查。 -
代码可移植性:
良好的代码架构可以节省后续项目开发时间。建议将硬件相关部分(如ADC读取、PWM输出)与算法核心分离,通过函数指针或接口类实现解耦。这样更换MCU平台时,只需重写硬件驱动层。
