资讯动态

单矢量控制下的占空比计算:有效抑制电流纹波与噪声

发布时间:2026/10/19 6:08:40 来源:尧图企业网站定制
做数字电机控制的人应该都经历过这种尴尬算法层面跑得好好的DTC或者有限集模型预测控制FCS-MPC每个控制周期都选了那个“最优电压矢量”上示波器一看电流纹波比SVPWM大一块高频噪声还特别多。以前我调试某永磁同步电机项目时也撞上过这个情况最开始怀疑电流采样、怀疑死区补偿折腾了两周最后才反应过来——问题就出在“只选一个矢量并且用满整个控制周期”这个机制上。这篇文章想聊的主题就是单矢量控制下的占空比计算。它解决的是这类控制策略最典型的一个痛点电压矢量被量化成6个离散方向后怎么通过占空比这一参数把“等效电压”做连续调节。我会从物理层面的纹波来源讲起把伏秒平衡、代价函数解析求导、转矩斜率法三条计算思路都拆开再给出实际C代码和我在工程调试中踩过的坑。适合正在做FCS-MPC、DTC或者刚接触模型预测控制但被电流纹波困扰的工程师和研究生参考。1. 为什么单矢量控制天生“毛刺”多从6选1的局限说起1.1 八个开关状态带来的电压量化问题电压源逆变器一共只有8种基本开关组合6个有源电压矢量和2个零矢量。有源矢量的幅值都是2/3倍直流母线电压相邻矢量相隔60°电角度空间分布看起来就是一个正六边形。所谓单矢量控制就是在每个控制周期Ts内直接从这6个有源矢量里选一个整个周期都施加它要么再退一步选零矢量。这个机制的物理后果很直接电机此刻需要的电压如果是某个扇区中间位置你只能把它拽到相邻的矢量上无法做到精确指向。SVPWM为什么平滑因为它同时合成两个有源矢量和零矢量用占空比在一个开关周期内做伏秒平衡等效电压的幅值和方向都能连续调节。单矢量控制没有这个操作每个周期结束后磁链圆弧轨迹上都会留下一个“锯齿”误差。1.2 磁链轨迹和转矩纹波是怎么被放大出来的从磁链角度看更直观。定子磁链矢量在有源电压矢量作用下会沿该矢量方向快速移动而零矢量作用下磁链几乎停在原地只受定子电阻压降影响缓慢漂移。单矢量控制整周期施加同一个有源矢量相当于强迫磁链在一个方向上冲满Ts下一周期再突然切换到另一个方向。磁链轨迹不是平滑圆而是一段段折线。折线轨迹映射到转矩上就是明显的周期性脉动。转矩脉动会带来转速抖动、噪音变大严重时还会让电流波形出现明显的“阶梯感”。在低电感电机或者高直流母线电压场合这个纹波会更加突出——因为电感小电流变化率di/dt大同一电压矢量子作用一个整周期电流能冲得非常高。1.3 占空比本质上是增加了一个连续自由度单矢量控制虽然叫“单矢量”但它真正的缺陷不是“只选一个方向”而是“方向选定后没有调节幅度的余地”。引入占空比之后情况就变了有源矢量只作用d·Ts时间剩余(1−d)·Ts时间插入零矢量等效电压等于d乘以该有源矢量幅值。d从0到1连续变化电压幅值就连续可调了。工程上有时候会把这种方案叫“单矢量占空比MPC”也有的叫“占空比直接转矩控制”。严格从开关序列看其实一个周期里有两个开关状态有源矢量状态和零矢量状态所以本质是“一有源一零”的伏秒合成。但这个方案的最大优势是保留了单矢量控制“候选矢量少、每次只需计算一次占空比”的轻计算量特点不用像双矢量、三矢量MPC那样嵌套搜索运算量只增加一点纹波却能明显压下去。这也是它成为FCS-MPC改进中最接地气方案的原因。2. 占空比计算的三条路线伏秒平衡、代价函数求导、转矩斜率法2.1 伏秒平衡从SVPWM继承过来的基础理解最简单的占空比计算思路直接沿用SVPWM里“伏秒平衡”的概念。一个开关周期Ts内有源矢量Vi作用时间为d·Ts零矢量作用时间为(1−d)·Ts平均电压为Vavg d·Vi假设控制器需要一个幅值为|Vref|、方向落在当前扇区内的电压矢量它与选定有源矢量Vi之间的夹角为θ那么平均电压在该方向上的分量需要满足d·|Vi|·cosθ |Vref|所以d |Vref| / (|Vi|·cosθ)这个公式非常直观参考电压越接近所选有源矢量方向d越接近1越偏离d越小。只要电机控制环输出的是一个电压参考比如电流环PI输出或者磁链参考伏秒平衡法就能直接算出占空比。但这个方法有个前提你得先知道参考电压在哪并且选择了正确的有源矢量。对于FCS-MPC这类不需要显式参考电压矢量的策略通常不是这个思路。所以伏秒平衡法更适合做概念解释真正在FCS-MPC里计算占空比更常用的是下面这条解析求导路线。2.2 代价函数解析求导把d当成连续变量解出来FCS-MPC的核心是对每个候选电压矢量建立预测模型然后算代价函数取最小代价对应的那个矢量。引入占空比后代价函数里多了一个连续变量d我们可以不靠枚举直接对d求偏导并令偏导为零解出该候选矢量下的最优占空比。以电流控制为例。电机电流预测模型写成一阶离散形式i(k1) i(k) Ts/L·(v − e − R·i(k))其中e是反电动势L是定子电感R是定子电阻。如果不施加任何有源矢量只靠零矢量作用一个整周期可以得到一个“基础预测电流”i_base i(k) Ts/L·(−e − R·i(k))如果选择有源矢量Vi作用d·Ts零矢量作用(1−d)·Ts则预测电流为i_pred i_base d·Ts/L·Vi代价函数设为电流误差平方J(d) |i_ref − i_base − d·Ts/L·Vi|²把d看作连续变量对d求导并令其为零得到d [(i_ref − i_base)·Vi] / (Ts/L·|Vi|²)这里的“·”是向量点乘。对双轴模型αβ轴写开就是这样。注意最终要限幅d只能落在[0,1]区间内超上限按1处理小于0就说明这个矢量不合适直接弃用或切零矢量。这条路的优势在于把离散搜索和连续优化解耦了外层仍然搜6个有源矢量内层每个矢量只用一次公式算出最优d总计算量增加很小。代价函数里如果加入转矩和磁链目标形式会变成多个二次项的加权和但思路一样——写成d的函数求导解一元二次极值问题。2.3 转矩斜率法DTC系最常用的工程近似直接转矩控制DTC里占空比计算又是另一种风格。DTC靠转矩滞环选矢量没有显式电流参考所以不方便用电流代价函数。实务上更常用转矩变化率来估算占空比。定义有源矢量作用下转矩上升斜率为S_on零矢量作用下转矩下降斜率为S_off通常是负值当前转矩误差为e_T T_ref − T(k)。如果在周期开始时就施加有源矢量持续时间为d·Ts剩下时间用零矢量周期末转矩误差可以近似写成ΔT S_on·d·Ts S_off·(1−d)·Ts希望周期末误差归零即ΔT e_T解出d (e_T/Ts − S_off) / (S_on − S_off)S_on和S_off怎么来严格推导转矩对时间的导数表达式相当复杂特别是内置式永磁同步电机还有磁阻转矩项直接算会非常繁琐。工程上常见的做法是用上一次周期的电流、磁链和电压做在线计算或离线建表。更粗糙但稳定的是利用“零矢量下转矩衰减主要和速度相关有源矢量下转矩上升主要和电压矢量与反电动势夹角相关”这个物理规律做成简化公式或查表。三种方法对比计算方法原理基础实现成本典型应用伏秒平衡法电压平均等效低需要参考电压矢量SVPWM思想沿用、占空比概念教学代价函数求导预测模型解析极值中需要RL参数FCS-MPC电流/磁链控制转矩斜率法转矩变化率近似中低需斜率模型或查表DTC及其改进方案3. 手把手落地单矢量占空比模型预测电流控制的公式与代码3.1 完整计算流程从矢量表到PWM装载实际工程中用得最多的还是“代价函数求导占空比”这条组合因为它直接嵌入FCS-MPC框架改动最小。完整流程可以分成六步离线准备好6个有源电压矢量在αβ轴的投影v_alpha[i]、v_beta[i]单位是伏特。这些值由直流母线电压换算而来控制周期内不变放在常量表里即可。每个控制周期开始时采集两相电流和母线电压估算或观测反电动势e_alpha、e_beta。计算基础预测电流i_base。这一步相当于“假如整个周期都施加零矢量”的预测。遍历6个有源矢量对每个矢量用解析公式计算最优d并限幅到[0,1]。用限幅后的d计算每个候选矢量的最终预测电流代入代价函数选出代价最小的(矢量编号, d)。根据选出的有源矢量和零矢量的开关状态计算对应的比较寄存器值更新到PWM定时器。这六步看着简单但每一步都有细节。第4步的d求解如果解出来是负数不代表这个矢量没有意义而是说明该矢量方向和电流误差方向背离用了它反而会让预测电流离参考更远。此时直接把d截到0等效于选零矢量。第3步的基础预测电流一定要算准它是整个公式的零点参照如果反电动势估算偏差大算出的d会整体偏斜即使代价函数还能选出矢量等效电压也会失真。3.2 核心C代码直接可用的一段参考实现我用C语言写一个核心循环片段目标平台是低成本MCU浮点运算也没问题控制周期Ts100μs。这段代码省略了ADC采样、PWM底层寄存器操作只保留从反电动势估算往后到矢量选择的逻辑// 假设已经得到 // is_alpha, is_beta —— 当前电流 // e_alpha, e_beta —— 反电动势估算值 // v_alpha[6], v_beta[6] —— 六个有源矢量在alpha/beta轴投影 // Ts —— 控制周期秒 // R, L —— 电机电阻、电感 // is_ref_alpha, is_ref_beta —— 电流参考值 // 1. 基础预测电流整个周期零矢量 float i_base_alpha is_alpha Ts / L * (-e_alpha - R * is_alpha); float i_base_beta is_beta Ts / L * (-e_beta - R * is_beta); float best_J 1e9f; int best_idx -1; float best_d 0.0f; // 2. 遍历六个有源矢量 for (int idx 0; idx 6; idx) { // 2.1 根据代价函数求导得到的占空比公式 float num (is_ref_alpha - i_base_alpha) * v_alpha[idx] (is_ref_beta - i_base_beta) * v_beta[idx]; float den (Ts / L) * (v_alpha[idx] * v_alpha[idx] v_beta[idx] * v_beta[idx]); float d num / den; // 2.2 限幅小于0截到0大于1截到1 if (d 0.0f) d 0.0f; if (d 1.0f) d 1.0f; // 2.3 用当前d计算预测电流 float pred_alpha i_base_alpha d * Ts / L * v_alpha[idx]; float pred_beta i_base_beta d * Ts / L * v_beta[idx]; // 2.4 代价函数 float J (is_ref_alpha - pred_alpha) * (is_ref_alpha - pred_alpha) (is_ref_beta - pred_beta) * (is_ref_beta - pred_beta); if (J best_J) { best_J J; best_idx idx; best_d d; } } // 3. 最后根据 best_idx 和 best_d 生成对应开关状态 // 有源矢量作用 best_d * Ts零矢量作用 (1 - best_d) * Ts这段代码去掉注释后非常短核心计算量其实就是6次内积和6次代价函数平方运算在cortex-m3级别的主控上占用资源可以忽略不计。3.3 零矢量选择V0还是V7不是随便选的占空比方案涉及零矢量很多人随手就选V0(000)或者V7(111)其实这里有个明显但容易忽略的优化点选零矢量时要看当前开关状态目的是减少开关次数。举例当前上一个周期结束时的开关状态如果是001这个周期有源矢量选的是100那么插入零矢量时选V0(000)从100切换到000只需要关掉A相上管只动1个桥臂如果选V7(111)则要从100切到111B、C两相都要切换开关次数多一倍。开关次数多了开关损耗和死区影响都会变大。我实际调试时的经验是把上一周期的“最终开关状态”存下来计算比较寄存器之前先判断V0和V7分别需要动几个桥臂选择动得少的那一个。这是一个纯软件判断计算量几乎为零但对降温和改善电磁干扰很有帮助。另一个与零矢量相关的问题是零矢量分布在周期开头还是结尾。很多PWM外设支持不对称PWM更新可以把有源矢量放在周期中间零矢量拆成前后两段这样等效开关频率更高、纹波更小但寄存器配置会复杂一点。我建议刚从单矢量切到占空比方案的同事先保持“有源矢量在前、零矢量在后”的最简单配置跑通了再玩对称插入。4. 占空比计算的工程坑过调制、延迟补偿、死区与量化4.1 过调制时的截断处理解析公式解出的d如果超过1说明这个矢量方向上需要的电压已经超过逆变器能给出的最大值物理上做不到。截断到1是最基本的做法但截断后要意识到一个问题代价函数选的矢量可能是“矮子里拔将军”真正最优的也许是把电压分解到相邻两个矢量各一部分。单矢量占空比方案天然没有这种分解能力所以适合在不过调制的工况下使用直流母线利用率和过调制工况是它不如双矢量方案的地方。工程上如果经常出现d长时间截断在1需要考虑两个方向一是降低电流参考的坡度二是干脆换双矢量或多矢量策略而不是硬调权重或者增益。截断问题本质是容量不够算法层面很难绕过去。4.2 数字延迟补偿算出来的d要提前一拍预测这是单矢量控制转化为数字实现时最容易忽略的坑。控制器在k时刻采样、计算、得到d但PWM比较值真正生效是在k1时刻。如果代码里直接把k时刻的电流和参考值代入公式算d实际执行时电流已经往前走了一步会产生至少一个控制周期的相位滞后表现为稳态误差、振荡或者电流过冲。正确做法是做一拍延迟补偿先用模型预测k1时刻的电流把这个值当作预测起点再代入占空比公式。很多文献叫这个“deadbeat思想”实际操作也不难先执行一遍零矢量预测把得到i_base当成k1时刻的预测电流状态后续选矢量和算d都基于它。上面代码里其实已经内含了这个思想——i_base包含的是从当前时刻向未来预测的效果关键是你有没有真正把执行时刻和预测时刻对应起来。我在某个项目里测试过不加延迟补偿电流波形在高速段会出现轻微的正弦畸变加了一拍补偿后波形立刻干净了很多代价函数收敛也更快。4.3 PWM计数器量化和死区的相互作用d是浮点数但最终写入PWM比较寄存器时要转换成定时器计数单位。假设PWM定时器频率100MHz控制周期100μs一个周期的计数值是10000d的量化分辨率其实已经很高足够用了。但如果控制频率很高比如30kHz周期计数值只有3000多d的最小步进约0.03%影响反而不大。真正要注意的是死区时间占比。当d很小比如只有3%时有源矢量实际作用时间可能只有1.5μs而死区时间是2μs级别的话这个“3%占空比”几乎完全被死区吃掉实际输出电压不是3%而是接近0。反过来d也很容易因为死区导致实际电压超过期望值。我的处理办法是在占空比公式里不做死区补偿的情况下额外引入最小占空比限制。比如定死区时间t_dead则最小有效d t_dead/Ts 裕量。低于最小值的d统一截到0避免输出一个“看似有、实际没有”的微窄脉冲。4.4 参数失配会让d算得漂RL误差的敏感度分析占空比解析公式中包含Ts/L和R如果电感参数偏差大d的计算会系统性漂移。L偏大公式分母偏大d算小了L偏小d算大了等效电压失控电流纹波不降反升。我遇到过一版代码电机模型里用的L是标称值的1.7倍结果占空比从0.6变成了0.35相当于实际电压打了六折闭环只能靠电流环PI拼命往上补最后表现为奇怪的“噪声偏置”。解决思路有两条一是离线做电感辨识在静止状态下注入电压脉冲测电流斜率反算L二是在线辨识用递推最小二乘法跟踪L和R的变化。对于文章主题而言我特别提醒一点占空比公式对L非常敏感代价函数本身反而没那么敏感——因为代价函数只是选方向d的质量直接由参数精度决定。调占空比MPC时如果感觉“选矢量选得对但电流还是抖”先检查参数。5. 效果对比与选型建议单矢量占空比到底值不值得用5.1 与SVPWM、双矢量MPC的横向对比我拿最近一次感应电机控制实验数据做个大致的横向对比控制频率20kHz直流母线电压310V电感参数约8mH。单矢量FCS-MPC的电流总谐波畸变率THD约为7.2%加入占空比计算后降到4.1%左右改善幅度接近40%。双矢量MPC还能再降一些大概到3.5%但枚举次数从6次变成30次计算时间大约增加3倍。SVPWM在这个工况下THD约2.8%是最低的但代价是控制结构完全不同没法直接在已有FCS-MPC框架上平滑升级。开关次数方面单矢量FCS-MPC每次切换只动一个桥臂开关频率最低单矢量占空比因为有源矢量和零矢量两次状态切换一个周期内需要多动几次桥臂开关频率大约上升40%到60%具体取决于零矢量选择是否优化。双矢量MPC因为每个周期两个有源矢量加零矢量开关活动最高。方案电流THD计算量开关频率工程改动难度单矢量FCS-MPC高很低低基准方案单矢量占空比明显降低低中小解析式限幅双矢量/三矢量MPC更低高较高中需扩展枚举SVPWM连续集最低中中等大控制结构不同5.2 什么场合最值得上这个方案从我的项目经验看单矢量占空比最适合这几类场景一是控制器算力有限的场合。FCS-MPC本来就是为了规避复杂调制上到低成本MCU的加个占空比解析公式不会破坏这个优势双矢量的枚举量却可能让主控扛不住。二是DTC或MPC已经跑通、只想压纹波的改进场景。如果你不想推翻控制结构占空比计算是最小侵入的改动。原来写好的矢量选择表还能用只需要在每个矢量旁边多算一个d再把原来的“整周期作用”改成“PWM比较值限幅”。三是中低开关频率的调速系统。开关频率低的情况下单矢量作用一个整周期的纹波被放大得特别明显占空比带来的改善显著。高开关频率下单矢量的时间量子本身就很小纹波已经不大占空比收益会缩水还不如把算力留给更复杂的在线辨识。5.3 调参和调试实操建议最后给几条我个人的调试心得。拿到一个新电机做单矢量占空比MPC时不要一上来就调参数先把占空比d的值用DA输出或者串口记录下来看时间波形。正常情况下d应该在0到1之间平滑变化如果你看到d在相邻周期里从0.8跳到0.1先查是不是参数失配再看是不是参考值变化太激进。d波形比电流波形更早暴露系统问题这是我调试了很多轮才养成的习惯。代价函数加磁链项时注意量纲问题。电流项单位是安培的平方磁链项单位是韦伯的平方数值上差好几个数量级权重必须做归一化。我是习惯先只跑电流项验证占空比计算正确性再逐渐加入磁链项和权重不要一上来就双目标。反电动势估算对占空比公式影响极大。低速段反电动势很小估算误差相对大这时候基础预测电流里的反电动势贡献不大问题不突出高速段反电动势占主导如果观测器没调好d会整体偏移。我在一个6极贴装式永磁电机项目里速度上去后总是感觉转矩出力不足排查到最后就是反电动势观测器增益低了高速段估算偏小导致d整体偏小白白损失了好几个百分点的电压利用率。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑