基于STM32的永磁同步电机(PMSM)FOC控制方案
概述
永磁同步电机(PMSM)的磁场定向控制(FOC)是一种高性能电机控制技术,通过对电机电流的矢量控制,实现高效率、高精度的转矩和速度控制。下面我将为您提供一个完整的基于STM32的PMSM FOC控制方案。
系统架构
graph TD
A[PMSM电机] --> B[三相逆变器]
B --> C[电流采样电路]
B --> D[位置/速度传感器]
C --> E[STM32 MCU]
D --> E
E --> F[FOC控制算法]
F --> G[SVPWM生成]
G --> B
H[用户指令] --> E
硬件设计
1. 主控芯片选择
- STM32F4系列:STM32F405/415/407/417,带有FPU和高级定时器
- STM32F3系列:STM32F302/303,内置高级模拟外设
- STM32G4系列:专门为数字电源和电机控制设计
2. 功率驱动电路
- MOSFET/IGBT三相逆变桥
- 栅极驱动芯片:如IR2101/IR2103, IRS2336等
- 电流采样电阻或霍尔电流传感器
- 过流/过压保护电路
3. 传感器系统
- 电流传感器:至少两相电流采样
- 位置传感器:
- 编码器(增量式/绝对式)
- 霍尔传感器
- 无传感器算法(适用于中高速)
软件实现
1. FOC核心算法
Clarke变换 (3相→2相)
typedef struct {
float a;
float b;
float c;
} ThreePhase_t;
typedef struct {
float alpha;
float beta;
} Clarke_t;
Clarke_t Clarke_Transform(ThreePhase_t current) {
Clarke_t clarke;
clarke.alpha = current.a;
clarke.beta = (current.a + 2 * current.b) * INV_SQRT3;
return clarke;
}
Park变换 (静止→旋转)
typedef struct {
float d;
float q;
} Park_t;
Park_t Park_Transform(Clarke_t clarke, float theta) {
Park_t park;
float sin_theta = sin(theta);
float cos_theta = cos(theta);
park.d = clarke.alpha * cos_theta + clarke.beta * sin_theta;
park.q = -clarke.alpha * sin_theta + clarke.beta * cos_theta;
return park;
}
逆Park变换 (旋转→静止)
Clarke_t Inverse_Park_Transform(Park_t park, float theta) {
Clarke_t clarke;
float sin_theta = sin(theta);
float cos_theta = cos(theta);
clarke.alpha = park.d * cos_theta - park.q * sin_theta;
clarke.beta = park.d * sin_theta + park.q * cos_theta;
return clarke;
}
SVPWM生成
void SVPWM_Generate(Clarke_t reference, PWM_HandleTypeDef *pwm) {
// 计算扇区
int sector = 0;
float v_alpha = reference.alpha;
float v_beta = reference.beta;
// 计算占空比
float t1, t2, t0;
// SVPWM算法实现...
// 设置PWM占空比
__HAL_TIM_SET_COMPARE(pwm->htim, pwm->channel_u, (uint32_t)(t1 * pwm->period));
__HAL_TIM_SET_COMPARE(pwm->htim, pwm->channel_v, (uint32_t)(t2 * pwm->period));
__HAL_TIM_SET_COMPARE(pwm->htim, pwm->channel_w, (uint32_t)(t0 * pwm->period));
}
2. PID控制器
typedef struct {
float Kp;
float Ki;
float Kd;
float integral;
float prev_error;
float output_min;
float output_max;
} PID_Controller;
float PID_Calculate(PID_Controller *pid, float error, float dt) {
// 比例项
float proportional = pid->Kp * error;
// 积分项(抗饱和)
pid->integral += error * dt;
if (pid->integral > pid->output_max) pid->integral = pid->output_max;
if (pid->integral < pid->output_min) pid->integral = pid->output_min;
float integral = pid->Ki * pid->integral;
// 微分项
float derivative = pid->Kd * (error - pid->prev_error) / dt;
pid->prev_error = error;
// 总输出
float output = proportional + integral + derivative;
// 输出限幅
if (output > pid->output_max) output = pid->output_max;
if (output < pid->output_min) output = pid->output_min;
return output;
}
3. 主控制循环
void FOC_Control_Loop(void) {
// 读取电流和位置
ThreePhase_t current = Read_Phase_Currents();
float theta = Read_Rotor_Angle();
float speed = Read_Rotor_Speed();
// Clarke变换
Clarke_t clarke = Clarke_Transform(current);
// Park变换
Park_t park = Park_Transform(clarke, theta);
// 速度PID控制(外环)
float speed_error = target_speed - speed;
float iq_ref = PID_Speed_Calculate(&speed_pid, speed_error, CONTROL_PERIOD);
// 电流PID控制(内环)
float id_error = 0 - park.d; // d轴电流控制为0(最大转矩控制)
float iq_error = iq_ref - park.q;
float vd = PID_Current_d_Calculate(¤t_d_pid, id_error, CONTROL_PERIOD);
float vq = PID_Current_q_Calculate(¤t_q_pid, iq_error, CONTROL_PERIOD);
// 逆Park变换
Park_t voltage_ref = {vd, vq};
Clarke_t clarke_ref = Inverse_Park_Transform(voltage_ref, theta);
// SVPWM生成
SVPWM_Generate(clarke_ref, &pwm_handler);
}
4. 无传感器位置估算(可选)
// 滑模观测器(SMO)实现
typedef struct {
float alpha;
float beta;
float z_alpha;
float z_beta;
float e_alpha;
float e_beta;
float k_slide;
} SMO_Observer;
void SMO_Update(SMO_Observer *smo, Clarke_t current, Clarke_t voltage, float dt) {
// 电流观测器
float i_alpha_hat = smo->alpha * smo->z_alpha + voltage.alpha;
float i_beta_hat = smo->alpha * smo->z_beta + voltage.beta;
// 误差计算
smo->e_alpha = current.alpha - i_alpha_hat;
smo->e_beta = current.beta - i_beta_hat;
// 滑模控制
float sign_alpha = smo->e_alpha > 0 ? smo->k_slide : -smo->k_slide;
float sign_beta = smo->e_beta > 0 ? smo->k_slide : -smo->k_slide;
// 反电动势估算
float emf_alpha = sign_alpha;
float emf_beta = sign_beta;
// 更新状态
smo->z_alpha += dt * (smo->beta * (current.alpha - i_alpha_hat) + emf_alpha);
smo->z_beta += dt * (smo->beta * (current.beta - i_beta_hat) + emf_beta);
// 位置估算
estimated_angle = atan2(-emf_alpha, emf_beta);
estimated_speed = (estimated_angle - prev_angle) / dt;
prev_angle = estimated_angle;
}
STM32外设配置
1. ADC配置(电流采样)
void ADC_Config(void) {
hadc1.Instance = ADC1;
hadc1.Init.Resolution = ADC_RESOLUTION_12B;
hadc1.Init.ScanConvMode = ENABLE;
hadc1.Init.ContinuousConvMode = ENABLE;
hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T1_CC1;
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc1.Init.NbrOfConversion = 2;
HAL_ADC_Init(&hadc1);
// 配置通道
ADC_ChannelConfTypeDef sConfig;
sConfig.Channel = ADC_CHANNEL_1; // U相电流
sConfig.Rank = 1;
sConfig.SamplingTime = ADC_SAMPLETIME_15CYCLES;
HAL_ADC_ConfigChannel(&hadc1, &sConfig);
sConfig.Channel = ADC_CHANNEL_2; // V相电流
sConfig.Rank = 2;
HAL_ADC_ConfigChannel(&hadc1, &sConfig);
}
2. PWM定时器配置
void PWM_Config(void) {
htim1.Instance = TIM1;
htim1.Init.Prescaler = 0;
htim1.Init.CounterMode = TIM_COUNTERMODE_CENTERALIGNED1;
htim1.Init.Period = PWM_PERIOD;
htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim1.Init.RepetitionCounter = 0;
HAL_TIM_PWM_Init(&htim1);
// PWM通道配置
TIM_OC_InitTypeDef sConfigOC;
sConfigOC.OCMode = TIM_OCMODE_PWM1;
sConfigOC.Pulse = 0;
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET;
sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;
HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1);
HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_2);
HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_3);
// 启动PWM
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_2);
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_3);
}
3. 编码器接口配置
void Encoder_Config(void) {
htim2.Instance = TIM2;
htim2.Init.Prescaler = 0;
htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
htim2.Init.Period = 0xFFFF;
htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
HAL_TIM_Encoder_Init(&htim2, TIM_ENCODERMODE_TI12);
// 启动编码器
HAL_TIM_Encoder_Start(&htim2, TIM_CHANNEL_ALL);
}
系统保护功能
1. 过流保护
void Overcurrent_Protection(void) {
float current_magnitude = sqrtf(current_d * current_d + current_q * current_q);
if (current_magnitude > MAX_CURRENT) {
// 立即关闭PWM输出
HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_1);
HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_2);
HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_3);
// 设置错误标志
system_error = OVERCURRENT_ERROR;
}
}
2. 过温保护
void Overtemperature_Protection(void) {
float temperature = Read_Temperature();
if (temperature > MAX_TEMPERATURE) {
// 降低电流限制
current_limit = REDUCED_CURRENT_LIMIT;
if (temperature > CRITICAL_TEMPERATURE) {
// 完全关闭系统
System_Shutdown();
}
}
}
参考代码 基于STM32的永磁同步电机的FOC控制方案 www.youwenfan.com/contentcnh/56715.html
调试与优化
1. 参数整定
- 电流环:带宽通常设置为1-2kHz,响应要快
- 速度环:带宽通常设置为100-200Hz,比电流环慢10倍左右
- 位置环:带宽通常设置为10-20Hz,比速度环慢10倍左右
2. 调试工具
- STM32CubeMonitor:实时监控变量
- SEGGER SystemView:分析系统实时性能
- 示波器:观察PWM波形和电流波形
基于STM32的PMSM FOC控制是一个复杂的系统工程,需要综合考虑硬件设计、软件算法和实际调试。建议从以下步骤开始:
- 先实现基础的SVPWM生成和电流采样
- 添加Clarke/Park变换和逆变换
- 实现电流环控制
- 添加速度环和位置环控制
- 最后实现无传感器算法(如果需要)

浙公网安备 33010602011771号