代码地址
一、概述
本文主要是讲述PMSM的SVPWM算法的实现,以及其中的实现的原理。
二、SVPWM的基本原理
利用六步开关之间的配合来实现三相产生的磁场为大小恒定的旋转磁场。如下:
注:由上图可知,我们可以通过互差120度,大小随着时间按正弦规律变化的3个分矢量来合成一个大小不变旋转的总矢量。
因此问题变成了:如何得到大小随着时间按正弦规律变化的3个分矢量呢?
我们知道在电机上,其实这3个分矢量就对应了电机的3个绕组,3个绕组就是互差120度的,只要再控制绕组上的电压大小按照正弦规律变化,是不是就可以得到大小不变旋转的总矢量呢?看下面电机定子的坐标系图:
因此现在我们的问题变成了,我们如何实现三相电流的电流正弦变化?
我们知道驱动器的控制电路可以简化为下图:
由上图可以知道:我们能够控制的只有6个管子的开启和关断状态。那么现在的问题又变成了如何实现开关之间的配合实现电流的正弦变化。
上面的图是SVPWM的,其实就是占空比越大,相对电压越大;占空比越小,相对电压越小。让占空比呈正弦变化,电压值自然也就呈正弦变化了。注意这里的电源电压Udc还是一个定值。只是利用了开关频率的变化,来达到等效电压的变化,--------我们得到了svpwm的很重要的一个指标“开关频率的性能指标是决定”
因此我们现在可以得到这样一个结论:
我们可以通过控制六步换向开关的的配合来实现三相绕组的电流呈现正弦值变化。三相绕组产生的磁场再合成生成磁场大小不变的旋转磁场。
那么如何实现三相绕组的相互配合那就是我们后面算法的实现功能了。
三、svpwm算法实现(matlab+simulink)
- 前期算法准备
- CLARKE变换 -----三相正弦便两项正弦(都是交流分量)
- 作用:
- 将三相交流系统(ABC)中的变量(如电流、电压)转换到两相静止坐标系(αβ),减少变量数量,同时保留原始信息。
- 原理:
- 三相系统(A、B、C)在空间上互差 120°,它们合成的效果可以用两个正交的坐标轴来表示:α 轴(与 A 相对齐) 和 β 轴(超前 α 90°)。
- Clarke 变换公式如下:
- 或更常见的矩阵形式:
- 实际代码实现中,常采用简化形式,假设三相平衡(即 i_A + i_B + i_C = 0),则 i_C 可省略,i_β 也可简化为:
结果:
得到 两相正交的交流信号 i_α 和 i_β
- 消除了三相之间的耦合,便于后续处理
- 作用:
- Park 变换:从两相静止到两相旋转(交流 → 直流)
- 作用
- 将 αβ 坐标系下的 交流分量,通过旋转变换,转换到 以转子磁场方向为基准的 dq 坐标系下,从而将变化的交流信号变为相对静止的 直流信号,实现解耦控制。
- 关键点:dq 坐标系的 d 轴与转子磁场(或磁链)方向对齐,是旋转的
公式:
- 其中:
θ 是 转子的电角度(electrical angle)
- i_d:励磁电流分量(一般控制为 0,以节省电能)
- i_q:转矩电流分量(直接控制电机转矩)
结果:
将随时间变化的交流信号,转换为 相对稳定的直流信号 i_d 和 i_q
- 便于使用 PI 控制器 分别独立控制转矩与磁场
- 作用
- 反 Clarke 变换:从两相旋转回到三相静止
作用
在控制算法的最后一步,我们需要将 dq 坐标系下经过 PI 控制后的 i_d 和 i_q,重新转换回三相交流信号,用于生成 PWM 信号驱动逆变器,进而控制电机。但首先需要经过 反 Park 变换,把直流信号变回两相交流信号,然后再通过 反 Clarke 变换 得到三相信号。不过我们先讲 反 Clarke:
公式(反 Clarke,从 αβ → ABC)
- 或矩阵形式:
结果
- 得到三相交流电流/电压信号,用于生成三相全桥 PWM 驱动
- 反PARK变换--直流分量变交流分量
作用
- 在得到 PI 控制器输出的 i_d 和 i_q(直流) 后,需要将它们 还原到旋转的两相坐标系 αβ 上,因为最终我们要回到三相系统。
公式
- 与 Park 变换互为逆过程,θ 同样是电角度
结果
- 得到 两相交流信号 i_α 和 i_β,但是它们已经是基于当前转子位置的“正确方向”了。z
- 扇区判断:确定电压矢量所在扇区(用于 SVPWM)
在 SVPWM(空间矢量脉宽调制)调制策略中,为了合成任意方向和大小的电压矢量,我们需要将其分解为 两个相邻的基本电压矢量 以及 零矢量,并通过合理分配它们的作用时间来实现精确控制。然而,不同的电压矢量位于不同的扇区(Sector),每个扇区覆盖 60° 的电角度范围,总共分为 6 个扇区(Sector 1 ~ Sector 6)。因此,在进行 SVPWM 调制之前,必须先判断当前目标电压矢量(通常由 Valpha 和 Vbeta,或者由三相电压/电流间接推导得出)位于哪个扇区,以便确定参与合成的两个基本矢量及其作用时间分配策略。
作用:
扇区判断的目的是确定目标电压矢量在空间中的大致方位,即位于 6 个扇区中的哪一个,从而为后续的 SVPWM 调制中选择正确的基本电压矢量组合与作用时间提供依据
原理:
扇区判断通常基于 两相旋转坐标系下的电压分量(Valpha, Vbeta),或者 三相电压/电流的符号组合,通过计算目标电压矢量的角度区间,将其映射到 0° ~ 360° 范围内的 6 个 60° 扇区之一。
一种常用的简化方法是 根据三相电压(或电流)的符号(正/负)组合,得到一个 0~7 的数字(即三相全波的 8 种状态),再通过查表或逻辑判断,映射为 1~6 的有效扇区编号,或者剔除无效状态(如全正或全负)。
代码
function [A, B, C, N] = CalculateABCAndSector(Ualpha, Ubeta) % CALCULATEABCANDSECTOR - 根据Ualpha和Ubeta计算A/B/C三相电压及扇区N % % 输入: % Ualpha - α轴电压分量(标量) % Ubeta - β轴电压分量(标量) % % 输出: % A, B, C - 三相电压(通过Clarke逆变换近似计算) % N - 扇区编号(1~6,根据Ualpha和Ubeta判断SVPWM扇区) % ===== 1. 计算 A, B, C(Clarke逆变换近似)===== A = Ubeta; B = (sqrt(3)/2) * Ualpha - (1/2) * Ubeta; C = -(sqrt(3)/2) * Ualpha - (1/2) * Ubeta; % ===== 2. 判断扇区 N(1~6,用于SVPWM)===== % 基于 Ualpha 和 Ubeta 的符号与大小,判断目标电压矢量所在扇区 theta_rad = atan2(Ubeta, Ualpha); % 计算角度(弧度),范围 [-pi, pi] theta_deg = rad2deg(theta_rad); % 转为角度 [-180°, 180°] % 将角度归一化到 [0°, 360°] if theta_deg < 0 theta_deg = theta_deg + 360; end % 划分扇区(每60°一个扇区,共6个扇区,编号 1~6) sector = floor(theta_deg / 60) + 1; % 限制在 1~6 范围内(防止由于计算误差导致越界) N = min(max(sector, 1), 6); % 可选:如果你想用更简单的 A/B/C 符号法(如三相全波8状态法)判断扇区,可用下面代码: % [N_alt, A, B, C] = SectorByABCSigns(Ualpha, Ubeta); % 如果你定义了这个函数 end
结果
得到一个 扇区编号(通常为 1 ~ 6),代表当前目标电压矢量位于哪个 60° 的扇区区间。
- 该编号用于 SVPWM 调制中确定哪两个基本电压矢量参与合成,以及各自的作用时间如何分配。
- 扇区判断是连接 坐标变换、PI 控制、与 PWM 调制 的重要桥梁,直接影响合成电压的准确性与系统动态性能。
- 仿真步骤
- 我们设d轴和q轴的分量分别是1.0、0.0;(我应该是后续设置的有问题,正常是d轴是0.0);
- 反CLARKE变换(直流分量变换交流分量)
- 输入
- d轴值
- q轴值
- 输出
- Ualpha
- Ubeta
- 输入
- 扇区判断
m文件代码
function N =SectorJudge(A,B,C) N=0; if A>0 N=N+1; end if B>0 N=N+2; end if C>0 N=N+4; end- 输入
- Ualpha
- Ubeta
- 输出
- 扇区 N (3-1-5-4-6-2);
- 矢量作用时间计算
- 代码
function [Ta,Tb] =VectorCalculate(N,Valpha,Vbeta,Udc,Tpwm ) Ta=double(0); Tb=double(0); X=(sqrt(3)*Tpwm)/Udc*Vbeta; Y=(sqrt(3)*Tpwm)/Udc*((sqrt(3)/2)*Valpha-(1/2)*Vbeta); Z=(sqrt(3)*Tpwm)/Udc*(-(sqrt(3)/2)*Valpha-(1/2)*Vbeta); if N==3 %1% Ta=Y; Tb=X; end if N==1 %2% Ta=-Y; Tb=-Z; end if N==5 %3% Ta=X; Tb=Z; end if N==4 %4% Ta=-X; Tb=-Y; end if N==6 %5% Ta=Z; Tb=Y; end if N==2 %6% Ta=-Z; Tb=-X; end- 输入
- 扇区 N
- Uaplha
- Ubeta
- Udc线电压(本文设置的是24意思是线电压是24V)
- Tpwm (本文设置的是8400)
- 注:
Tpwm是 PWM 控制周期的时间长度(单位通常是秒 s 或微秒 μs),它是用来将电压指令(Valpha, Vbeta)转换为各个扇区基本电压矢量的作用时间(如 Ta, Tb)的基准时间。
- 注:
- 输出
- Ta、Tb;
Ta:第一个基本非零电压矢量(例如 U2)的作用时间
- Tb:第二个基本非零电压矢量(例如 U3)的作用时间
- Ta、Tb;
- CCR值的计算
- 输入
- N 扇区
- Ta
- Tb
- Tpwm
- 输出
- CCR1 (U相的电压输出波形)
- CCR2(V相的电压输出波形)
- CCR3(W相的电压输出波形)
- value1(后续并未用到仅供理解马鞍波)
- value2(后续并未用到仅供理解马鞍波)
- value3(后续并未用到仅供理解马鞍波)
- 代码
- 输入
function [CH1,CH1N,CH2,CH2N,CH3,CH3N] =PWM(CNT,CCR1,CCR2,CCR3) if CNT<CCR1 CH1=0; CH1N=1; else CH1=1; CH1N=0; end if CNT<CCR2 CH2=0; CH2N=1; else CH2=1; CH2N=0; end if CNT<CCR3 CH3=0; CH3N=1; else CH3=1; CH3N=0; end- 示例
- 输入波形
- 输出波形
- CRR1/CCR2/CCR3
- value1/value2/value3
- 六步换向开关控制
- 输入
- CNT 定时器
- CCR1/CCR2/CCR3
- CNT 定时器
- 输出
- CH1/CH1N
- CH2/CH2N
- CH3/CH3N
- 注意其中的区别:
注:上述三图可以明显的看到 六步开关的开启和关断的先后顺序以及开启关断时间是发生变化的。
- 逆变器(Two-Level Converter)
- 输入
- 六步开关的开启和关断
- 电源电压
- 输出
- A/B/C(U/V/W)三相电压
- PMSM直流无刷电机
- 输入
- Tm 负载\
- A/B/C 三相电流
- 输出
- 三相电流电压
- 角速度
- 角位置
- 三相霍尔值
- 注:可以利用这些做foc闭环控制。
四、结束语
至此我已经将SVPWM的开环控制已经全部描述完毕。能够实现我们开始功能。至此我后续还会在实物上的开发资料进行整理并加以分享,敬请期待。
附件:matlab 2024b 的simulink文件一份。文件可以直接运行。