1. 电流谐波抑制的整体设计思路拆解1.1 为什么PMSM的电流谐波是个绕不开的坎搞永磁同步电机控制的人迟早都会撞上电流谐波这个问题。不管你是做伺服驱动器、做电动工具还是搞新能源汽车的电驱系统只要电机一转起来用示波器或者上位机抓一下相电流波形你就会发现它根本不是教科书上那个完美的正弦波——上面叠着一层一层的毛刺和畸变。这些畸变就是电流谐波它带来的直接后果是转矩脉动、噪声增大、铁耗和铜耗上升严重的时候还会让电流环震荡整个系统根本稳不住。很多人一开始会怀疑是编码器的问题、是采样电路的问题、是PI参数没调好折腾一圈之后才发现根源在逆变器的非线性特性和电机本身的磁路结构上。具体来说谐波的来源主要有这么几大类逆变器死区效应导致的电压畸变、开关器件的导通压降、电机反电动势的非正弦分布、齿槽效应、以及电流采样环节的偏差。这几类里面死区效应是最普遍、影响最大的一个也是我们这篇文章重点要聊的对象。从控制策略上看谐波抑制的手段可以分成两大流派。一派是从源头补偿也就是把逆变器非线性造成的电压误差算出来前馈补偿回去死区补偿就是典型代表。另一派是在控制环路里做文章用谐振控制器或者重复控制器在特定频率上把谐波“吸掉”准谐振控制就属于这一类。这两派各有各的适用场景实际工程里往往是搭配使用的。1.2 死区补偿和准谐振控制到底该选哪个先说结论这两个不是二选一的关系而是互补的关系。死区补偿解决的是低频段、宽频带的电压畸变问题它针对的是逆变器非线性这个“病因”准谐振控制解决的是特定次数的谐波问题比如5次、7次、11次、13次这些低次谐波它针对的是“症状”。死区补偿的优势在于实现简单、计算量小在大多数中低端驱动器上都能跑得动。它的核心逻辑是根据电流的极性判断当前哪些开关管在死区期间出现了续流然后把丢失的电压补回来。听起来简单但实际做的时候电流过零点附近的极性判断是个大麻烦判错了反而会引入更严重的畸变。准谐振控制的优势在于精度高、针对性强它可以在特定频率上提供极高的增益把该次谐波压得很低。但它的代价是计算量大、参数整定麻烦而且对频率变化比较敏感。如果你的电机转速范围很宽谐振频率得跟着基波频率一起变这就涉及到自适应谐振控制的问题了。我个人的经验是先做死区补偿把基础的波形质量提上来如果指标还不够再叠加准谐振控制去压特定次数的谐波。这个顺序不要反反了的话谐振控制器的负担会很重参数也很难调。1.3 方案选型背后的几个关键考量在动手之前有几个问题必须先想清楚。第一个是开关频率。你的PWM开关频率决定了死区补偿的精度上限也决定了谐振控制器能覆盖的谐波次数范围。一般来说开关频率越高死区占的比例越小补偿起来越容易但开关损耗也越大。常见的伺服驱动器开关频率在8kHz到16kHz之间这个范围内做死区补偿是比较舒服的。第二个是电流采样方式。单电阻采样、双电阻采样、三电阻采样这三种方式对谐波抑制的影响很大。三电阻采样能直接拿到三相电流极性判断最准确死区补偿效果最好。单电阻采样需要在特定时刻才能采到电流过零点附近的判断会更困难补偿效果会打折扣。第三个是控制器的算力。准谐振控制每个谐振器都要做一次二阶滤波运算如果你要压5次、7次、11次、13次四个谐波那就是四个谐振器并联计算量不小。如果用的是低端MCU可能跑不动这时候就得考虑用重复控制器或者查表补偿的方式来替代。第四个是电机的应用场景。如果是风机水泵这类对噪声和转矩脉动要求不高的场合做个简单的死区补偿就够了。如果是数控机床、机器人关节这类对精度和平稳性要求极高的场合那就得死区补偿加准谐振控制一起上。2. 核心细节解析与实操要点2.1 死区效应的物理本质与补偿原理死区效应说白了就是为了防止上下桥臂直通短路我们在开关管切换的时候插入了一段死区时间。在这段时间里上下两个管子都不导通电流只能通过续流二极管走。问题是二极管导通会产生一个压降而且这个压降的方向取决于电流的方向。如果电流从逆变器流向电机那么实际输出的电压就比我们期望的少了一块如果电流从电机流回逆变器实际输出的电压就比期望的多了一块。这个电压误差的大小可以这样估算假设死区时间是Td开关周期是Ts母线电压是Vdc二极管和开关管的导通压降之和是Vs那么平均电压误差大约是ΔV (Td / Ts) * Vdc * sign(i) Vs * sign(i)这里的sign(i)就是电流的极性符号。你看这个误差跟电流方向直接相关所以补偿的时候必须知道电流的极性。在电流比较大的时候极性很明确补偿起来没问题。但在电流过零点附近极性会反复跳变这时候如果补偿做不好就会在电流波形上留下明显的“平台”或者“台阶”反而让谐波更严重。我实测下来的经验是在电流过零点附近设置一个死区也就是当|i|小于某个阈值的时候不做补偿或者做线性过渡。这个阈值一般取额定电流的5%到10%左右。具体取多少得根据你的采样精度和噪声水平来调。2.2 准谐振控制器的数学结构与参数整定准谐振控制器的本质是一个在特定频率上增益极高的二阶滤波器。它的传递函数一般写成这样G(s) Kr * s / (s^2 2 * ωc * s ω0^2)其中ω0是谐振频率也就是你要压制的那个谐波频率ωc是带宽参数决定了谐振峰的尖锐程度Kr是增益决定了在这个频率上的放大倍数。这个控制器的作用是在ω0附近它的增益非常大可以把该频率的误差信号放大很多倍从而让电流环在这个频率上形成极强的跟踪能力把谐波压下去。而在其他频率上它的增益很小几乎不影响原来的控制环路。参数整定的时候ω0好确定就是基波频率乘以谐波次数。比如基波是50Hz你要压5次谐波那ω0就是250Hz。麻烦的是ωc和Kr。ωc太小谐振峰太尖对频率变化很敏感电机转速稍微一变谐振点就偏了效果大打折扣。ωc太大谐振峰太宽虽然鲁棒性好了但会影响到附近的频率响应可能把不该压的信号也压了。一般来说ωc取基波频率的5到15倍比较合适。Kr的选取跟系统的开环增益有关。Kr太小压谐波的效果不明显Kr太大系统可能不稳定。我的做法是先把Kr设得很小然后慢慢往上加同时观察电流波形的THD和系统的稳定性。当THD不再明显下降或者系统开始出现震荡的时候就往回退一点。2.3 电流环带宽与谐波抑制的相互制约这里有一个很多人容易忽略的问题电流环的带宽决定了你能压制的最高谐波次数。根据控制理论闭环系统对频率高于带宽的信号是没有抑制能力的。如果你的电流环带宽只有500Hz那你想压7次谐波350Hz可能还行想压11次谐波550Hz就力不从心了。所以在做谐波抑制之前先把电流环的带宽提上去。提高带宽的手段包括提高开关频率、优化PI参数、减小采样和计算延迟。但带宽也不是越高越好太高了会对噪声敏感而且受限于开关频率实际能到的带宽也就是开关频率的十分之一到五分之一左右。我一般会先把电流环带宽做到1kHz以上然后再去考虑加谐振控制器。如果带宽上不去那谐振控制器的效果会很有限这时候不如把精力放在死区补偿和PWM优化上。2.4 数字实现中的延迟与离散化问题准谐振控制器在数字芯片上实现的时候必须做离散化。常用的方法有双线性变换、后向差分、零极点匹配等。不同的离散化方法对谐振频率的偏移影响不一样。双线性变换会把谐振频率往低频方向拉一点需要在设计的时候做预畸变校正。后向差分更简单但频率偏移更大。还有一个绕不开的问题是计算延迟。从电流采样到PWM更新中间有一个开关周期的延迟。这个延迟在低频的时候影响不大但在高频段会引入明显的相位滞后让谐振控制器的效果变差。补偿的办法是在谐振控制器的输出上做一个相位超前校正或者用预测控制的方式提前一拍计算。我在实际项目里踩过的坑是离散化之后忘了做预畸变结果谐振点偏了十几赫兹压谐波的效果一直不理想查了好几天才发现是这个问题。所以提醒大家离散化之后一定要验证一下实际谐振频率对不对。3. 实操过程与核心环节实现3.1 硬件平台搭建与基础配置先说一下我的测试平台配置方便大家参考复现。主控芯片用的是TI的TMS320F280049C这是一颗带浮点运算的电机控制专用DSP主频100MHz跑电流环加谐振控制器绰绰有余。逆变器是三相全桥拓扑开关管用的是IPB60R099母线电压设到300V。电流采样用的是三电阻方案采样电阻是5毫欧配合INA240做差分放大。电机是一台表贴式永磁同步电机额定功率750W额定电流4.2A极对数是4额定转速3000rpm。开关频率设的是10kHz死区时间设的是1.5微秒。这个死区时间是根据开关管的开通关断时间和驱动电路的延迟来定的太小了有直通风险太大了电压误差大。1.5微秒在10kHz的开关周期里占1.5%算是比较典型的取值。基础配置做完之后先不急着做谐波抑制先把电流环跑通。电流环的PI参数用经典的内模控制方法整定把带宽做到1.2kHz左右。这时候用示波器看相电流波形应该已经是一个比较像样的正弦波了但仔细看还是能看到周期性的畸变这就是谐波。3.2 死区补偿的具体实现步骤死区补偿的实现可以分成三步。第一步是判断电流极性。我用的是三电阻采样直接拿三相电流的符号就行。但为了防止过零点附近的抖动我做了一个滞环判断当电流大于正阈值的时候极性判为正当电流小于负阈值的时候极性判为负在阈值之间的时候保持上一次的极性不变。这个阈值我设的是0.2A大概是额定电流的5%。第二步是计算补偿电压。根据前面的公式补偿电压的大小是(Td/Ts)*Vdc加上导通压降。Td是1.5微秒Ts是100微秒Vdc是300V算下来是4.5V。导通压降我取的是1.2V加起来是5.7V。这个值再乘以电流极性的符号就是需要补偿的电压。第三步是把补偿电压加到电压指令上。注意这个补偿是在αβ坐标系下做的不是在dq坐标系下做的。因为死区效应是跟相电流方向直接相关的在αβ坐标系下处理更自然。具体做法是先根据电流极性算出三相的补偿电压然后做Clarke变换到αβ坐标系再叠加到原来的电压指令上。代码实现大概长这样float deadtime_comp(float ia, float ib, float ic, float vdc, float td, float ts, float vf) { float comp_alpha, comp_beta; float comp_a, comp_b, comp_c; float threshold 0.2f; // 判断极性带滞环 static int sign_a 1, sign_b 1, sign_c 1; if (ia threshold) sign_a 1; else if (ia -threshold) sign_a -1; if (ib threshold) sign_b 1; else if (ib -threshold) sign_b -1; if (ic threshold) sign_c 1; else if (ic -threshold) sign_c -1; // 计算补偿电压 float v_comp (td / ts) * vdc vf; comp_a v_comp * sign_a; comp_b v_comp * sign_b; comp_c v_comp * sign_c; // Clarke变换 comp_alpha comp_a; comp_beta (comp_a 2.0f * comp_b) / 1.7320508f; return comp_alpha, comp_beta; }这段代码里有个细节Clarke变换我用的不是标准的等幅值变换而是根据三相电压的关系推导出来的。标准等幅值Clarke变换的β轴分量是(2comp_b comp_a)/√3我这里写的是(comp_a 2comp_b)/√3其实是一样的只是符号和顺序的问题。实际用的时候建议用标准的变换矩阵不容易出错。补偿做完之后再用示波器看电流波形你会发现过零点附近的畸变明显改善了THD大概能从8%降到4%左右。但5次和7次谐波还是能看到这时候就得上准谐振控制了。3.3 准谐振控制器的代码实现与调试准谐振控制器我是加在dq坐标系下的电流环上的。为什么加在dq坐标系下因为在dq坐标系下基波是直流量5次谐波对应的是6倍基波频率的交流量7次谐波对应的是-6倍基波频率的交流量。这样处理起来比较规整。具体做法是在d轴和q轴的电流误差上各并联一组谐振控制器。每个谐振控制器对应一个谐波次数。比如我要压5次和7次谐波那就在d轴和q轴上各加两个谐振器一共四个。离散化的谐振控制器代码大概是这样typedef struct { float Kr; float wc; float w0; float Ts; float y_prev1; float y_prev2; float u_prev1; float u_prev2; } ResonantController; float resonant_update(ResonantController *rc, float error) { float y; float a0, a1, a2, b0, b1, b2; // 双线性变换离散化 float T rc-Ts; float w0 rc-w0; float wc rc-wc; float Kr rc-Kr; float denom 4.0f 4.0f * wc * T w0 * w0 * T * T; a0 1.0f; a1 (2.0f * w0 * w0 * T * T - 8.0f) / denom; a2 (4.0f - 4.0f * wc * T w0 * w0 * T * T) / denom; b0 2.0f * Kr * T / denom; b1 0.0f; b2 -2.0f * Kr * T / denom; y -a1 * rc-y_prev1 - a2 * rc-y_prev2 b0 * error b2 * rc-u_prev2; rc-y_prev2 rc-y_prev1; rc-y_prev1 y; rc-u_prev2 rc-u_prev1; rc-u_prev1 error; return y; }这段代码里Kr我一开始设的是50wc设的是基波频率的10倍。调试的时候先把Kr设小一点比如10然后慢慢往上加。加到100的时候5次谐波明显被压下去了但系统开始有点震荡。最后我取的是60效果和稳定性比较平衡。还有一个细节谐振控制器的输出要限幅不然在启动或者负载突变的时候谐振器可能会输出很大的值导致系统不稳定。我一般把谐振器的输出限幅在电压指令的10%以内。3.4 实测波形对比与效果评估做完死区补偿和准谐振控制之后我用功率分析仪测了一下电流THD。在额定负载下补偿前的THD是8.2%只做死区补偿后降到4.1%再加上准谐振控制后降到1.8%。5次谐波从3.5%降到0.4%7次谐波从2.8%降到0.3%。效果还是很明显的。转矩脉动方面用扭矩传感器测了一下补偿前的转矩脉动峰峰值大概是额定转矩的6%补偿后降到1.5%左右。噪声方面用声级计在距离电机30厘米的地方测补偿前是72分贝补偿后降到65分贝人耳能明显感觉到安静了不少。不过要注意的是这些数据是在特定工况下测的。不同的电机、不同的负载、不同的转速效果会有差异。特别是高速的时候基波频率高了谐振控制器的频率跟踪如果跟不上效果会打折扣。这时候可以考虑用自适应谐振控制让谐振频率跟着转速走。4. 常见问题与排查技巧实录4.1 死区补偿后电流过零点出现尖刺怎么办这是最常见的问题之一。原因通常是极性判断在过零点附近出现了误判。电流在过零点附近会有噪声如果阈值设得太小噪声就会导致极性反复跳变补偿电压也跟着跳就在电流波形上留下了尖刺。解决办法有三个。第一个是加大滞环阈值让极性判断更稳定。但阈值也不能太大太大了在轻载的时候补偿就不准了。第二个是对电流做低通滤波把噪声滤掉再做极性判断。但滤波会引入相位延迟影响补偿的时机。第三个是用预测的方式判断极性根据上一拍的电流和电压指令预测下一拍的电流方向。这个方法最复杂但效果最好。我一般先用加大阈值的方法如果还不行再考虑加滤波。滤波的截止频率一般取开关频率的十分之一左右比如10kHz开关频率滤波截止频率取1kHz。4.2 准谐振控制器引起系统震荡怎么调谐振控制器引起震荡通常是Kr太大或者wc太小。Kr太大谐振峰的增益太高系统相位裕度不够就会震荡。wc太小谐振峰太尖对频率变化太敏感电机转速稍微一变谐振点就偏了也会引起震荡。调试的时候先把Kr设小wc设大然后慢慢调。如果震荡了先把Kr减半看能不能稳住。如果还不行再把wc加大。实在不行就把谐振控制器的输出限幅调小牺牲一点谐波抑制效果换稳定性。还有一个可能的原因是谐振频率跟基波频率不匹配。比如你设的谐振频率是250Hz但实际基波频率是52Hz那5次谐波就是260Hz谐振点偏了10Hz效果就不好。这时候要么用自适应谐振要么把wc加大让谐振峰宽一点覆盖这个偏差。4.3 不同转速下谐波抑制效果差异大怎么解决这个问题在宽调速范围的场合特别明显。低速的时候基波频率低谐波频率也低谐振控制器很容易覆盖。高速的时候基波频率高谐波频率也高可能超出了电流环带宽谐振控制器就力不从心了。解决办法有两个方向。一个是提高电流环带宽让它能覆盖更高的频率。这需要提高开关频率或者优化控制算法。另一个是用自适应谐振控制让谐振频率跟着基波频率实时调整。具体做法是用锁相环或者编码器算出当前基波频率然后实时更新谐振控制器的w0参数。自适应谐振控制的代码实现稍微复杂一点需要在每个控制周期里重新计算谐振控制器的系数。如果算力不够可以做成查表的方式提前算好不同转速下的系数运行时直接查表。4.4 常见问题速查表问题现象可能原因排查方法解决措施电流过零点有尖刺极性判断误判观察电流波形和补偿电压波形加大滞环阈值或加低通滤波系统震荡Kr太大或wc太小减小Kr或加大wc重新整定参数加输出限幅高速时谐波抑制效果差谐振频率超出电流环带宽测量不同转速下的THD提高带宽或改用自适应谐振轻载时补偿效果差死区补偿阈值太大观察轻载时的电流波形减小阈值或改用预测极性判断谐振控制器输出饱和启动或负载突变观察谐振器输出加输出限幅离散化后谐振点偏移未做预畸变校正扫频测试实际谐振频率做预畸变校正或改用其他离散化方法4.5 几个容易被忽略的实操心得第一个心得死区补偿和准谐振控制的调试顺序不能反。先把死区补偿调好把基础的波形质量提上来再加谐振控制器。如果反了谐振控制器要处理的谐波成分太复杂参数很难调。第二个心得谐振控制器的参数不是一劳永逸的。不同的电机、不同的负载、不同的转速最优参数可能不一样。如果应用场景变化大最好做成参数自适应的。第三个心得不要追求把THD压到极低。THD压到2%以下之后再往下压的代价很大收益很小。而且过度的谐波抑制可能会让系统对噪声更敏感鲁棒性变差。一般来说THD控制在3%以内就够用了。第四个心得实测的时候一定要用功率分析仪或者高精度的电流探头普通的电流钳精度不够测出来的THD不准。而且测量的时候要注意探头的位置和方向不然会引入额外的误差。第五个心得如果条件允许做一下扫频测试把整个系统的频率响应测出来。这样你能清楚地看到电流环的带宽在哪里谐振控制器的效果怎么样哪里还有问题。扫频测试虽然麻烦但能省下很多盲调的时间。5. 进阶方向与扩展思路5.1 从准谐振到重复控制的演进准谐振控制器只能压特定次数的谐波如果你要压的谐波次数很多比如5次、7次、11次、13次、17次、19次那就需要很多个谐振器并联计算量很大。这时候可以考虑用重复控制器。重复控制器的原理是基于内模原理在控制环路里插入一个周期延迟环节可以对所有整数次谐波同时提供高增益。重复控制器的缺点是动态响应慢因为它需要一个完整的周期才能建立起抑制效果。所以常见的做法是重复控制器和PI控制器并联PI负责动态响应重复控制器负责稳态精度。这样既有快的动态又有好的稳态性能。5.2 无感FOC下的谐波抑制挑战前面聊的都是有感FOC也就是有编码器或者旋转变压器的情况。如果是无感FOC也就是用反电动势观测器估算转子位置那谐波抑制会更麻烦。因为反电动势观测器本身就会受到谐波的影响谐波会导致位置估算误差位置误差又会导致电流谐波形成恶性循环。无感FOC下的谐波抑制除了前面说的死区补偿和谐振控制还需要在观测器上做文章。比如用自适应观测器把谐波当成扰动来抑制或者用高频注入的方式在低速时提高位置估算精度。这块内容比较多以后可以单独展开聊。5.3 匝间短路等故障情况下的谐波特征永磁同步电机如果出现匝间短路电流谐波的特征会发生明显变化。正常情况下谐波主要是5次、7次这些低次谐波。匝间短路之后会出现特定的边频带谐波比如基波频率的±1倍、±2倍附近会出现新的频率成分。这些特征可以用来做故障诊断。如果你在做电机的状态监测可以把电流谐波分析作为一个重要的手段。具体做法是对相电流做FFT然后观察特定频率成分的幅值变化。如果某些边频带的幅值异常增大就可能是出现了匝间短路。当然实际的故障诊断需要结合振动、温度等多方面的信息不能只看电流。5.4 不同PWM调制策略对谐波的影响前面聊的都是基于SVPWM的其实不同的PWM调制策略对电流谐波的影响也很大。比如DPWM不连续PWM在某些扇区里不开关可以减少开关次数降低开关损耗但会引入更多的低次谐波。Random PWM随机PWM可以把谐波能量分散到更宽的频带上降低特定频率的噪声但THD可能会略微上升。选择哪种PWM策略取决于你的应用需求。如果对噪声要求高可以用Random PWM如果对效率要求高可以用DPWM如果对波形质量要求高那就老老实实用SVPWM。我个人的经验是SVPWM加死区补偿加准谐振控制这个组合能覆盖大多数应用场景性价比最高。5.5 从仿真到实测的过渡经验最后聊一下仿真和实测的差异。我在MATLAB/Simulink里搭了一个完整的模型包括逆变器、电机、死区、采样延迟仿真出来的THD能压到1%以下。但实际跑起来THD是1.8%比仿真差了不少。差异主要来自几个方面一是实际电机的参数跟仿真模型有偏差特别是电感随电流变化二是实际电路的寄生参数比如线路电感、开关管的结电容仿真里很难精确建模三是采样噪声和量化误差仿真里是理想采样实际有噪声。所以仿真只能用来验证算法逻辑和初步整定参数最终的参数一定要在实测中调。而且实测的时候要从轻载到重载、从低速到高速全工况扫一遍确保在各种条件下都能稳定工作。我在实际项目中光是调谐波抑制的参数就花了将近两周时间大部分时间都花在覆盖各种工况上了。这个内容后续还可以往自适应控制、故障诊断、多电机协同等方向扩展。如果你在做的过程中遇到什么问题或者有更好的方案欢迎一起交流。