FOC电流环采样更新策略:SSSU、DSDU、SSDU、DSSU时序延迟对比与选型 1. 电流环延迟这件事为什么值得单独拎出来聊搞电机控制的人迟早会撞上同一个问题电流环带宽上不去PI参数怎么调都别扭波形看着还行但动态响应就是慢半拍。很多人第一反应是控制器算力不够或者PI参数没整定好但真正把根因挖到底十有八九会落到一个地方——采样到更新的时序策略。FOC磁场定向控制的电流环本质上是一个数字控制系统它的性能天花板不完全由算法决定而是由“什么时候采样、什么时候更新PWM”这套时序规则决定的。这套规则在行业里有个不太统一的叫法我习惯用四个缩写来区分SSSU、DSDU、SSDU、DSSU。这四个词拆开看就是采样Sample和更新Update的排列组合S代表单次SingleD代表双次Double位置顺序对应“上半周期做什么、下半周期做什么”。别小看这几个字母的排列它直接决定了电流环里到底存在多少拍延迟。一拍延迟在低频段看不出来但到了几千赫兹的带宽需求时相位裕度会被吃掉一大块PI再猛也救不回来。我见过不少项目硬件选型不差MCU主频也够最后卡在电流环振荡或者响应迟钝上折腾半天发现是采样更新策略选错了。这篇内容适合谁看如果你正在做PMSM无感FOC或者有感FOC的电流环调试如果你对“为什么我的电流环带宽只能做到开关频率的十分之一”感到困惑如果你想搞清楚二电阻采样和三电阻采样在时序上到底差在哪那这篇东西应该能帮你省下不少试错时间。我会把四种策略的时序逻辑、延迟来源、适用场景、实操配置和踩坑经验全部摊开讲尽量做到你看完就能对着自己的代码改。2. 先把底层时序逻辑捋清楚采样和更新到底在干什么2.1 电流环的一个周期里发生了什么要理解四种策略得先建立一个最基础的时序模型。假设PWM采用中心对齐模式载波周期为T_pwm那么一个完整的PWM周期里有两个关键事件点计数器的谷底下溢和峰顶上溢。这两个点把周期分成了上半周期和下半周期。在FOC电流环里每个周期需要完成两件核心事第一采样相电流通过ADC把Ia、Ib或再加Ic读进来第二更新PWM占空比把PI调节器算出来的新电压矢量写进比较寄存器。这两件事发生在什么时刻就构成了不同的采样-更新策略。最理想的情况是在这一拍刚开始的时候采样立刻算算完立刻更新这样从采样到更新之间几乎没有延迟。但现实是ADC采样需要时间FOC运算需要时间PWM寄存器更新也有它的生效规则。所以延迟不可避免问题只是延迟多少、延迟在哪。2.2 单次采样和双次采样的本质区别单次采样Single Sample指的是一个PWM周期只触发一次ADC采样。通常放在计数器谷底或者峰顶采一相或两相电流。它的优点是ADC触发逻辑简单CPU中断负担轻适合开关频率不高或者对成本敏感的场合。双次采样Double Sample则是在一个PWM周期的上半周期和下半周期各触发一次ADC采样。这样每个PWM周期能拿到两组电流信息等效采样率翻倍。但代价是ADC触发更频繁中断处理更重而且两组采样值之间可能存在纹波差异需要额外处理。这里有个容易混淆的点双次采样不等于双次更新。采样频率翻倍了但如果更新还是每周期一次那多出来的采样值怎么用就成了策略设计的关键。2.3 单次更新和双次更新的实际含义单次更新Single Update是指每个PWM周期只更新一次PWM比较寄存器。通常是在周期中断里算完PI然后在下个周期的开始生效。这种方式实现简单但更新频率受限于PWM频率。双次更新Double Update是指每个PWM周期更新两次PWM寄存器上半周期更新一次下半周期再更新一次。这样等效更新率翻倍电流环的等效控制频率提高动态响应会明显改善。但双次更新对运算时间要求更苛刻因为每次更新前都必须完成采样和PI计算。把采样和更新的单双组合起来就得到了四种策略。下面我逐个拆解它们的时序图和延迟来源。3. SSSU策略最朴素也最容易被低估的方案3.1 SSSU的时序逻辑拆解SSSU就是单次采样加单次更新。典型的时序是这样的在PWM计数器谷底触发ADC采样ADC转换完成后进入中断在中断里执行Clarke、Park、PI、反Park、SVPWM这一整套运算算完之后把新的占空比写入比较寄存器。由于PWM寄存器通常有影子寄存器机制写入的值会在下一个周期生效。所以从采样时刻到新占空比真正作用到电机上中间隔了ADC转换时间 FOC运算时间 寄存器生效等待时间。如果ADC和运算都在一个PWM周期内完成那么实际延迟大约是1到1.5个PWM周期。3.2 为什么SSSU的延迟最大SSSU的延迟来源主要有三块。第一块是采样到计算的等待ADC转换需要时间虽然现代MCU的ADC很快但加上采样保持和触发延迟几百纳秒到一微秒是跑不掉的。第二块是计算时间FOC运算量不小特别是带无感观测器的时候浮点运算或者定点运算都要占时间。第三块是更新生效延迟你在这个周期算完写入但PWM要等到下个周期才真正用上新值。这三块加起来在开关频率10kHz的情况下延迟大概在100到150微秒。对于带宽要求不高的应用比如风机、水泵这个延迟可以接受。但如果你要做伺服或者需要快速动态响应的场合SSSU就会成为瓶颈。3.3 SSSU的适用场景和实操注意事项SSSU最适合的是开关频率较低、对成本敏感、控制精度要求一般的场景。比如一些低成本的无感FOC方案MCU主频不高ADC资源有限用SSSU能把中断负担降到最低。实操中有几个点要注意。第一ADC触发点尽量靠近谷底但不要正好在谷底因为开关噪声在谷底附近可能还没完全衰减采样值会受干扰。我一般会往后延迟一点等开关噪声过去再采。第二FOC运算要尽量优化能定点就定点能查表就查表把中断执行时间压到最短。第三PI参数整定时要考虑到这个延迟积分增益不能给太大否则容易振荡。注意SSSU下如果发现电流波形有明显纹波或者动态响应迟钝不要急着怪PI先示波器抓一下采样时刻和PWM更新时刻确认延迟到底有多少。4. DSDU策略双采样双更新性能天花板最高4.1 DSDU的时序逻辑拆解DSDU是双次采样加双次更新这是四种策略里最激进的一种。它的时序是上半周期在谷底触发第一次采样算完后在上半周期结束前更新一次PWM下半周期在峰顶触发第二次采样算完后在下半周期结束前再更新一次PWM。这样每个PWM周期有两次完整的采样-计算-更新流程等效控制频率是PWM频率的两倍。如果PWM是10kHz那电流环的等效频率就是20kHz。延迟也从SSSU的1到1.5个周期降到了0.5个周期左右。4.2 DSDU为什么能大幅降低延迟DSDU降低延迟的核心在于更新时机提前了。SSSU是算完等下一个周期生效而DSDU是算完在当前半周期内就生效。虽然PWM寄存器还是影子机制但因为更新发生在半周期边界实际生效时间缩短了。另外双次采样让电流信息更新更快。上半周期采到的值用于上半周期的控制下半周期采到的值用于下半周期的控制信息滞后更小。这对于需要快速电流响应的应用比如力矩控制、位置伺服提升非常明显。4.3 DSDU的代价和实现难点DSDU不是没有代价。首先CPU负担翻倍。每个PWM周期要进两次中断每次都要跑完整的FOC运算这对MCU算力要求很高。其次ADC资源紧张。双次采样意味着ADC触发更频繁如果还要采母线电压、温度等信号ADC通道和转换时间都会吃紧。第三运算时间窗口很窄。半周期内必须完成采样和运算如果PWM频率是20kHz半周期只有25微秒减去ADC转换和死区时间留给FOC运算的可能只有十几微秒稍微复杂一点的观测器都跑不完。我在一个伺服项目里试过DSDUMCU是200MHz的M4核带FPU跑无感观测器加双次采样双更新中断里时间余量只剩不到3微秒稍微加一点保护逻辑就超时。所以DSDU适合的是算力充裕、开关频率不高、对性能要求极致的场合。4.4 DSDU的实操配置要点配置DSDU时PWM计数器的配置很关键。中心对齐模式下需要使能半周期中断在谷底和峰顶各触发一次。ADC触发源要分别配置为谷底触发和峰顶触发或者用PWM的多个比较事件来触发。代码结构上中断服务程序要能区分是上半周期还是下半周期因为两次采样的相电流对应关系可能不同。特别是二电阻采样时不同扇区下可采的相不一样上半周期和下半周期的采样相可能变化需要根据扇区动态调整。提示DSDU下PI参数可以给得比SSSU更激进因为延迟小了相位裕度更充足。但要注意双次更新之间的计算一致性避免上半周期和下半周期算出的电压矢量跳变太大。5. SSDU策略单次采样双次更新折中之道5.1 SSDU的时序逻辑拆解SSDU是单次采样加双次更新。采样还是每个PWM周期一次通常在谷底触发。但更新是两次上半周期更新一次下半周期再更新一次。那下半周期更新用的数据从哪来答案是用上半周期采样算出的结果在下半周期再更新一次或者用某种预测算法补一个值。这种策略的典型做法是谷底采样算一次PI得到电压矢量V1在上半周期更新然后在下半周期用V1或者对V1做一点修正后再更新一次。这样虽然没有新的采样信息但更新频率翻倍了PWM的等效分辨率提高电流纹波会减小。5.2 SSDU的延迟和性能表现SSDU的延迟介于SSSU和DSDU之间。因为采样还是每周期一次所以信息延迟没有改善还是1个周期左右。但更新频率翻倍后PWM的等效开关频率提高电流纹波降低电机的谐波损耗减小。从控制带宽角度看SSDU的提升不如DSDU明显因为反馈信息的更新率没变。但它有一个好处CPU负担比DSDU小。只需要一次采样和一次完整PI计算下半周期的更新可以用简单计算或者直接复用上半周期的结果运算量增加不多。5.3 SSDU适合什么场景SSDU适合开关频率不高但希望减小电流纹波的场合。比如一些低压大电流的应用MOSFET开关损耗大不能把PWM频率提太高但又希望电流波形平滑一些这时候SSDU是个不错的选择。另外SSDU也适合ADC资源紧张但PWM资源有余的情况。有些MCU的ADC触发源有限做不了双次采样但PWM比较寄存器可以多次更新这时候SSDU就能派上用场。5.4 SSDU的实现细节和坑SSDU实现时最大的坑是下半周期更新的值怎么算。如果直接复用上半周期的电压矢量那下半周期的电流可能会偏离预期因为电机状态在半个周期内已经变了。比较好的做法是用一个简单的预测器根据上半周期的电流变化率预测下半周期的电压修正量。我在一个项目里试过直接复用结果电流波形在过零点附近有明显的畸变。后来改成用电流斜率做线性预测畸变就小了很多。这个预测不需要很复杂一阶线性外推就够了。注意SSDU的下半周期更新值如果和上半周期差太多会导致PWM占空比在两个半周期之间跳变反而引入额外谐波。所以预测要保守修正量不要超过一定限幅。6. DSSU策略双次采样单次更新信息多但用得少6.1 DSSU的时序逻辑拆解DSSU是双次采样加单次更新。上半周期谷底采一次下半周期峰顶再采一次但PWM更新还是每个周期只做一次通常在周期结束时统一更新。这种策略的特点是采样信息翻倍了但控制更新没跟上。多出来的那组采样值可以用来做平均、滤波、或者观测器校正但不能直接用于提高控制频率。6.2 DSSU的价值在哪里DSSU的价值主要体现在观测器和滤波上。比如无感FOC的转子位置估算需要准确的电流信息。双次采样可以提供更多的电流数据点用来做滑动平均滤波降低采样噪声。或者用两组采样值的差异来估计电流纹波进而补偿死区效应。另外DSSU也可以用来做故障检测。两组采样值如果差异过大可能意味着采样通道有问题或者电机异常可以触发保护。这在安全要求高的场合很有用。6.3 DSSU的延迟分析DSSU的延迟和SSSU差不多因为更新还是每周期一次。采样信息虽然多了但从采样到更新的路径没变还是1到1.5个周期。所以DSSU不能用来提升电流环带宽它的定位是提升信息质量而非控制速度。6.4 DSSU的实操建议用DSSU时两组采样值的处理方式很关键。如果简单平均可能会把纹波也平均掉反而丢失了有用信息。我一般会根据采样时刻和PWM状态给两组值不同的权重。比如谷底采的值受开关噪声影响小权重高一些峰顶采的值可能受续流影响权重低一些。另外DSSU下ADC的配置要注意两组采样的触发源要分开避免冲突。有些MCU的ADC支持多触发源但需要仔细配置优先级和转换序列。7. 四种策略的横向对比与选型决策7.1 延迟、算力、性能的三角关系把四种策略放在一起看本质上是在延迟、算力消耗、控制性能之间做取舍。SSSU延迟最大但算力最省DSDU延迟最小但算力最费SSDU和DSSU则是两个方向的折中。下面这张表是我根据实际项目经验整理的对比参数以10kHz PWM、100MHz M4核为例策略采样频率更新频率等效控制频率典型延迟CPU占用适用场景SSSU10kHz10kHz10kHz1~1.5周期低风机、水泵、低成本方案DSDU20kHz20kHz20kHz0.5周期高伺服、力矩控制、高性能SSDU10kHz20kHz10~20kHz1周期中低纹波、中等性能DSSU20kHz10kHz10kHz1~1.5周期中观测器校正、故障检测7.2 选型时先问自己三个问题第一个问题电流环带宽需求是多少如果只需要几百赫兹SSSU足够。如果要几千赫兹DSDU或者SSDU才够用。带宽需求决定了延迟容忍度。第二个问题MCU算力余量有多少把FOC运算时间、观测器时间、保护逻辑时间全算上看看半周期内能不能跑完。跑不完就别硬上DSDU。第三个问题ADC资源够不够双次采样需要ADC有足够的转换速度和触发灵活性。如果ADC还要采母线电压、温度、位置信号要算一下总转换时间会不会冲突。7.3 一个容易被忽略的点死区时间的影响不管选哪种策略死区时间都会影响采样时刻。死区期间上下桥臂都不导通电流续流路径变化这时候采样会不准。所以采样触发点要避开死区。通常的做法是在死区结束后再延迟一点采样确保电流已经稳定。DSDU下这个问题更突出因为半周期很短死区占的比例更大。如果死区是1微秒半周期是25微秒那死区占了4%采样窗口很窄。这时候可能需要用三电阻采样因为三电阻可以在任意时刻采到至少两相电流不像二电阻那样受扇区限制。8. 常见问题与排查技巧实录8.1 电流波形振荡PI怎么调都不对先别动PI用示波器抓三路信号PWM输出、ADC触发、电流采样值。看采样时刻是不是在开关噪声最大的地方看更新时刻和采样时刻差了多少。如果延迟超过1.5个周期说明时序配置有问题可能是中断优先级被抢占或者ADC转换时间太长。我遇到过一次ADC采样后等DMA搬运DMA又被另一个高优先级中断打断导致FOC运算延迟了一个周期。后来把DMA优先级调高问题就解决了。8.2 双次采样时两组值差异很大先检查两组采样的触发源是不是真的分开了。有些MCU的ADC触发源配置有坑两个触发源可能映射到同一个事件。另外检查采样保持时间够不够双次采样时ADC转换更频繁如果采样保持时间太短采到的值会不准。还有一个可能两组采样对应的相电流不同。二电阻采样时不同扇区下可采的相不一样如果代码里没做扇区判断两组值可能对应不同的物理量当然差异大。8.3 高调制比下采样失败高调制比时某一相的占空比接近100%二电阻采样可能采不到足够的电流。这时候要么切换到三电阻采样要么用观测器补一个相电流。DSDU下这个问题更严重因为半周期短采样窗口更窄。我的经验是如果调制比经常超过85%就别用二电阻了直接上三电阻。三电阻虽然成本高一点但采样窗口灵活高调制比下也能采到。8.4 中断执行时间超限用DSDU时最容易遇到。先测一下中断里各段代码的执行时间用GPIO翻转加示波器测最准。如果FOC运算时间太长先优化数学运算比如用查表代替三角函数用定点代替浮点。如果还是超考虑降低PWM频率或者换更高主频的MCU。提示中断里不要做浮点除法很慢。能预计算的预计算能查表的查表。SVPWM的扇区判断和矢量作用时间计算用定点实现比浮点快很多。8.5 无感观测器在DSDU下不稳定无感观测器需要准确的电流和电压信息。DSDU下更新频率高观测器的迭代步长变小如果观测器增益没跟着调可能会振荡。另外双次更新时电压矢量的跳变可能让观测器误判。解决办法是观测器的带宽要低于电流环带宽一般取电流环带宽的1/5到1/10。DSDU下电流环带宽提高了观测器带宽也要相应调整但不要超过电流环的1/5否则噪声会放大。9. 从代码层面看四种策略的实现差异9.1 中断结构的不同SSSU和DSSU都是每周期一次中断中断里做采样和更新。DSDU和SSDU需要半周期中断中断里要判断是上半周期还是下半周期。以DSDU为例中断服务程序的骨架大概是void PWM_ISR(void) { if (PWM_GetHalfPeriodFlag()) { // 上半周期谷底采样算PI更新上半周期PWM current_sample ADC_ReadPhaseCurrents(); FOC_Calculate(current_sample); PWM_UpdateDuty(FOC_GetVoltageVector()); } else { // 下半周期峰顶采样算PI更新下半周期PWM current_sample ADC_ReadPhaseCurrents(); FOC_Calculate(current_sample); PWM_UpdateDuty(FOC_GetVoltageVector()); } }SSDU的中断结构类似但下半周期不采样直接用上半周期的结果或者做预测void PWM_ISR(void) { if (PWM_GetHalfPeriodFlag()) { current_sample ADC_ReadPhaseCurrents(); FOC_Calculate(current_sample); PWM_UpdateDuty(FOC_GetVoltageVector()); } else { // 下半周期不采样用预测值更新 voltage_vector FOC_PredictVoltage(); PWM_UpdateDuty(voltage_vector); } }9.2 ADC触发配置的差异SSSU和SSDU的ADC触发源通常配置为PWM谷底事件。DSDU和DSSU需要两个触发源一个谷底一个峰顶。配置时要注意触发源的优先级和转换序列避免两个触发源冲突。有些MCU的ADC支持注入通道和规则通道可以用注入通道做电流采样规则通道做其他信号。这样电流采样优先级高不会被其他信号打断。9.3 PWM寄存器更新的时机PWM比较寄存器的更新时机由影子寄存器控制。通常配置为“下个周期生效”或者“立即生效”。DSDU下上半周期的更新要在上半周期结束前生效下半周期的更新要在下半周期结束前生效所以影子寄存器的配置要仔细。有些MCU支持“半周期生效”模式正好适合DSDU。如果没有这个模式就要用“立即生效”但要注意避免在PWM输出过程中写入导致毛刺。10. 我个人的一些实操体会折腾过这么多项目我最大的体会是没有最好的策略只有最合适的策略。SSSU虽然老土但在很多低成本场合它是最稳的。DSDU性能好但对硬件和代码要求高搞不好反而容易出问题。选策略之前先明确你的核心需求是什么。是要低成本还是要高性能还是要低纹波需求明确了策略自然就定了。另外不管选哪种策略实测永远比理论重要。理论算出来的延迟是理想值实际中中断延迟、ADC延迟、寄存器生效延迟都可能比预期大。用示波器抓一下实际波形比看多少文档都管用。最后分享一个小技巧如果拿不准用哪种策略可以先在SSSU上把功能跑通然后逐步切换到SSDU或者DSDU对比电流波形和动态响应。这样风险最小也最容易定位问题。