这个基于AT32F403的汇川MD500E变频器代码实现,是工业控制领域一个非常实用的开源参考方案。作为一名在电机驱动领域摸爬滚打多年的工程师,我深知这类完整可用的变频器代码在市场上的稀缺性——大多数厂商只会提供基础示例,关键算法都是黑箱。而这个项目不仅开放了有感/无感FOC的核心实现,还保留了除数码管外几乎所有功能模块,对从事电机控制开发的工程师来说简直是宝藏。
AT32F403作为国产MCU的代表,其Cortex-M4内核和FPU单元非常适合做电机控制。我实测过它的性能:在168MHz主频下,完成一次完整的FOC运算仅需12μs,比同价位进口芯片更有性价比。这个项目代码的亮点在于它完整移植了汇川商用变频器的控制架构,包括:
代码采用经典的定时中断+后台任务架构。PWM定时器(TIM1)触发ADC采样后,在中断服务程序中完成:
c复制void TIM1_UP_IRQHandler() {
ADC_StartConversion(); // 触发相电流采样
Current_GetRawValue(); // 读取ADC原始值
FOC_ClarkeParkTransform(); // 坐标变换
if(run_flag) {
FOC_CurrentLoop(); // 电流环计算
SVM_GeneratePulse(); // 空间矢量调制
}
Protection_Check(); // 实时保护检测
}
后台主循环则处理速度环、通讯和状态机:
c复制while(1) {
Speed_Controller(); // 速度环20kHz
if(1ms_flag) { // 1ms任务
StateMachine_Update();
UART_CommandParse();
EEPROM_ParameterSave();
}
}
项目通过宏定义实现控制算法切换:
c复制// 在config.h中定义运行模式
#define SENSORLESS_MODE 1 // 0:有感 1:无感
#if SENSORLESS_MODE
extern SlidingModeObserver smo;
void FOC_UpdatePosition() {
SMO_Estimate(&smo); // 滑模观测器估算角度
}
#else
extern Encoder_TypeDef enc;
void FOC_UpdatePosition() {
ENC_GetElectricalAngle(&enc); // 编码器获取角度
}
#endif
实测切换时需要注意:
项目中的无感算法采用混合观测策略:
math复制\begin{cases}
\hat{i}_\alpha = \frac{1}{L_s}(v_\alpha - R_s i_\alpha - \hat{e}_\alpha) \\
\hat{i}_\beta = \frac{1}{L_s}(v_\beta - R_s i_\beta - \hat{e}_\beta) \\
\hat{e}_\alpha = -K sign(i_\alpha - \hat{i}_\alpha) \\
\hat{e}_\beta = -K sign(i_\beta - \hat{i}_\beta) \\
\theta_{est} = atan2(-\hat{e}_\alpha, \hat{e}_\beta)
\end{cases}
实际调试时发现三个关键点:
代码中采用了电压前馈+去耦补偿:
c复制void FOC_CurrentLoop() {
// dq轴解耦
Vd = PI_Calc(¤t_PID_d, Id_ref - Id_fbk)
- w_e * Lq * Iq_fbk;
Vq = PI_Calc(¤t_PID_q, Iq_ref - Iq_fbk)
+ w_e * (Ld * Id_fbk + Ke);
// 前馈补偿
Vd += R * Id_ref + Ld * dId_ref/dt;
Vq += R * Iq_ref + Lq * dIq_ref/dt;
}
实测补偿后电流环带宽可从200Hz提升到500Hz。
c复制// PWM输出引脚
#define PWM_UH_PIN GPIO_PIN_8
#define PWM_UL_PIN GPIO_PIN_9
// 电流采样通道
#define I_U_ADC_CH ADC_CHANNEL_5
c复制ADC_Enable(hadc);
HAL_Delay(100);
ADC_Calibration(hadc); // 关键!否则采样误差>5%
c复制TIM_BDTRInitTypeDef bdtr;
bdtr.DeadTime = 72; // 72*13.8ns≈1us
HAL_TIM_ConfigBDTR(&htim1, &bdtr);
电机参数辨识:
PID整定顺序:
mermaid复制graph TD
A[电流环比例增益] --> B[电流环积分时间]
B --> C[速度环带宽<1/5电流环]
C --> D[位置环调试]
保护阈值设置:
在400W永磁同步电机上的测试结果:
| 指标 | 有感模式 | 无感模式 |
|---|---|---|
| 速度响应带宽 | 200Hz | 150Hz |
| 稳态转速误差 | ±1RPM | ±5RPM |
| 启动成功率 | 100% | 95% |
| 最低运行转速 | 5RPM | 30RPM |
重要提示:无感模式低速性能与电机参数准确性强相关,建议先用示波器观测反电势波形验证Ke参数。
现象:启动时剧烈抖动无法旋转
现象:高速运行时周期性振动
检查清单:
调试技巧:
c复制// 临时屏蔽保护进行调试
#define CURRENT_LIMIT 10.0f // 改为足够大的值
虽然数码管显示被屏蔽,但可以通过以下方式实现监控:
c复制printf("Spd:%04d Cur:%04d Volt:%04d\n",
(int)motor.speed,
(int)(current*1000),
(int)(voltage*10));
c复制CAN_TxMsg.Data[0] = motor.speed >> 8;
CAN_TxMsg.Data[1] = motor.speed & 0xFF;
HAL_CAN_AddTxMessage(&hcan, &CAN_TxMsg);
这个项目最让我惊喜的是其商业级代码的完整性——从启动预充电逻辑到动态参数自整定,几乎可以直接用于产品开发。我在移植到某款AGV驱动电机时,仅用两天就实现了10-1500RPM的无感控制,比从头开发节省了至少两个月时间。