FOC电机控制之SVPWM原理与实现

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

今天同步一下微信公众号的内容。上次介绍了坐标变换(Clarke,Park)的原理和软件代码实现,时隔两个多月,我们接着分享FOC电机控制相关的经验,这次我们介绍SVPWM的原理和软件代码实现…


一、SVPWM原理

SVPWM(Space Vector Pulse Width Modulation),即空间矢量脉宽调制。SVPWM的理论基础是平均值等效原理,即在一个开关周期Ts内,对基本矢量电压加以组合,使其平均值与给定电压矢量相等。通过控制基本矢量电压的作用时间,使合成的目标矢量电压在空间位置按照接近圆形轨迹旋转,所产生的实际磁通去逼近一个理想的磁通圆。模型如下图所示,采样点数越多,就越逼近理想磁通圆,理论上采样点数无穷多时就是理想磁通圆了。
在这里插入图片描述
左图:基本电压矢量图; 右图:实际磁通圆轨迹示意图
加在三相绕组线圈上的端电压都为正弦电压,设峰值为Um,两两相位差120°,记为:

U A ( t ) = U m cos ⁡ θ U B ( t ) = U m cos ⁡ ( θ − 2 3 π ) U C ( t ) = U m cos ⁡ ( θ − 4 3 π ) = U m cos ⁡ ( θ + 2 3 π ) \begin{array}{l} {U_A}(t) = {U_m}\cos \theta \\ {U_B}(t) = {U_m}\cos (\theta - \frac{2}{3}\pi )\\ {U_C}(t) = {U_m}\cos (\theta - \frac{4}{3}\pi ) = {U_m}\cos (\theta + \frac{2}{3}\pi ) \end{array} UA(t)=UmcosθUB(t)=Umcos(θ32π)UC(t)=Umcos(θ34π)=Umcos(θ+32π)

注意:这里的电压是标量,只是电压幅值按正弦变化。

在二维平面上,三相绕组ABC构成的坐标系,两两坐标轴相差120°,则三相基本电压用矢量表示为:
u A ( t ) = U A ( t ) ⋅ e j 0 = U m cos ⁡ θ ⋅ e j 0 u B ( t ) = U B ( t ) ⋅ e j 2 3 π = U m cos ⁡ ( θ − 2 3 π ) ⋅ e j 2 3 π u C ( t ) = U C ( t ) ⋅ e j 4 3 π = U m cos ⁡ ( θ + 2 3 π ) ⋅ e j 4 3 π \begin{array}{l} {\boldsymbol{u}_A}(t) = {U_A}(t) \cdot {e^{j0}} = {U_m}\cos \theta \cdot {e^{j0}}\\ {\boldsymbol{u}_B}(t) = {U_B}(t) \cdot {e^{j\frac{2}{3}\pi }} = {U_m}\cos (\theta - \frac{2}{3}\pi ) \cdot {e^{j\frac{2}{3}\pi }}\\ {\boldsymbol{u}_C}(t) = {U_C}(t) \cdot {e^{j\frac{4}{3}\pi }} = {U_m}\cos (\theta + \frac{2}{3}\pi ) \cdot {e^{j\frac{4}{3}\pi }} \end{array} uA(t)=UA(t)ej0=Umcosθej0uB(t)=UB(t)ej32π=Umcos(θ32π)ej32πuC(t)=UC(t)ej34π=Umcos(θ+32π)ej34π

用欧拉公式 e i x = cos ⁡ x + i sin ⁡ x ; e − i x = cos ⁡ x − i sin ⁡ x ; cos ⁡ x = 1 2 ( e i x + e − i x ) {e^{ix}} = \cos x + i\sin x;{e^{ - ix}} = \cos x - i\sin x;\cos x = \frac{1}{2}({e^{ix}} + {e^{ - ix}}) eix=cosx+isinx;eix=cosxisinx;cosx=21(eix+eix)展开上式,并计算其矢量和: u s = u A + u B + u C {\boldsymbol{u}_s} = {\boldsymbol{u}_A} + {\boldsymbol{u}_B} + {\boldsymbol{u}_C} us=uA+uB+uC
下面是展开计算的过程:
在这里插入图片描述

在计算过程中用到了三角函数的展开公式:
cos ⁡ ( α + β ) = cos ⁡ α cos ⁡ β − sin ⁡ α sin ⁡ β cos ⁡ ( α − β ) = cos ⁡ α cos ⁡ β + sin ⁡ α sin ⁡ β \begin{array}{l} \cos (\alpha + \beta ) = \cos \alpha \cos \beta - \sin \alpha \sin \beta \\ \cos (\alpha - \beta ) = \cos \alpha \cos \beta + \sin \alpha \sin \beta \end{array} cos(α+β)=cosαcosβsinαsinβcos(αβ)=cosαcosβ+sinαsinβ

原理总结:
通过在空间位置上两两相差120°的三个基本电压来合成目标电压。三个基本电压的方向不变,幅值按正弦规律变化,相位两两相差120°;合成的目标矢量电压其幅值固定不变,为相电压峰值的1.5倍,方向在空间旋转,旋转的角速度等于相电压幅值变化的角速度。

二、SVPWM实现方法

1. 基本矢量电压:

如下图所示,逆变器的三相桥臂共有6个开关管(Q1,Q2,Q3,Q4,Q5,Q6),对于每一个半桥,同一时刻只能有一个开关管导通,即控制信号G1和G2反相,G3和G4反相,G5和G6反相,如果同一个半桥的上下桥臂同时导通则会导致电源Udc短路。逆变器三个半桥的输出分别加到电机的ABC三相绕上,三相绕组在空间位置上两两相差120°。
在这里插入图片描述
定义开关函数在这里插入图片描述

如S(A)=1表示Q1导通Q2截止,母线电压Udc加到A相绕组;

再比如S(B)=1表示Q3截止Q4导通,B相绕组连接到电源负极,即GND。

ABC三个开关函数的状态(S(A),S(B),S©)共有8种组合,分别是{(0,0,0),(0,0,1),(0,1,0),(0,1,1),(1,0,0),(1,0,1),(1,1,0),(1,1,1),},分别对应8个矢量电压,其中2个零矢量电压是 U 0 ( 0 , 0 , 0 ) {U_0}(0,0,0) U0(0,0,0) U 7 ( 1 , 1 , 1 ) {U_7}(1,1,1) U7(1,1,1),6个非零矢量电压分别是 U 1 ( 0 , 0 , 1 ) , U 2 ( 0 , 1 , 0 ) , U 3 ( 0 , 1 , 1 ) , U 4 ( 1 , 0 , 0 ) , U 5 ( 1 , 0 , 1 ) , U 6 ( 1 , 1 , 0 ) {U_1}(0,0,1),{U_2}(0,1,0),{U_3}(0,1,1),{U_4}(1,0,0),{U_5}(1,0,1),{U_6}(1,1,0) U1(0,0,1),U2(0,1,0),U3(0,1,1),U4(1,0,0),U5(1,0,1),U6(1,1,0),它们在空间位置上相邻间隔60°,将平面等分为6个扇区。

以三相绕组的公共端N点作为参考零电位,各基本矢量电压的方向如上图所示,在三相坐标系下,这6个非零基本矢量电压的幅值为Udc,具体如下表所示。
在这里插入图片描述

容易想到,通过控制开关管的状态,可以合成6个方向中任意一个方向的矢量电压;通过控制该状态下开关管的PWM占空比,可以改变该方向的矢量电压的幅值的有效值(占空比从0到100%对应矢量电压有效值从0到Udc)。比如要合成一个方向和U4相同,幅值为Udc/2的矢量电压,只需要控制G1的占空比为50%,G3,G5的占空比为0%即可;再比如要合成一个方向和U6相同,幅值为3Udc/4的矢量电压,只需要控制G1,G3的占空比为75%,G5的占空比为0%即可。

在三相坐标系下,6个基本矢量电压的幅值都为Udc,转换到αβ两相坐标系下,基本矢量电压的幅值为2*Udc/3(为什么是2/3倍这个问题困扰了我好久才弄清楚了,下面简单说明一下)。

以基本矢量电压U1为例,U1(001)在abc三相坐标系下的幅值为Udc,他由 U a = − 1 3 U d c , U b = − 1 3 U d c , U c = 2 3 U d c {U_a} = - \frac{1}{3}{U_{dc}},{U_b} = - \frac{1}{3}{U_{dc}},{U_c} = \frac{2}{3}{U_{dc}} Ua=31Udc,Ub=31Udc,Uc=32Udc合成。经过clarke变换,得到在αβ两相坐标系下的电压
[ U α U β ] = 2 3 [ 1 − 1 2 − 1 2 0 3 2 − 3 2 ] ⋅ [ U a U b U c ] = [ − 1 3 U d c − 3 3 U d c ] \left[ {\begin{matrix} {{U_\alpha }}\\ {{U_\beta }} \end{matrix}} \right] = \frac{2}{3}\left[ {\begin{matrix} 1{ - \frac{1}{2}}{ - \frac{1}{2}}\\ 0{\frac{{\sqrt 3 }}{2}}{ - \frac{{\sqrt 3 }}{2}} \end{matrix}} \right] \cdot \left[ {\begin{matrix} {{U_a}}\\ {{U_b}}\\ {{U_c}} \end{matrix}} \right] = \left[ {\begin{matrix} { - \frac{1}{3}{U_{dc}}}\\ { - \frac{{\sqrt 3 }}{3}{U_{dc}}} \end{matrix}} \right] [UαUβ]=32[12121023 23 ]UaUbUc=[31Udc33 Udc],合成在两相坐标系下的基本矢量电压U1的幅值为 U α 2 + U β 2 = 2 3 U d c \sqrt {U_\alpha ^2 + U_\beta ^2} = \frac{2}{3}{U_{dc}} Uα2+Uβ2 =32Udc,方向不变。因为我们判断扇区和PID计算的输出目标矢量电压都是在两相坐标系下进行的,故计算SVPWM也在两相坐标系下进行。

下面的介绍都是在两相坐标系下的,注意!

经过上面的步骤,已经能合成6个方向,幅值为0 ~ 2Udc/3的基本矢量电压了。接下来我们用这6个基本的矢量电压,合成一个任意方向0-360°,任意幅值0~Umax的矢量电压,即我们最终的目标矢量电压,下面计算Umax的值。

容易知道,通过这6个基本矢量电压,能够合成的最大旋转圆形目标电压,其幅值为正六边形的内切圆的半径,即 U max ⁡ = 3 2 ⋅ 2 3 U d c = 3 3 U d c {U_{\max }} = \frac{{\sqrt 3 }}{2} \cdot \frac{2}{3}{U_{dc}} = \frac{{\sqrt 3 }}{3}{U_{dc}} Umax=23 32Udc=33 Udc
回顾一下数学知识:在一个平面内,两个不共线的非零向量可以作为一个基底,两个基底的线性组合可以合成该平面内任意方向和任意大小的第三个向量。(不懂没关系,看下面就够了)

容易想到,任意一个目标电压矢量,可以由该矢量所在扇区的相邻两个基本矢量电压合成。比如扇区I的任意矢量电压Us都可以由相邻的U4和U6两个基本矢量电压合成。
在这里插入图片描述
这里的Us就是坐标变换里的Uq和Ud的矢量和,(PS:在电机控制应用中,Uq由q轴电流环PI控制器计算输出得到,同时d轴电流环还会计算输出得到一个Ud,Ud滞后Uq90°)

然后回到坐标变换去了,另一篇文章有详细讲解[另一篇文章的链接],这里只简单说明结果。

先是park逆变换,由期望输出的Uq,Ud和当前的空间位置即角度θ[在电机控制里面这里是指电角度,并不是旋转平面的角度(后面讲电角度、电机极对数和旋转角度的关系)],通过park逆变换计算Uα,Uβ。 [ U α U β ] = [ cos ⁡ θ − sin ⁡ θ sin ⁡ θ cos ⁡ θ ] ⋅ [ U d U q ] \left[ {\begin{matrix} {{U_\alpha }}\\ {{U_\beta }} \end{matrix}} \right] = \left[ {\begin{matrix} {\cos \theta }&{ - \sin \theta }\\ {\sin \theta }&{\cos \theta } \end{matrix}} \right] \cdot \left[ {\begin{matrix} {{U_d}}\\ {{U_q}} \end{matrix}} \right] [UαUβ]=[cosθsinθsinθcosθ][UdUq]
得到Uα,Uβ后,接着就是判断所在扇区

2.扇区判断:

目标矢量电压Uref就是PI控制器计算的输出Uq,Ud的矢量和,经过Park逆变换得到Uα和Uβ,空间矢量调制的第一步,就是由Uα和Uβ判断目标空间矢量电压所处的扇区。
在这里插入图片描述
由以上矢量图几何关系分析可以得到,所在扇区和需要满足的充分必要条件列表:
在这里插入图片描述

可以看出,决定扇区的基本变量有: U α , U β , U β − 3 U α , − U β − 3 U α , U β − 3 ∣ U α ∣ , − U β − 3 ∣ U α ∣ {U_\alpha },{U_\beta },{U_\beta } - \sqrt 3 {U_\alpha }, - {U_\beta } - \sqrt 3 {U_\alpha },{U_\beta } - \sqrt 3 \left| {{U_\alpha }} \right|, - {U_\beta } - \sqrt 3 \left| {{U_\alpha }} \right| Uα,Uβ,Uβ3 Uα,Uβ3 Uα,Uβ3 Uα,Uβ3 Uα,其中线性无关的只有三个(也可以取其他三个线性无关的): U β , U β − 3 U α , − U β − 3 U α {U_\beta },{U_\beta } - \sqrt 3 {U_\alpha }, - {U_\beta } - \sqrt 3 {U_\alpha } Uβ,Uβ3 Uα,Uβ3 Uα
{ U 1 = U β U 2 = 1 2 ( − U β + 3 U α ) U 3 = 1 2 ( − U β − 3 U α ) \begin{cases} {{U_1} = {U_\beta }}\\ {{U_2} = \frac{1}{2}( - {U_\beta } + \sqrt 3 {U_\alpha })}\\ {{U_3} = \frac{1}{2}( - {U_\beta } - \sqrt 3 {U_\alpha })} \end{cases} U1=UβU2=21(Uβ+3 Uα)U3=21(Uβ3 Uα)【这里有点类似Clarke逆变换,但不是哦】
在这里插入图片描述

则(A,B,C)有8种状态000,001,…………… ,111

其中(A,B,C)=(000)和(111)并不存在,另外6个状态对应6个扇区,下面做简单分析。

(A,B,C) =000时:
即U1<0,U2<0,U3<0,
即Uβ<0,由式2式3叠加得-Uβ<0,Uβ>0,和 式1冲突,故该状态不存在。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

(A,B,C) =111时:
即U1>0,U2>0,U3>0,
即Uβ>0,由式2式3叠加得-Uβ>0,Uβ<0,和 式1冲突,故该状态不存在。

综上,可以列出(A,B,C)的值和所对应的扇区关系如下表;
在这里插入图片描述
然后在程序里里面查表,根据计算的N查找对应的扇区。


3. 计算相邻两个基本矢量电压的作用时间

扇区判断结束后,就是计算相邻两个基本矢量电压的作用时间T1,T2。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

到这里,计算出来的公式看着有点复杂,所以我们通过下面的方式稍稍简化一下,记: { K = 3 T s U d c U x = U β U y = 3 2 U α − 1 2 U β U z = 3 2 U α + 1 2 U β \begin{cases} {K = \frac{{\sqrt 3 {T_s}}}{{{U_{dc}}}}}\\ {{U_x} = {U_\beta }}\\ {{U_y} = \frac{{\sqrt 3 }}{2}{U_\alpha } - \frac{1}{2}{U_\beta }}\\ {{U_z} = \frac{{\sqrt 3 }}{2}{U_\alpha } + \frac{1}{2}{U_\beta }} \end{cases} K=Udc3 TsUx=UβUy=23 Uα21UβUz=23 Uα+21Uβ,则在各个扇区内的作用时间就分别为:
在这里插入图片描述

到这里,合成目标矢量电压Uref需要的两个相邻矢量电压Ux,Uy以及分别作用的时间Tx,Ty就计算好了,但这里计算出来的时间不一定刚好满足 T x + T y = T s {T_x} + {T_y} = {T_s} Tx+Ty=Ts
T x + T y > T s {T_x} + {T_y}> {T_s} Tx+Ty>Ts时需要进行等比例缩小处理,处理方式如下:
T x = T x T x + T y , T y = T y T x + T y {T_x} = \frac{{{T_x}}}{{{T_x} + {T_y}}},{T_y} = \frac{{{T_y}}}{{{T_x} + {T_y}}} Tx=Tx+TyTx,Ty=Tx+TyTy
T x + T y < T s {T_x} + {T_y} < {T_s} Tx+Ty<Ts时,需要引入零矢量电压:
T 0 = T 7 = 1 2 ( T s − T x − T y ) {T_0} = {T_7} = \frac{1}{2}({T_s} - {T_x} - {T_y}) T0=T7=21(TsTxTy)

4 .三路PWM占空比计算

目标矢量电压的所在扇区知道了,相邻两个基本矢量电压及其作用时间也知道了,接下来就是7段式SVPWM的生成了。所谓的7段式SVPWM,即在一个周期Ts内,基本电压矢量的作用顺序为 U 0 → U x → U y → U 7 → U y → U x → U 0 {U_0} \to {U_x} \to {U_y} \to {U_7} \to {U_y} \to {U_x} \to {U_0} U0UxUyU7UyUxU0
作用的时间分别为: 1 2 T 0 → 1 2 T x → 1 2 T y → T 7 → 1 2 T y → 1 2 T x → 1 2 T 0 \frac{1}{2}{T_0} \to \frac{1}{2}{T_x} \to \frac{1}{2}{T_y} \to {T_7} \to \frac{1}{2}{T_y} \to \frac{1}{2}{T_x} \to \frac{1}{2}{T_0} 21T021Tx21TyT721Ty21Tx21T0
以在第1扇区为例:基本电压矢量作用的顺序为 U 0 → U 4 → U 6 → U 7 → U 6 → U 4 → U 0 {U_0} \to {U_4} \to {U_6} \to {U_7} \to {U_6} \to {U_4} \to {U_0} U0U4U6U7U6U4U0,对应的三相电压波形为:
在这里插入图片描述
这里,可能会问,Tx,Ty和U4,U6是怎么对应的呢?为什么要先U4再U6呢?把各个扇区的作用顺序竖着列出来就能看出来了:
在这里插入图片描述
可以看出,从一个扇区进入相邻的另一个扇区时,只有一个基本矢量电压发生改变。即通过这样的作用顺序,可以减小开关管的切换次数,从而减少开关损耗,尤其是在负载电流较大时更应该减小开关切换次数。

然后就是根据基本矢量电压的作用时间去计算逆变H桥的占空比了,

仍然先以第1扇区为例:基本矢量电压作用的顺序为
U 0 ( 000 ) → U 4 ( 100 ) → U 6 ( 110 ) → U 7 ( 111 ) → U 6 ( 110 ) → U 4 ( 100 ) → U 0 ( 000 ) {U_0}(000) \to {U_4}(100) \to {U_6}(110) \to {U_7}(111) \to {U_6}(110) \to {U_4}(100) \to {U_0}(000) U0(000)U4(100)U6(110)U7(111)U6(110)U4(100)U0(000)
即在一个周期Ts时间内,前面定义的开关函数
S(C)=1的时间为 T c = T 7 = 1 2 ( T s − T 4 − T 6 ) {T_c} = {T_7} = \frac{1}{2}({T_s} - {T_4} - {T_6}) Tc=T7=21(TsT4T6)
S(B)=1的时间为 T b = T 7 + T 6 = T c + T 6 {T_b} = {T_7} + {T_6} = {T_c} + {T_6} Tb=T7+T6=Tc+T6
S(A)=1的时间为 T a = T 7 + T 6 + T 4 = T b + T 4 {T_a} = {T_7} + {T_6} + {T_4} = {T_b} + {T_4} Ta=T7+T6+T4=Tb+T4
对应的ABC三路PWM的占空比就分别为 T a T s , T b T s , T c T s \frac{{{T_a}}}{{{T_s}}},\frac{{{T_b}}}{{{T_s}}},\frac{{{T_c}}}{{{T_s}}} TsTa,TsTb,TsTc。注意的是,看上面的三相电压波形可知,输出的PWM波时高电平中间对齐,所以在对你所使用的微控制器MCU的PWM定时器进行配置的时候要注意设置好计数方向(一般先向上计数在向下计数)和输出极性(超过阈值为高电平)。

对于其他几个扇区类似,这里不再重复详细叙述,列个表出来
在这里插入图片描述
在这里插入图片描述
这里说明一下,前面进行Clarke变换和park变换的所有电压电流参数都是标幺值,这里的Uα和Uβ采用的也是标幺值。

我们合成的输出目标矢量电压也用标幺值表示(令Uref_max=1),并令Ts=1时,这里的系数K就等于常数1,这样的话,我们计算的时间Ta,Tb,Tc就等于占空比。下面简单证明一下why。

仍以第1扇区为例:

已知最终的目标矢量电压最大不失真的幅值为 U r e f _ max ⁡ = 3 3 U d c {U_{ref\_\max }} = \frac{{\sqrt 3 }}{3}{U_{dc}} Uref_max=33 Udc,则 K = 3 T s U d c = T s U r e f _ max ⁡ K = \frac{{\sqrt 3 {T_s}}}{{{U_{dc}}}} = \frac{{{T_s}}}{{{U_{ref\_\max }}}} K=Udc3 Ts=Uref_maxTs
我们已经计算的有 { T 4 = K ⋅ U y T 6 = K ⋅ U x \begin{cases} {{T_4} = K \cdot {U_y}}\\ {{T_6} = K \cdot {U_x}} \end{cases} {T4=KUyT6=KUx,即 { T 4 = T s U r e f _ max ⁡ ⋅ U y T 6 = T s U r e f _ max ⁡ ⋅ U x \begin{cases} {{T_4} = \frac{{{T_s}}}{{{U_{ref\_\max }}}} \cdot {U_y}}\\ {{T_6} = \frac{{{T_s}}}{{{U_{ref\_\max }}}} \cdot {U_x}} \end{cases} {T4=Uref_maxTsUyT6=Uref_maxTsUx(这里的 已经是标幺值)

U r e f _ max ⁡ = 1 {U_{ref\_\max }} = 1 Uref_max=1把目标矢量电压标幺值化,再令Ts=1,就可以把非零电压作用的时间转化为标幺值。

所以,我们在程序计算处理的时候,直接令K=1,然后按照上面列表计算出来的Ta,Tb,Tc就可以直接作为占空比了,占空比再乘以PWM定时器的计数周期值,就可以得到比较寄存器的值了,这样计算量就减小很多了,然后就完成了整个SVPWM的操作。
剩下的就是PWM定时器相关的操作了,这里不详说,后面有时间我再针对DSP和STM32这两款处理器做简要介绍。

算法流程

接着上一篇的坐标变换(上一篇链接:https://mp.weixin.qq.com/s/4PbY2FbnXcN2ai4aolGVcg)

上篇已经介绍,由park逆变换计算得到Uα,Uβ

step1:扇区判断

计算 { U 1 = U β U 2 = 1 2 ( − U β + 3 U α ) U 3 = 1 2 ( − U β − 3 U α ) \begin{cases} {{U_1} = {U_\beta }}\\ {{U_2} = \frac{1}{2}( - {U_\beta } + \sqrt 3 {U_\alpha })}\\ {{U_3} = \frac{1}{2}( - {U_\beta } - \sqrt 3 {U_\alpha })} \end{cases} U1=UβU2=21(Uβ+3 Uα)U3=21(Uβ3 Uα),根据U1,U2,U3的符号计算N=4C+2B+A,再结合扇区表判断所处的扇区。

C语言代码示例:

    v.U1 = v.Ubeta;                                         \
    v.U2 = ( v.Ualpha*0.8660254) - (v.Ubeta*0.5);           \
    v.U3 = (-v.Ualpha*0.8660254) - (v.Ubeta*0.5);           \
    v.Sector = 0;                                           \
    if(v.U1 > 0)    v.Sector += 1;                          \
    if(v.U2 > 0)    v.Sector += 2;                          \
    if(v.U3 > 0)    v.Sector += 4;                          \

step2:计算基本矢量电压作用时间(占空比)

计算 { U x = U β U y = 3 2 U α − 1 2 U β U z = 3 2 U α + 1 2 U β \begin{cases} {{U_x} = {U_\beta }}\\ {{U_y} = \frac{{\sqrt 3 }}{2}{U_\alpha } - \frac{1}{2}{U_\beta }}\\ {{U_z} = \frac{{\sqrt 3 }}{2}{U_\alpha } + \frac{1}{2}{U_\beta }} \end{cases} Ux=UβUy=23 Uα21UβUz=23 Uα+21Uβ,并根据扇区确定相邻两个基本矢量电压及其作用时间,然后对作用时间进行等比例缩小处理或引入零矢量电压处理,使得总的作用时间等于Ts,或总的占空比等于1。

C语言代码示例:

    v.Tx = v.Ubeta;                                         \
    v.Ty = ( v.Ualpha*0.8660254) + (v.Ubeta*0.5);           \
    v.Tz = (-v.Ualpha*0.8660254) + (v.Ubeta*0.5);           \
    switch(v.Sector)                                        \
    {                                                       \
        case 1:{                                            \
            v.t1=v.Tz; v.t2=v.Ty;                           \
            if((v.t1+v.t2)>1){                              \
                v.t1 = v.t1/(v.t1+v.t2);                    \
                v.t2 = v.t2/(v.t1+v.t2);                    \
            }                                               \
            v.Tb = 0.5*(1-v.t1-v.t2);                       \
            v.Ta = v.Tb + v.t1;                             \
            v.Tc = v.Ta + v.t2;}break;                      \
        case 2:{                                            \
            v.t1=v.Ty; v.t2=-v.Tx;                          \
            if((v.t1+v.t2)>1){                              \
                v.t1 = v.t1/(v.t1+v.t2);                    \
                v.t2 = v.t2/(v.t1+v.t2);                    \
            }                                               \
            v.Ta = 0.5*(1-v.t1-v.t2);                       \
            v.Tc = v.Ta + v.t1;                             \
            v.Tb = v.Tc + v.t2;}break;                      \
        case 3:{                                            \
            v.t1=-v.Tz; v.t2=v.Tx;                          \
            if((v.t1+v.t2)>1){                              \
                v.t1 = v.t1/(v.t1+v.t2);                    \
                v.t2 = v.t2/(v.t1+v.t2);                    \
            }                                               \
            v.Ta = 0.5*(1-v.t1-v.t2);                       \
            v.Tb = v.Ta + v.t1;                             \
            v.Tc = v.Tb + v.t2;}break;                      \
        case 4:{                                            \
            v.t1=-v.Tx; v.t2=v.Tz;                          \
            if((v.t1+v.t2)>1){                              \
                v.t1 = v.t1/(v.t1+v.t2);                    \
                v.t2 = v.t2/(v.t1+v.t2);                    \
            }                                               \
            v.Tc = 0.5*(1-v.t1-v.t2);                       \
            v.Tb = v.Tc + v.t1;                             \
            v.Ta = v.Tb + v.t2;}break;                      \
        case 5:{                                            \
            v.t1=v.Tx; v.t2=-v.Ty;                          \
            if((v.t1+v.t2)>1){                              \
                v.t1 = v.t1/(v.t1+v.t2);                    \
                v.t2 = v.t2/(v.t1+v.t2);                    \
            }                                               \
            v.Tb = 0.5*(1-v.t1-v.t2);                       \
            v.Tc = v.Tb + v.t1;                             \
            v.Ta = v.Tc + v.t2;}break;                      \
        case 6:{                                            \
            v.t1=-v.Ty; v.t2=-v.Tz;                         \
            if((v.t1+v.t2)>1){                              \
                v.t1 = v.t1/(v.t1+v.t2);                    \
                v.t2 = v.t2/(v.t1+v.t2);                    \
            }                                               \
            v.Tc = 0.5*(1-v.t1-v.t2);                       \
            v.Ta = v.Tc + v.t1;                             \
            v.Tb = v.Ta + v.t2;}break;                      \

step3:计算PWM定时器比较寄存器值

这个很简单,就是用占空比乘以定时器的计数周期

C语言代码如下:

EPwm1Regs.CMPA.half.CMPA = (int16)(MPeriod * Svpwm1.Ta);
EPwm2Regs.CMPA.half.CMPA = (int16)(MPeriod * Svpwm1.Tb);
EPwm3Regs.CMPA.half.CMPA = (int16)(MPeriod * Svpwm1.Tc);

tips:由于这篇文章用到的公式有点多,而公众号的文章编辑器又不支持插入公式,无奈我只能插入图片了,所以看起来排版不是很协调。感兴趣的可以留言或私信,分享PDF源文档哦。
(附上我整理的笔记链接:https://download.csdn.net/download/weixin_42887190/85812369)

最后,推销一下自己,关注一下我的微信公众号,可以更及时的收到在下的分享哦。
在这里插入图片描述

  • 67
    点赞
  • 543
    收藏
    觉得还不错? 一键收藏
  • 12
    评论
FOC(Field-Oriented Control,磁场定向控制)和SVPWM(Space Vector Pulse Width Modulation,空间矢量脉宽调制)是两种常用的电机控制技术,它们之间有以下几点区别: 1. 控制思想不同:FOC控制技术是基于磁场定向理论的一种控制方法,通过对电机的电流和磁场进行独立控制,实现对电机的高精度、高效控制;SVPWM是一种高级的PWM调制技术,通过对三相电压进行矢量变换,将其转化为一个空间矢量,再通过对矢量的调制,控制电机的输出电压和电流,实现电机的高效、稳定控制。 2. 控制精度不同:FOC控制技术具有响应速度快、控制精度高等优点,能够实现对电机的高精度、高效控制;SVPWM技术具有调制精度高、输出质量好等优点,能够实现对电机的高效、稳定控制。 3. 硬件实现不同:FOC控制技术需要使用传感器测量电机的状态信息,例如电流、速度、位置等;SVPWM技术则不需要使用传感器,可以通过软件算法实现对电机的控制。 4. 计算复杂度不同:FOC控制技术的计算复杂度较高,需要进行复杂的坐标变换和控制算法计算;SVPWM技术的计算复杂度相对较低,只需要进行简单的矢量变换和PWM调制计算。 需要注意的是,FOCSVPWM技术各有优劣,应根据具体的应用场景选择适合的控制技术。在实际应用中,还需考虑控制器的稳定性、计算复杂度、控制延迟等因素,以保证电机控制系统的有效性和稳定性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值