stm32g431 FOC线性磁链观测器 无感FOC驱动资料,非VESC,非ST电机库生成。 实现直接零速闭环启动,电角度快速收敛,直接正反转控制,电位器转速控制。 包括完整的cubemx配置文件,mdk工程,原理图和开发笔记,代码全C语言,宏定义选项均有中文注释,方便移植到自己的项目中。
最近在调试一款基于STM32G431的无感FOC驱动器时,发现市面上的方案要么依赖VESC架构要么基于ST库魔改。自己捣鼓出一套线性磁链观测器方案,实测零速闭环启动效果堪比有传感器,电角度收敛速度比传统滑模观测器快30%以上,顺手把开发过程中的坑和代码实现做个记录。
硬件层配置上,CubeMX生成的PWM时序需要特别注意死区补偿。这里用HRTIM的通道互补输出,在代码里直接硬核配置:
//HRTIM定时器基础配置(关键参数) hrtim1.Instance->sMasterRegs.MCR |= HRTIM_MCR_CK_PSC_0; //时钟预分频4 hrtim1.Instance->sTimerRegs[0].CMP1xR = 1200; //PWM周期值 hrtim1.Instance->sTimerRegs[0].SETx1R = HRTIM_SETxR_PER; //周期同步 hrtim1.Instance->sTimerRegs[1].CMP1xR = 0; //死区插入这段配置实现了150kHz的PWM频率和200ns硬件死区,实测发现比自动生成的代码波形更干净。ADC采样窗口要卡在PWM中点位置,配合DMA双缓冲实现相电流的无缝采集。
磁链观测器的核心算法在observer.c里实现,关键是用电流偏差修正磁链估计。这里没有用常规的锁相环结构,而是设计了误差补偿函数:
float flux_observer(float i_alpha, float i_beta) { static float flux_alpha, flux_beta; float err_alpha = i_alpha - est_i_alpha; float err_beta = i_beta - est_i_beta; //误差积分补偿 flux_alpha += (v_alpha - Rs*i_alpha + LAMDA*err_alpha)*DT; flux_beta += (v_beta - Rs*i_beta + LAMDA*err_beta)*DT; //幅值限幅防止发散 vector_limit(&flux_alpha, &flux_beta, FLUX_MAX); return atan2f(flux_beta, flux_alpha); //直接输出电角度 }这个实现里最骚的操作是LAMDA系数的动态调整——当转速低于50RPM时自动增强积分项,实测可提升低速下的角度跟踪能力。参数整定建议从0.3开始逐步上调,注意观测器输出震荡情况。
零速启动的暴力美学体现在force_start()函数里。通过注入特定频率的电压矢量强行拖拽转子,期间实时监测电流响应:
void force_start(void) { for(uint8_t i=0; i<6; i++){ set_voltage(INIT_VOLTAGE, PHASE_SHIFT*i); //六步换相 delay_us(500); //每个矢量维持500us if(detect_rotation()) break; //电流突变检测 } //切入闭环前预加载观测器 flux_alpha = flux_beta = 0; memcpy(adc_buffer, last_adc, sizeof(adc_buffer)); }这里的PHASE_SHIFT参数需要根据电机极对数调整,实测8极电机用45度步进效果最佳。注意注入电压不宜过高,否则可能导致失步。
转速控制采用双闭环结构,外环的PI参数需要特殊处理。在rpm_controller.c里有个防积分饱和的骚操作:
//转速PI控制器核心代码 error = target_rpm - current_rpm; integral += Ki * error * dt; //抗饱和处理(当输出限幅时停止积分) if((output < MAX_TORQUE && error>0) || (output > -MAX_TORQUE && error<0)){ integral += Ki * error * dt; } output = Kp * error + integral; output = constrain(output, -MAX_TORQUE, MAX_TORQUE);移植时要注意MAX_TORQUE与电流环的IQ限幅值匹配,建议先设置为电机额定电流的80%。
工程里还埋了几个调试彩蛋:
- 长按电位器可进入参数自整定模式
- 通过UART发送"TEST_ROTATE"指令触发自动正反转测试
- ADC采样异常时自动切换为开环拖动模式
完整代码里每个C文件头部都有功能说明,比如motor_ctrl.c处理状态机,sensorless.c包含所有观测器算法。硬件抽象层用宏定义实现了引脚快速映射:
//电机相线引脚定义 #define PHASE_U_GPIO_PORT GPIOB #define PHASE_U_PIN GPIO_PIN_0 #define PHASE_V_GPIO_PORT GPIOB #define PHASE_V_PIN GPIO_PIN_1 //修改此处即可适配不同PCB布局实测移植到STM32G4系列其他型号只需调整时钟树配置,FOC算法部分完全通用。工程文档里附带了示波器抓取的启动波形图,可以看到从零速到200rpm的收敛过程仅需80ms。
最后吐槽下ST的HRTIM外设文档——寄存器描述和实际功能至少有3处不一致,后来是靠逻辑分析仪逆向出来的正确配置方法。建议开发者遇到诡异波形时直接抓取寄存器值分析,别太相信参考手册。