SVPWM 空间矢量调制原理与实现

系列:电机控制系列 - 第 6 篇 目标平台:STM32F407ZGT6 阅读时间:35 分钟

前言

SVPWM 是 FOC 的核心调制技术

  • ✅ 直流电压利用率高(比 SPWM 高 15%)
  • ✅ 谐波小、转矩脉动低
  • ✅ 适合数字化实现

本篇目标

  • 理解空间矢量基本概念
  • 掌握扇区判断与时间计算
  • 实现完整的 SVPWM 代码

一、空间矢量基本概念

1.1 电压空间矢量

定义

 V_ref = (2/3) × (Va + Vb·e^(j120°) + Vc·e^(j240°))
 
 其中:
 - Va, Vb, Vc:三相电压
 - e^(jθ):复数旋转算子

几何意义

  • 三相电压 → 旋转矢量
  • 以电角速度 ω 旋转
  • 幅值 = 电压幅值

1.2 八个基本矢量

三相逆变桥的 8 种状态

 ┌─────┬───────┬────────────────┬────────┐
 │矢量 │开关状态│ 电压矢量 (α, β) │  类型  │
 ├─────┼───────┼────────────────┼────────┤
 │ V0  │ 000   │ (0, 0)         │ 零矢量 │
 │ V1  │ 100   │ (2/3·Udc, 0)   │ 有效   │
 │ V2  │ 110   │ (1/3·Udc, √3/3·Udc) │ 有效 │
 │ V3  │ 010   │ (-1/3·Udc, √3/3·Udc)│ 有效 │
 │ V4  │ 011   │ (-2/3·Udc, 0)  │ 有效   │
 │ V5  │ 001   │ (-1/3·Udc, -√3/3·Udc)│ 有效│
 │ V6  │ 101   │ (1/3·Udc, -√3/3·Udc) │ 有效│
 │ V7  │ 111   │ (0, 0)         │ 零矢量 │
 └─────┴───────┴────────────────┴────────┘

六边形轨迹

             V3 (010)
               /\
              /  \
             /    \
      V4 (011)______\ V2 (110)
           / \    /
          /   \  /
         /_____\/_____
    V5 (001)  V0/V7  V1 (100)
             V6 (101)
 
 六个有效矢量构成正六边形

1.3 伏秒平衡原理

核心思想

 在一个 PWM 周期 T_pwm 内:
 V_ref × T_pwm = V1 × T1 + V2 × T2 + V0 × T0
 
 其中:
 - V_ref:参考电压矢量
 - V1, V2:相邻两个有效矢量
 - V0:零矢量(V0 或 V7)
 - T1, T2, T0:作用时间
 - T_pwm = T1 + T2 + T0

物理意义

  • 用相邻矢量合成任意方向电压
  • 时间加权平均 = 目标电压

二、SVPWM 实现步骤

2.1 扇区判断

方法 1:角度法

 int Get_Sector(float theta) {
     // theta ∈ [0, 2π)
     theta = fmodf(theta, 2.0f * M_PI);
     if (theta < 0) theta += 2.0f * M_PI;
     
     // 每个扇区 60° = π/3
     return (int)(theta / (M_PI / 3.0f)) + 1;
 }

方法 2:比较法(更快)

 int Get_Sector_Fast(float v_alpha, float v_beta) {
     int sector = 0;
     
     // 计算三个参考值
     float A = v_beta;
     float B = -0.5f * v_beta + 0.866025f * v_alpha;
     float C = -0.5f * v_beta - 0.866025f * v_alpha;
     
     // 判断扇区
     if (A > 0) sector = 1;
     if (B > 0) sector |= 2;
     if (C > 0) sector |= 4;
     
     // 扇区映射
     switch (sector) {
         case 1: return 2;
         case 2: return 6;
         case 3: return 1;
         case 4: return 4;
         case 5: return 3;
         case 6: return 5;
         default: return 1;
     }
 }

2.2 时间计算

以第 1 扇区为例

 参考电压 V_ref 在第 1 扇区(V1 和 V2 之间)
 
 V1 = (2/3·Udc, 0)
 V2 = (1/3·Udc, √3/3·Udc)
 
 伏秒平衡方程:
 [Vα]   [2/3·Udc  1/3·Udc] [T1]   [Vα_ref × T_pwm]
 [Vβ] = [0        √3/3·Udc] [T2] = [Vβ_ref × T_pwm]
 
 解得:
 T1 = T_pwm × (√3·Vβ_ref) / Udc
 T2 = T_pwm × (3·Vα_ref + √3·Vβ_ref) / (2·Udc)
 T0 = T_pwm - T1 - T2

通用公式

 void Calc_Time(float v_alpha, float v_beta, float vdc, float T_pwm,
                float *T1, float *T2, float *T0, int sector) {
     float X = v_alpha / vdc;
     float Y = (v_alpha + 1.7320508f * v_beta) / vdc;
     float Z = (v_alpha - 1.7320508f * v_beta) / vdc;
     
     switch (sector) {
         case 1:
             *T1 = T_pwm * Z;
             *T2 = T_pwm * Y;
             break;
         case 2:
             *T1 = T_pwm * (-Z);
             *T2 = T_pwm * X;
             break;
         case 3:
             *T1 = T_pwm * (-Y);
             *T2 = T_pwm * (-Z);
             break;
         // ... 其他扇区
     }
     
     *T0 = T_pwm - *T1 - *T2;
     
     // 过调制处理
     if (*T0 < 0) {
         float scale = T_pwm / (*T1 + *T2);
         *T1 *= scale;
         *T2 *= scale;
         *T0 = 0;
     }
 }

2.3 占空比更新

七段式 SVPWM

第 1 扇区(V0-V1-V2-V7-V2-V1-V0):

     ┌──┐   ┌──────┐ ┌──────┐ ┌──┐
     │V0│   │  V1  │ │  V2  │ │V7│
─────┘  └───┘      └─┘      └─┘  └───
     └T0/4┘└  T1  ┘└  T2  ┘└T0/2┘

占空比计算:
CCR1 = (T0/4 + T1/2 + T2/2) / T_pwm × ARR
CCR2 = (T0/4 + T2/2) / T_pwm × ARR
CCR3 = T0/4 / T_pwm × ARR

代码实现

void SVPWM_Update_Duty(int sector, float T1, float T2, float T0, float T_pwm) {
    float Ta, Tb, Tc;

    switch (sector) {
        case 1:
            Ta = (T0/4 + T1/2 + T2/2);
            Tb = (T0/4 + T2/2);
            Tc = T0/4;
            break;
        case 2:
            Ta = (T0/4 + T2/2);
            Tb = (T0/4 + T1/2 + T2/2);
            Tc = T0/4;
            break;
        case 3:
            Ta = T0/4;
            Tb = (T0/4 + T1/2 + T2/2);
            Tc = (T0/4 + T2/2);
            break;
        // ... 其他扇区
    }

    // 转换为占空比
    uint16_t arr = TIM1->ARR;
    TIM1->CCR1 = (uint16_t)(Ta / T_pwm * arr);
    TIM1->CCR2 = (uint16_t)(Tb / T_pwm * arr);
    TIM1->CCR3 = (uint16_t)(Tc / T_pwm * arr);
}

三、完整 SVPWM 代码

/**
 * @file svpwm.c
 * @brief SVPWM 调制实现
 */

#include <math.h>

/**
 * @brief SVPWM 主函数
 */
void SVPWM_Control(float v_alpha, float v_beta, float vdc) {
    float T_pwm = 1.0f / PWM_FREQUENCY;

    // 1. 扇区判断
    int sector = Get_Sector_Fast(v_alpha, v_beta);

    // 2. 时间计算
    float T1, T2, T0;
    Calc_Time(v_alpha, v_beta, vdc, T_pwm, &T1, &T2, &T0, sector);

    // 3. 更新 PWM 占空比
    SVPWM_Update_Duty(sector, T1, T2, T0, T_pwm);
}

四、SVPWM vs SPWM

对比项SPWMSVPWM
直流电压利用率50%90.6% (+15%)
谐波较大较小
转矩脉动较大较小
计算复杂度简单中等
应用场景通用电机控制(优选)

五、总结

SVPWM 核心要点

  1. 八个基本矢量(6 有效 + 2 零)
  2. 伏秒平衡原理
  3. 扇区判断 + 时间计算 + 占空比更新

下一篇ADC 与电流采样

最后修改:2026 年 03 月 14 日
如果觉得我的文章对你有用,请随意赞赏