永磁同步电机36问(三)——SVPWM代码实现

本文详细介绍了SVPWM(Space Vector Pulse Width Modulation)算法的实现过程,包括扇区判断、基本矢量作用时间分配和切换点计算等关键步骤,并提供了MATLAB代码实现。通过Simulink搭建的仿真模型,展示了SVPWM生成的马鞍波形,有助于深入理解和学习该算法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

学习SVPWM过后总有一种似乎学了,又好像没学的感觉,感觉懂了又好像没懂。怎么办呢,那最好的办法就是一五一十的撸一遍原理,用代码实现一下它。为了方便理解,就用与公式原理完全一一对应的代码去实现,先不管这个代码的效率了,理解了再优化。走起。

判断前的准备:Ualpha与Ubeta信号来源的构建

simulink的library搜索sine,Ualpha和Ubeta设置如下,设定频率为50Hz,幅值为300。Ualpha要超前Ubeta一个90°的相位,因此设置的区别在于Ubeta的相位初始值为 -pi/2。

写算法前看看输入信号的效果,好嘞是我想要的效果,幅值频率都对,下一步就开始写算法了。

步骤一名称:扇区判断

步骤一原理:

依据输入的Ualpha与Ubeta来判断此时的电压矢量处于哪个扇区,其判断逻辑如下图所示,通过设立 Uref1 、Uref2 、Uref3 三个判断变量,来决定ABC值的大小,并通过公式 N =4A+2B+C得到扇区号。

这里必须明确一个非常重要的点:扇区号N 与 扇区I II等是两个概念,我们后面的逻辑判断全都是用的扇区号N,而非从0-360°依次以60°区分的扇区。

步骤一代码:

Uref1 = Ubeta;
Uref2 = sqrt(3)*Ualpha/2 - Ubeta/2;
Uref3 = -sqrt(3)*Ualpha/2 - Ubeta/2;

    if Uref1>0
    A = 1;
    else
    A = 0;
    end 
    if Uref2>0
    B = 1;
    else
    B = 0;
    end  
    if Uref3>0
    C = 1;
    else
    C = 0;
    end 
   
N = 4*C + 2*B + A;

这一步也看看效果:效果就是N出来是3-1-5-4-6-2,对应0-360的旋转。

步骤二名称:基本矢量作用时间的判断与分配

步骤二原理:

算出XYZ三个基本矢量的作用时间,然后根据扇区号N对其进行分配,其分配的表格如下图所示。

 步骤二代码:

X = sqrt(3)*Ts*Ubeta/Udc;
Y = sqrt(3)*Ts/Udc*(sqrt(3)*Ualpha/2+Ubeta/2);
Z = sqrt(3)*Ts/Udc*(-sqrt(3)*Ualpha/2+Ubeta/2);

switch(N)
    case 1
        T1 = Z;
        T2 = Y;
    case 2
        T1 = Y;
        T2 = -X;
    case 3
        T1 = -Z;
        T2 = X;
    case 4
        T1 = -X;
        T2 = Z;
    case 5
        T1 = X;
        T2 = -Y; 
    case 6
        T1 = -Y;
        T2 = -Z;  
end

步骤二的代码不太好验证效果,直接进入步骤三吧。

步骤三:切换点的时间计算与分配

步骤三原理:

在计算到了基本矢量的作用时间后,也就是得到了下图公式的T4和T6之后,就需要对ABC三相进行切换点的计算,并分配到ABC三相上去。 这里需要搞清楚的一个地方记录一下:切换点是什么的问题?首先问这个切换是针对的是什么?,这个切换点是针对abc三路脉冲电平由低切换到高的点。再问生成的脉冲电平用来干什么?我们熟知的三相逆变器有6个管子,三个桥臂,驱动桥臂开关管的其实就是PWM脉冲,PWM脉冲有高有低,这个切换点实际上就是PWM高低切换的点。如果我们把这个点算出来了,那么PWM就算出来了,三相逆变器也被按照我们所想的驱动了。

步骤三代码:

Ta = (Ts - T1 - T2)/4;
Tb = Ta + T1/2;
Tc = Tb + T2/2;
switch(N)
    case 1
Tcm1 = Tb;
Tcm2 = Ta;
Tcm3 = Tc;

    case 2
Tcm1 = Ta;
Tcm2 = Tc;
Tcm3 = Tb;

    case 3
Tcm1 = Ta;
Tcm2 = Tb;
Tcm3 = Tc;

    case 4
Tcm1 = Tc;
Tcm2 = Tb;
Tcm3 = Ta;

    case 5
Tcm1 = Tc;
Tcm2 = Ta;
Tcm3 = Tb;
 
    case 6
Tcm1 = Tb;
Tcm2 = Tc;
Tcm3 = Ta;
  
end

步骤四:接口输出

到这里配置一个接口输出量(matlab的function模块输出信号不允许直接放在判断逻辑里面,否则会报错),所以最后加一小段代码。

Tc1 = Tcm1;
Tc2 = Tcm2;
Tc3 = Tcm3;

输出效果如下图所示:是不是非常美丽的马鞍波,并且其频率也是输入的50Hz。 

如果有兴趣的小伙伴,想要学习这个地方的,可以按照以上步骤搭建一下,搭建的仿真框图如下图所示:

为了方便使用,其中function部分的全代码放在下面了,大家直接复制粘贴就可以了,去试试效果吧,有深入探究的同学可以试着优化一下,我这个代码太过。。。。额。。。初级了,但是好处是便于理解。有优化好的同学可以评论区留言分享一下。

function [N,N_Sector1,Tc1,Tc2,Tc3]  = fcn(Ualpha,Ubeta)
%#codegen
persistent Uref1 Uref2 Uref3 A B C X Y Z T1 T2 Ta Tb Tc N_Sector Udc Ts Tcm1 Tcm2 Tcm3;
if isempty(Uref1)
  U1 = 0;  U2 = 0;  U3 = 0;
  A = 0;  B = 0;  C = 0;
  X = 0;  Y = 0;  Z = 0;
  T1 = 0;  T2 = 0;
  Ta = 0;  Tb = 0;  Tc = 0; 
  Tcm1 = 0;  Tcm2 = 0;  Tcm3 = 0; 
  Ts = 1/5000;
  m = sqrt(3)/540*Ts;
  N_Sector=0;
  Udc =540;
end

Uref1 = Ubeta;
Uref2 = sqrt(3)*Ualpha/2 - Ubeta/2;
Uref3 = -sqrt(3)*Ualpha/2 - Ubeta/2;

    if Uref1>0
    A = 1;
    else
    A = 0;
    end 
    if Uref2>0
    B = 1;
    else
    B = 0;
    end  
    if Uref3>0
    C = 1;
    else
    C = 0;
    end 
   
N = 4*C + 2*B + A;

switch(N)
    case 1
        N_Sector=2;
    case 2
        N_Sector=6;
    case 3
        N_Sector=1;
    case 4
        N_Sector=4;
    case 5
        N_Sector=3;
    case 6
        N_Sector=5;
end
N_Sector1 = N_Sector;

X = sqrt(3)*Ts*Ubeta/Udc;
Y = sqrt(3)*Ts/Udc*(sqrt(3)*Ualpha/2+Ubeta/2);
Z = sqrt(3)*Ts/Udc*(-sqrt(3)*Ualpha/2+Ubeta/2);

switch(N)
    case 1
        T1 = Z;
        T2 = Y;
    case 2
        T1 = Y;
        T2 = -X;
    case 3
        T1 = -Z;
        T2 = X;
    case 4
        T1 = -X;
        T2 = Z;
    case 5
        T1 = X;
        T2 = -Y; 
    case 6
        T1 = -Y;
        T2 = -Z;  
end

Ta = (Ts - T1 - T2)/4;
Tb = Ta + T1/2;
Tc = Tb + T2/2;
switch(N)
    case 1
Tcm1 = Tb;
Tcm2 = Ta;
Tcm3 = Tc;

    case 2
Tcm1 = Ta;
Tcm2 = Tc;
Tcm3 = Tb;

    case 3
Tcm1 = Ta;
Tcm2 = Tb;
Tcm3 = Tc;

    case 4
Tcm1 = Tc;
Tcm2 = Tb;
Tcm3 = Ta;

    case 5
Tcm1 = Tc;
Tcm2 = Ta;
Tcm3 = Tb;
 
    case 6
Tcm1 = Tb;
Tcm2 = Tc;
Tcm3 = Ta;
  
end
Tc1 = Tcm1;
Tc2 = Tcm2;
Tc3 = Tcm3;


这个算法大家也可以优化一下的,还是比较复杂。

### 基于SVPWM控制永磁同步电机MATLAB仿真教程 #### SVPWM控制简介 空间矢量脉宽调制(Space Vector Pulse Width Modulation, SVPWM)是一种用于逆变器输出电压波形优化的技术,能够提高直流母线电压利用率并减少谐波失真。通过合理安排开关状态的时间比例来合成期望的空间电压矢量。 #### 永磁同步电机(PMSM)建模 在MATLAB/Simulink环境中建立PMSM模型时,通常会涉及到电动机参数设置以及机械负载特性定义。对于具体应用场合下的不同规格型号电机而言,其电气常数如电阻、电感等需依据实际产品手册给定数值输入到软件平台内完成初始化配置过程[^1]。 ```matlab % PMSM 参数设定示例代码 Rs = 0.8; % 定子相绕组电阻 (Ω) Ld = 0.027; % d轴自感 (H) Lq = 0.029; % q轴自感 (H) Ke = 0.23; % 反电动势系数 (Vs/rad) Jm = 0.0006; % 转动惯量 (kg·m²) Bm = 0.002; % 黏滞摩擦系数 (Nms) pmsmParams.Rs = Rs; pmsmParams.Ld = Ld; pmsmParams.Lq = Lq; pmsmParams.Ke = Ke; pmsmParams.Jm = Jm; pmsmParams.Bm = Bm; ``` #### 构建SVPWM模块 为了实现相交流信号的有效调节,在控制系统中加入专门负责生成PWM驱动指令序列的功能单元——即所谓的"SVPWM发生器".该部分逻辑主要围绕着如何根据当前时刻所需施加至各相端口上的瞬态幅值大小来进行精确计算,并最终转换成一系列高低电平交替变化的形式作用于功率器件之上从而达到预期效果的目的[^4]. ```matlab function svpwm_out = generate_svpwm(v_ref_dq, Ts) Vdc = 500; % DC bus voltage v_alpha = real(v_ref_dq); v_beta = imag(v_ref_dq); theta = atan2(v_beta,v_alpha); mag = sqrt(v_alpha^2+v_beta^2)/Vdc; sector = floor(mod(theta*3/2/pi+1,6))+1; t1 = min(max(mag*cos(pi*(sector-1)/3-theta),0),1)*Ts; t2 = min(max((mag-sqrt(3)*(mod(sector,2)))/(sqrt(3)),0),1-t1)*Ts; switch sector case {1} svpwm_out=[t1+t2,t1,Ts-t1-t2]; case {2} svpwm_out=[Ts-t2,t1+t2,t1]; case {3} svpwm_out=[Ts-t1-t2,Ts-t1,t2]; case {4} svpwm_out=[t2,Ts-t1-t2,Ts-t1]; case {5} svpwm_out=[t1,t2,Ts-t1-t2]; otherwise svpwm_out=[t1,Ts-t1-t2,t1+t2]; end end ``` #### 整体系统集成与测试 将上述构建好的各个组件按照功能需求连接起来形成完整的闭环反馈回路结构图之后便可以开始执行初步调试工作了。此时应该特别注意观察各项指标是否满足设计之初所提出的性能要求,比如稳态误差范围内的响应时间长短等等因素均会影响到最后评判标准的确立[^3].
评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值