简介:面向电机控制与电力电子领域的研究人员和技术人员,这份PDF聚焦永磁同步电机5次、7次电流谐波的产生机理与注入补偿方法,针对转矩脉动、效率降低和电机发热等问题,提供基于Simulink的建模仿真与抑制思路。内容覆盖电机模型、谐波检测、谐波注入及PI闭环控制等模块,并展开FFT谐波幅值相位提取、相位对齐、带通滤波器应用、补偿量限制和电压限幅保护等工程细节,配有MATLAB/Simulink代码示例与补偿前后频谱对比,便于读者对照搭建模型、分析参数影响并排查调试问题;对谐波检测误差、控制器整定和补偿相位偏差等常见难点也有提示。资源包共1个PDF文件,约115KB,轻量易查阅,适合在项目方案验证和自学中快速定位关键步骤。已有51人学习,可作为PMSM电流谐波抑制入门与工程实践的参考。
1. 一套能直接跑的 PMSM 谐波抑制模型:5 次 7 次电流谐波到底是怎么被压下去的
调一台 3kW 的永磁同步电机,空载时电流波形看着还算周正,一挂上负载,示波器上的正弦波就开始长毛刺,转矩波形跟着一起哆嗦,电机外壳温度也比预期高一截。这类现场问题十有八九绕不开 5 次和 7 次电流谐波,它们由逆变器死区、绕组分布、齿槽效应和磁路饱和共同喂养出来,频率牢牢钉在基波的 5 倍和 7 倍上。这份永磁同步电机 5 次 7 次电流谐波注入补偿 Simulink 模型仿真资源,干的就是把这两根刺拔掉:在常规磁场定向控制外面挂一条谐波支路,实时把 5 次、7 次成分拎出来,生成等幅反相的注入量塞回控制环。它适合手上有 Matlab/Simulink、正在做电机控制算法验证,或者准备把抑制策略往样机上落的人;哪怕第一次接触 PMSM 建模,照着把参数填进去也能跑出频谱对比图。
2. 模型总体架构:从 FOC 双闭环到两条谐波补偿支路
拆开这份模型,最外面看是教科书式的双闭环,速度环出转矩指令,电流环拆 d/q 两路,经过反 Park 和 SVPWM 打到逆变器。真正值钱的是电流环旁边那条并行的谐波通道:它不动基波控制器的结构,只从反馈量里抽谐波,算完再叠加到电压给定上。这种「并联补偿」而不是「改写控制器」的思路,好处是基波性能不受拖累,谐波支路关掉整台电机照样能转。
2.1 顶层信号流:基波通道与谐波通道怎么并行
先把通道关系理清楚,不然后面接线一乱,模型跑起来只会得到一堆没法解释的波形。基波通道的路径是:速度给定减反馈 → 速度 PI → iq 给定;id 给定一般置零或走弱磁逻辑;d/q 电流 PI 输出 vd、vq;反 Park 出 vα、vβ;SVPWM 出六路驱动。谐波通道从哪取信号,是个要先定死的设计点。
常见做法是从 d/q 轴电流反馈取,因为 5 次、7 次谐波在静止三相里是 5 倍频、7 倍频,可一旦变换到同步旋转坐标系,它们都会变成 6 倍基频的交流脉动。也就是说,在 id、iq 上你能直接看到 300Hz 的波纹(基波 50Hz 时)。谐波支路把这部分提出来,反相后作为 vd_comp、vq_comp 叠到电流环输出上。为什么不直接改电流给定?因为电流环带宽有限,PI 对 300Hz 信号的跟踪能力很差,你把反相谐波塞进给定,PI 只会把它当成扰动去压制,最后白忙一场。改电压给定相当于绕过带宽瓶颈,直接在调制波上做文章。
模型里两条通道的汇合点就在反 Park 变换之前,也就是 vd、vq 各加一个求和模块。这一点务必在顶层用 Goto/From 标清楚,否则后期改参数时很容易把补偿量加错轴。d 轴上的补偿影响励磁分量,q 轴上的补偿影响转矩分量,5 次谐波主要落在 q 轴形成 6 次转矩脉动,补偿加错轴,你会看到电流频谱改善了但转矩脉动没动静。
2.2 被控对象参数:先把电机和逆变器钉死
谐波抑制效果好不好,一半取决于电机模型准不准。资源里的 PMSM 模块参数是这样一组值,先按这套填,跑通了再换成自己电机的铭牌数据:
% pmsm_params.m —— 电机本体与逆变器参数,建模前统一初始化 Pn = 3000; % 额定功率 W Vn = 380; % 额定线电压 V fn = 50; % 额定频率 Hz p = 4; % 极对数 Rs = 2.875; % 定子相电阻 Ohm Ld = 8.5e-3; % d 轴电感 H Lq = 8.5e-3; % q 轴电感 H(表贴式,Ld≈Lq) psi_f = 0.175; % 永磁体磁链 Wb J = 8e-4; % 转动惯量 kg*m^2 Vdc = 540; % 直流母线电压 V Ts = 1e-5; % 电力电子部分仿真步长 s这组参数里,psi_f和Ld、Lq决定了反电动势幅值和电流环增益,填错会直接改变谐波含量,你后面调补偿参数就全是在跟一个错误的被控对象较劲。Rs影响低速区的压降补偿,J只影响转速动态响应,跟谐波关系不大但会影响仿真收敛。Vdc决定了电压限幅的边界,补偿量能加多大,最终是被它卡住的。
逆变器部分,如果只关心控制算法而不关心开关纹波,用 Average-Value 型桥臂能省大量仿真时间;要看死区效应,就得换成带开关器件的 Universal Bridge,并把死区时间显式设进去,典型 2~4 微秒。死区本身就会在电流里制造 5 次、7 次为主的一系列谐波,这也是这份模型最贴近实际工况的一点:你要抑制的谐波,本身就得先被正确地产生出来。
2.3 采样率与步长:控制周期和电力电子步长必须分开
新手最容易图省事,整份模型一个步长跑到底,要么慢得跑不动,要么谐波辨识精度不够。工程上的处理是两套时间尺度:电力电子主电路用固定小步长(Ts = 1e-5),控制器部分用离散采样周期(常见 10kHz,即Ts_ctrl = 1e-4),中间用 Rate Transition 模块过渡。这样仿 1 秒大约 10 万个主电路步,速度还能接受。
采样率还直接决定谐波辨识的上限。7 次谐波在 50Hz 基波下是 350Hz,10kHz 采样下每个周期只有约 28.6 个采样点,滤波器的相位误差会比较敏感;如果要把辨识做得更干净,控制周期可以提到 20kHz。反过来,如果只跑 5 次(250Hz),10kHz 下每周期 40 个点,做带通滤波已经够用。
初始化脚本里顺手把求解器也设好,省得每次打开模型手动点:
% init_model.m —— 打开模型前跑一遍 mdl = 'pmsm_harmonic_foc'; load_system(mdl); set_param(mdl, 'Solver', 'ode4', 'FixedStep', 'Ts', ... 'StopTime', '2', 'SaveFormat', 'StructureWithTime'); assignin('base', 'Ts_ctrl', 1e-4); % 控制器采样周期 assignin('base', 'f_base', fn); % 基波频率,后面前馈要用ode4是定步长四阶龙格库塔,配固定步长跑电力电子模型比较稳;SaveFormat设成带时间结构体,导出数据做 FFT 时不用再拼时间轴。f_base单独拎出来放进工作区,是因为谐波频率要跟着转速动态变化,后面谐振控制器和坐标变换都要读它。
3. 谐波提取:Park 变换与带通滤波的两条技术路线
同一份资源里其实并存了两种提取思路,一条是用多同步旋转坐标系把谐波「转成直流」,一条是直接对 d/q 电流做带通滤波。两种都能用,但适用场合不一样,混着抄容易出问题。
3.1 多同步旋转坐标系:给 5 次 7 次谐波装个定位器
核心是一件事:在基波同步旋转坐标系里,5 次谐波是负序分量,旋转方向和基波相反;7 次是正序,旋转方向相同。所以想让某一个次数的谐波在该坐标系下变成直流量,角度得取对符号。
function [id5, iq5] = park5(ialpha, ibeta, theta_e) % 5 次谐波在基波 dq 系下是负序,旋转方向相反,角度取 -5*theta_e % 若写成 +5*theta_e,提取出来的会是负序的镜像量,相位直接错 180 度 th = -5 * theta_e; id5 = cos(th)*ialpha + sin(th)*ibeta; iq5 = -sin(th)*ialpha + cos(th)*ibeta; end function [id7, iq7] = park7(ialpha, ibeta, theta_e) % 7 次谐波为正序,角度直接取 +7*theta_e th = 7 * theta_e; id7 = cos(th)*ialpha + sin(th)*ibeta; iq7 = -sin(th)*ialpha + cos(th)*ibeta; end这两个函数吃的是 αβ 静止坐标系电流和电角度theta_e,输出的id5/iq5、id7/iq7在理想情况下是直流量(严格说是缓慢变化的量,随负载和转速漂),后面接一个低通滤波器或者 PI 就能把幅值和相位估出来。theta_e必须来自电机模型的实时电角度,不能自己搭一个恒定斜率的斜坡信号,否则转速一变,提取立刻失效。
这套方法的优点是物理意义清晰,哪个次数对应哪个旋转角速度一目了然;缺点是每加一个谐波次数就要多一路变换和滤波,5 次、7 次、11 次、13 次全上就是四路,计算量成倍涨。工程里通常只处理对转矩脉动贡献最大的一两个次数,够用就收手。
3.2 带通滤波:把 id、iq 打包成复信号一次处理
如果不想堆那么多坐标变换,另一种更省算力的写法是把 d/q 两路电流当成一个复数,一次滤波同时拿到两路的谐波分量。
function [i5, i7] = harmonic_extract(id, iq, f_base, Ts) % 把 id/iq 合成复信号,一次滤波同时处理两路,计算量减半 persistent bp5 bp7 if isempty(bp5) fs = 1/Ts; % 带宽留 ±0.5 倍基频余量,防止转速波动时谐波跑出通带 bp5 = designfilt('bandpassiir', 'FilterOrder', 4, ... 'HalfPowerFrequency1', 4.5*f_base, 'HalfPowerFrequency2', 5.5*f_base, ... 'SampleRate', fs); bp7 = designfilt('bandpassiir', 'FilterOrder', 4, ... 'HalfPowerFrequency1', 6.5*f_base, 'HalfPowerFrequency2', 7.5*f_base, ... 'SampleRate', fs); end z = id + 1j*iq; % 复信号打包 i5 = filter(bp5, z); % 实时用 filter,相位特性可控 i7 = filter(bp7, z); % 离线分析可换 filtfilt 做零相移 end几个参数值得说清楚:FilterOrder取 4 阶是计算量与选择性之间的折中,阶数再高,相位延迟会明显变大,补偿反而难对齐;通带上下限取4.5~5.5倍基频,是因为电机转速不会绝对恒定,谐波频率会跟着基波漂,带宽太窄谐波一出通带就漏检;filter是有相位延迟的因果滤波,实时系统必须用这个,filtfilt只能用在事后数据分析,别拿它跑闭环。
IIR 相比 FIR,在同样选择性下阶数低得多,对实时控制器更友好。这份模型默认就是 IIR 方案,如果你后面要往定点 DSP 上搬,这条链路可以直接复用。
3.3 FFT 校核:别把离线分析模块当成闭环控制器
模型里那个实时 FFT 模块,很多人的用法是错的。它应该承担的角色是「仪表」,不是「控制器」。用它量出谐波幅值相位没问题,但把 FFT 结果直接拿去生成补偿指令,就会掉进延迟和整周期截断两个坑里。
function [A5, A7] = fft_check(i_a, fs, f_base) % 谐波含量校核:整周期截断 + 加窗,避免频谱泄漏把幅值算飘 N = numel(i_a); Nper = round(N / (fs/f_base)); % 截成整数个基波周期 Nuse = round(Nper * fs / f_base); x = i_a(1:Nuse) .* hann(Nuse); % 加窗抑制泄漏 X = fft(x) / Nuse * 2; % 单边幅值谱 f = (0:Nuse-1) * (fs/Nuse); [~, k5] = min(abs(f - 5*f_base)); [~, k7] = min(abs(f - 7*f_base)); A5 = abs(X(k5)); A7 = abs(X(k7)); endNper那一步是整周期截断,如果采样窗口不是基波周期的整数倍,频谱就会泄漏,表现是 5 次、7 次的峰值忽高忽低地抖,你以为电机状态在变,其实是算法在骗你。加hann窗是第二道保险,能把泄漏再压一截,代价是幅值要乘个修正系数,做相对比较时可以直接忽略。
频谱结果建议按「补偿前 / 补偿后」两条曲线画在一张图里,横轴 0~1000Hz 就够,重点看 250Hz 和 350Hz 两根柱子。参考模型给出的结果是 5 次谐波幅值从 15A 左右降到 1A 以内,7 次从 9A 降到 0.5A 上下,THD 从 8% 量级掉到 2% 以内。这个量级是合理的,你要是自己做出来只降了 3dB,八成是相位没对齐。
4. 补偿指令生成:谐振控制器、相位对齐与限幅
提取只是第一步,真正决定成败的是补偿量怎么造出来、相位对不对、加多大。这一层是整套模型里参数最敏感的部分,也是最容易翻车的地方。
4.1 谐振控制器:在目标频率上给一条「零阻抗」通道
常规 PI 在 250Hz、350Hz 处增益已经衰减得厉害,指望它压住谐波不现实。工程里普遍的做法是用准比例谐振控制器,在指定频率处造一个很高的增益尖峰,等效于对那个频率的误差「零阻抗」吸收。
function Gr = pr_ctrl(f0, Kr, wc, Ts) % 准 PR 控制器:R(s) = 2*Kr*wc*s / (s^2 + 2*wc*s + w0^2) % f0 目标谐振频率 Hz,Kr 谐振增益,wc 带宽 rad/s w0 = 2*pi*f0; num = [2*Kr*wc, 0]; den = [1, 2*wc, w0^2]; Gr = c2d(tf(num, den), Ts, 'tustin'); % 双线性离散化 end三处参数要拧清楚。f0是目标频率,5 次对应5*f_base,7 次对应7*f_base,基波频率一旦随转速变化,这两个值必须跟着更新,写死成 250 和 350 只在额定转速下成立。Kr是谐振增益,从 10 开始往上加,每加一次看 THD 和电流波形,参考值在几十到两百之间,太大直接震荡。wc是带宽,单位是 rad/s,典型取 5~20,它决定控制器对频率偏移的容忍度——带宽窄了选择性好但怕转速漂,宽了抗漂但会误伤邻近频率。
顺带提一句资源里那段谐振控制器代码:它用tf([1 0 250^2], [1 0 250^2])这种写法,分子分母完全一样,传函恒等于 1,实际什么都没滤。另外 5 次和 7 次对应的 250Hz、350Hz 在两个变量上写反了。这种代码抄进工程是要出事的,正确形态应该是上面这个准 PR 结构,离散化用c2d走tustin,还要注意在高频段做预畸变,否则 350Hz 的中心频率会偏出去几个 Hz。
4.2 相位对齐:补偿反了比不补还糟
谐波抑制的本质是「等幅反相」,幅值差一点只是抑制不彻底,相位差 180 度那就是叠加增强,电流谐波翻倍,电机抖得像装了偏心块。这条链路上有三处会引入相位误差:带通滤波器的相移、控制周期的延迟、以及 PWM 更新的一拍滞后。三处叠起来,在中高频段能累计出几十度。
补偿手段是在补偿通道里串一个相位校正环节,常用一阶全通结构,用一个系数连续调超前或滞后:
function y = phase_comp(u, alpha) % 一阶全通相位校正:alpha > 0 超前,alpha < 0 滞后 % 目标是把 250Hz / 350Hz 处的总相位误差压到 5 度以内 persistent x1 y1 if isempty(x1) x1 = 0; y1 = 0; end y = -alpha*u + x1 + alpha*y1; x1 = u; y1 = y; endalpha和相移量的关系不是线性的,最靠谱的定参方式是用扫频信号实测:给模型灌一个 250Hz 正弦,看补偿通道输出相对输入的相位差,调alpha直到差值接近 180 度。350Hz 再单独校一次。两个频率都校完,基本就稳了。这个步骤在仿真里花十分钟,能省掉实机上大半天的排查。
还有一条血泪经验:Park 变换角度符号错(5 次写成+5*theta_e)造成的相位错误,用全通补偿是拉不回来的,因为那是整个通道反了 180 度,你只能靠频谱图上看「越补越大」来发现它。
4.3 电压限幅与抗饱和:别让补偿把功率器件送走
补偿量是直接加到调制波上的,意味着它和基波共享同一份母线电压余量。稳态下问题不大,突加负载或者转速阶跃时,基波电压需求瞬间抬高,再叠上谐波补偿,很容易冲进过调制区,波形削顶,电流畸变反而更严重。工程上必须在补偿输出后面加动态限幅。
function v_out = limit_comp(v_cmd, v_base, v_max, Ts) % v_base 为基波通道当前输出,v_max 为母线允许的相电压峰值 % 先按剩余裕量限幅,再做斜率限制,防止补偿量阶跃冲击 persistent v_prev if isempty(v_prev) v_prev = 0; end headroom = max(v_max - abs(v_base), 0); % 当前可用电压裕量 v_lim = max(min(v_cmd, headroom), -headroom); rate = 2000; % V/s,按实际母线电压调整 v_out = v_prev + max(min(v_lim - v_prev, rate*Ts), -rate*Ts); v_prev = v_out; endheadroom是根据基波需求实时算出来的,不是固定值,这一点很关键。固定限幅在轻载时浪费裕量,重载时又拦不住。rate做斜率限制,避免补偿量突变引起电流冲击。参考模型里没提这条,但实机上不加限幅,突加载工况下很容易触发过流保护,这一点做样机的人应该都有体会。
配套的还有积分抗饱和:电流环 PI 的输出如果已经顶到限幅,积分项还在继续累加,等工况恢复时要很久才能退出来,表现是动态响应拖沓、电流波形畸变一段时间。Simulink 里 PI 模块自带抗饱和选项,记得勾上,别自己搭离散积分器还忘了钳位。
5. 避坑与排查:仿真跑不通、越补越抖的几处硬伤
模型能跑起来只是开始,跑出来的波形能不能用是另一回事。下面这几条是这类谐波补偿模型里出现频率最高的问题,基本覆盖了「补偿无效」和「补偿反效」两大类。
5.1 谐波幅值一直在抖,频谱图上的柱子忽高忽低
现象:FFT 分析结果每次运行都不一样,5 次谐波幅值在 12A 到 18A 之间跳,补偿前后对比根本没法看。
原因:采样窗口不是基波周期的整数倍,频谱泄漏把能量摊到了邻近频点上,峰值自然不稳。另一种可能是 FFT 模块的采样率设成了跟主电路步长一致,数据量巨大且窗口长度随机。
解决:按 3.3 节的做法先做整周期截断,再叠一个hann窗,幅值波动立刻收敛到 1% 以内。同时把 FFT 的采样时间显式设成控制器采样周期,不要让它跟着变步长求解器走。
5.2 补偿打开后谐波不降反升,电流波形更难看
现象:把补偿支路使能,5 次谐波幅值翻了一倍,电机转矩脉动明显变大。
原因:相位反了,补偿量变成了同相叠加。最常见的两个来源是 5 次谐波 Park 变换角度符号写成了+5*theta_e(应为负),以及相位校正环节的alpha符号调反。
解决:先把补偿支路断开,单独观察提取出来的id5/iq5是否接近直流,再手动灌一个 250Hz 正弦进补偿通道,看输出相位是否接近 180 度。不要凭感觉把alpha从正调到负,一定要用扫频实测确认。
5.3 谐振控制器离散化后中心频率偏移,抑制效果打折
现象:目标 350Hz,仿真里补偿最强点出现在 340Hz 附近,350Hz 处增益不够,谐波只降了几个 dB。
原因:双线性变换在高频段有频率畸变,350Hz 相对采样率 10kHz 虽然不算高,但如果控制器里还有别的滤波器级联,累计偏移就会显现出来。
解决:c2d时用'tustin'加预畸变参数,或者在离散化前把目标频率按w0' = (2/Ts)*tan(w0*Ts/2)预修正。另一种更省事的做法是直接把采样率提到 20kHz,畸变量减半,工程上通常这样就够了。
5.4 转速一变补偿就失效,稳态好动态差
现象:额定转速下 THD 从 8% 降到 2%,转速降到 70% 额定,THD 又回到 6%, compensated 电流里能看到明显低频拍频。
原因:基波频率没有跟着转速实时更新,带通滤波器的中心频率和谐振控制器的f0全写死成了 250/350,转速一变谐波频率就跑出通带,提取失效。
解决:把f_base从电机模型的电角度微分算出来,实时喂给滤波器和 PR 控制器。带通滤波器的通带宽度也要按比例留余量(±10% 基频),别按固定频率设死。这套前馈在 3.2 节的函数里已经预留了f_base入参,接上就行。
5.5 突加负载时仿真报错或电流削顶
现象:0.8 秒突加额定负载,仿真直接报积分步长过小或者数值不收敛,看波形是调制波削顶。
原因:补偿量无限制地叠加在基波电压上,总需求超过母线可提供的相电压峰值,进入过调制;同时电流环 PI 积分饱和,恢复很慢。
解决:按 4.3 节加动态限幅和斜率限制,PI 模块勾选抗饱和。另外把仿真步长在突加负载前后保持一致,别用变步长求解器跑开关模型,否则该报的错会以另一种形式藏起来。
6. 二次开发:把这套模型搬到自己电机的参数上
模型能跑通之后,绝大多数人要做的下一件事是换成自己手上的电机。这一步看着只是改几个数,实际上参数一变,谐波含量、谐振点、补偿增益全都要重调,照抄原来的Kr大概率震荡。
我一般按这个顺序改。第一轮只改电机本体参数,把pmsm_params.m里除Ts、Vdc之外的量全部替换成铭牌加实测值,Ld、Lq没有实测条件就用 LCR 表量相电感,凸极机要分别量 d/q 轴。这一轮补偿支路先断开,跑一遍确认基波电流、转速、转矩都正常,THD 大致落在什么水平,这个数是你后面的基准。第二轮才接补偿,先把Kr放到很小的值(比如 5),确认没震荡再逐步加,同时盯着 5 次、7 次两根谱线。第三轮做转速扫描,从 30% 额定到 100% 额定分五档跑,每档记录 THD 和补偿量峰值,这一步最费时间但最能暴露频率跟踪的问题。
参数调整的对应关系可以参照这张表:
| 参数 | 物理含义 | 调大后的效果 | 建议起步值 |
|---|---|---|---|
Kr | 谐振增益 | 抑制更强,过大引发震荡 | 10~30,逐步加 |
wc | 谐振带宽 rad/s | 抗频率漂移强,选择性变差 | 10 |
| 滤波器阶数 | 选择性 | 谐波分离干净,相位延迟变大 | 4 阶 |
| 通带宽度 | 频率容差 | 转速波动下不易漏检,易混入邻次谐波 | ±0.5 倍基频 |
| 限幅裕量 | 电压安全边界 | 补偿更充分,过调制风险上升 | 母线峰值 90% |
真正往实机搬的时候,别一上来就把补偿跑在闭环里。稳妥的路径是先做快速原型,控制器里只留谐波提取和补偿计算,输出接示波器观察相位,确认无误再接进电压给定。上电前用可编程电源限流,第一次运行把补偿增益设在设计值的 20%,用电流探头看波形,一点一点加。这套流程走下来慢是慢,但比炸一台样机便宜太多。
改代码的时候把参数集中到一个结构体里,比散落在各个模块的对话框里强得多:
% cfg.m —— 所有可调参数集中管理,方便做参数扫描 cfg.base.fn = 50; % 基波频率 cfg.harm.order = [5, 7]; % 待抑制谐波次数 cfg.harm.Kr = [30, 20]; % 5 次、7 次谐振增益,7 次通常给低一些 cfg.harm.wc = 10; % 谐振带宽 rad/s cfg.flt.order = 4; % 带通滤波器阶数 cfg.flt.bw = 0.5; % 通带半宽(倍基频) cfg.lim.vmax = 0.9 * Vdc/2; % 相电压峰值限幅7 次谐波的增益通常比 5 次给得低一档,原因很实在:350Hz 在 10kHz 采样下每周期只有 28 个点,辨识精度和相位对齐都比 250Hz 差,增益给高了更容易震荡。这个细节在模型里没写,是我调了几轮之后才定下来的习惯。
从那以后我每次改这类模型,都强制先跑一遍「补偿使能置零」的基线,把 THD、5 次 7 次幅值、电流峰值三个数记在脚本注释里,改完参数再对比。没有基线的调参全是玄学,你根本分不清是算法变好了还是工况飘了。希望这套流程能帮到你,少走几段弯路。
本文还有配套的精品资源,点击获取