FOC控制源码实现与解析(基于STM32平台)
一、核心代码结构
STM32平台下FOC控制的核心代码框架,包含硬件抽象层、算法模块和通信接口:
// main.c
#include "main.h"
#include "foc.h"
#include "sensors.h"
#include "drivers.h"
// 硬件初始化
void SystemInit(void) {
HAL_Init();
SystemClock_Config();
MX_TIM1_Init(); // PWM定时器
MX_TIM2_Init(); // 编码器接口
MX_ADC1_Init(); // 电流采样
MX_USART1_UART_Init(); // 调试通信
}
// FOC主循环
int main(void) {
SystemInit();
FOC_Init(&motor, &sensor, &driver); // 初始化FOC控制器
while(1) {
FOC_SensorUpdate(&motor); // 传感器数据采集
FOC_CurrentControl(&motor); // 电流环控制
FOC_FieldWeakening(&motor); // 弱磁控制(高速时启用)
FOC_PWM_Update(&driver); // 生成PWM信号
}
}
// 磁链观测器实现(滑模观测器)
void Observer_Update(Observer_t *obs) {
float32_t error = obs->theta_mech - obs->theta_est;
obs->Ld = KalmanFilter_Update(obs->KF, error); // 基于卡尔曼滤波的参数校正
obs->iq_ref = PI_Controller(&obs->PI_iq, obs->id_ref, obs->id_actual);
}
二、关键模块实现
1. 电流环控制(Park/Clarke变换)
// clarke_park.h
typedef struct {
float32_t i_alpha;
float32_t i_beta;
float32_t i_d;
float32_t i_q;
} ClarkePark_t;
void ClarkeTransform(ClarkePark_t *cp, float32_t ia, float32_t ib, float32_t ic) {
cp->i_alpha = ia;
cp->i_beta = (2.0f/3.0f) * (ib - 0.5f*ia);
}
void ParkTransform(ClarkePark_t *cp, float32_t theta) {
cp->i_d = cp->i_alpha * cosf(theta) + cp->i_beta * sinf(theta);
cp->i_q = -cp->i_alpha * sinf(theta) + cp->i_beta * cosf(theta);
}
2. SVPWM生成(STM32 HAL实现)
// svpwm.c
void SVPWM_Generate(SVPWM_HandleTypeDef *hsvpwm, float32_t va, float32_t vb, float32_t vc) {
// 扇区判断
uint8_t sector = GetSector(va, vb, vc);
// 时间计算
float32_t T1, T2, T0;
CalculateDutyCycle(&hsvpwm->config, va, vb, vc, &T1, &T2, &T0);
// PWM更新
HAL_TIM_PWM_Start_DMA(&htim1, TIM_CHANNEL_1, (uint32_t*)&T1, 1);
HAL_TIM_PWM_Start_DMA(&htim1, TIM_CHANNEL_2, (uint32_t*)&T2, 1);
HAL_TIM_PWM_Start_DMA(&htim1, TIM_CHANNEL_3, (uint32_t*)&T0, 1);
}
3. 滑模观测器(无传感器FOC)
// observer.c
typedef struct {
float32_t theta_est; // 估计电角度
float32_t speed_est; // 估计转速
float32_t Ld; // d轴电感(在线辨识)
KalmanFilter_t KF; // 卡尔曼滤波器
} Observer_t;
void Observer_Init(Observer_t *obs) {
obs->KF.x = 0.0f; // 初始状态
obs->KF.P = 0.01f; // 初始协方差
obs->KF.Q = 0.0001f; // 过程噪声
obs->KF.R = 0.001f; // 测量噪声
}
void Observer_Update(Observer_t *obs, float32_t ia, float32_t ib, float32_t theta_mech) {
// 反电动势计算
float32_t id_ref = 0.0f; // 弱磁控制时调整
float32_t iq_ref = PI_Controller(&obs->PI_iq, obs->speed_ref, obs->speed_actual);
// 滑模面设计
float32_t s = obs->theta_est - theta_mech;
if (fabs(s) > obs->threshold) {
obs->theta_est += obs->K * s; // 滑模控制律
}
}
三、硬件适配代码
1. STM32CubeMX配置
// 生成代码时勾选以下模块:
// - HAL_TIM_PWM (TIM1用于PWM输出)
// - HAL_TIM_ENCODER (TIM2用于编码器接口)
// - HAL_ADC (ADC1用于电流采样)
// - HAL_UART (USART1用于调试)
// 生成的初始化代码示例:
void MX_TIM1_Init(void) {
TIM_OC_InitTypeDef sConfigOC = {0};
htim1.Instance = TIM1;
htim1.Init.Prescaler = 0;
htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
htim1.Init.Period = 20000-1; // 20kHz PWM频率
HAL_TIM_PWM_Init(&htim1);
sConfigOC.OCMode = TIM_OCMODE_PWM1;
sConfigOC.Pulse = 1000; // 初始占空比5%
HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1);
}
2. 电流采样处理
// adc_handler.c
void ADC_Current_Read(ADC_HandleTypeDef *hadc) {
uint32_t raw[3] = {0};
HAL_ADCEx_MultiChannelStart_DMA(hadc, raw, 3); // 三相电流采样
// 电流重构(三相→两相)
float32_t ia = (raw[0] * 3.3f / 4095.0f) - 1.65f; // 偏移校准
float32_t ib = (raw[1] * 3.3f / 4095.0f) - 1.65f;
float32_t ic = (raw[2] * 3.3f / 4095.0f) - 1.65f;
ClarkePark_Transform(&motor.cp, ia, ib, ic);
}
四、调试与优化
1. 串口调试协议
// uart_comm.c
void UART_Debug_Cmd(char *cmd) {
if (strcmp(cmd, "STATUS") == 0) {
printf("Speed: %.2f RPM | Iq: %.2f A\n", motor.speed, motor.iq);
} else if (strcmp(cmd, "SET_ID") == 0) {
motor.id_ref = atof(strstr(cmd, "=") + 1);
}
}
2. 性能优化技巧
-
死区补偿:在PWM生成时添加死区补偿值(通常0.1-0.5μs)
#define DEAD_TIME_US 0.3f TIM_SetDeadTime(TIM1, DEAD_TIME_US * 1000); // 转换为纳秒 -
抗积分饱和:
void PI_ResetIntegral(PI_HandleTypeDef *pi) { if (pi->error > pi->max_output || pi->error < -pi->max_output) { pi->integral = 0.0f; // 积分项清零 } }
参考代码 FOC控制源码 www.youwenfan.com/contentcnr/56164.html
五、调试注意事项
-
硬件安全
- 添加过流保护电路(如TVS管和采样电阻)
- 使用隔离型ADC防止干扰
-
软件调试
- 启用STM32的MPU(内存保护单元)防止指针越界
- 使用Segger SystemView进行实时任务分析
-
参数整定
- 电流环:带宽>1kHz,相位裕度>45°
- 速度环:带宽>100Hz,采用前馈补偿