基于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(&current_d_pid, id_error, CONTROL_PERIOD);
    float vq = PID_Current_q_Calculate(&current_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控制是一个复杂的系统工程,需要综合考虑硬件设计、软件算法和实际调试。建议从以下步骤开始:

  1. 先实现基础的SVPWM生成和电流采样
  2. 添加Clarke/Park变换和逆变换
  3. 实现电流环控制
  4. 添加速度环和位置环控制
  5. 最后实现无传感器算法(如果需要)
posted @ 2025-09-18 16:04  躲雨小伙  阅读(771)  评论(0)    收藏  举报