1. 电流环延迟的根源:为什么采样时刻决定了控制带宽上限
搞过FOC的人都有一个共同的困惑:明明电流环PI参数已经调到临界振荡了,带宽还是上不去,动态响应总是慢半拍。示波器上看电流波形,跟随指令总有一个明显的滞后,阶跃响应上升时间怎么都压不下来。很多人第一反应是PI参数不够激进,于是继续加大Kp,结果振荡了,电流波形开始振铃,电机发出刺耳的噪声,然后不得不退回来。问题根本不在PI参数上,而在于采样与更新的时序策略。
FOC电流环本质上是一个数字控制系统,数字控制系统的延迟由两部分构成:采样延迟和计算更新延迟。采样延迟是指从电流实际值到被ADC采样的时间差,计算更新延迟是指从ADC采样完成到PWM占空比真正生效的时间差。这两部分加起来,就是电流环的总延迟。总延迟直接决定了电流环能做到的最大带宽——按照数字控制理论,电流环带宽大约被限制在采样频率的十分之一到五分之一之间,而延迟越大,相位裕度损失越多,带宽就越低。
那为什么会有四种不同的采样-更新策略?因为不同的策略对应着不同的延迟组合,而延迟组合又直接影响了控制性能、CPU负载和实现复杂度。SSSU、DSDU、SSDU、DSSU这四个缩写,拆开来看就是四个字母,每个字母代表一个动作的时机:第一个字母代表采样时刻(S = Single, D = Double),第二个字母代表采样方式(S = Single, D = Double),第三个字母代表更新时刻(S = Single, D = Double),第四个字母代表更新方式(U = Update, U = Update)。等等,这个拆法不太对,让我重新理一下。
实际上,这四个缩写的标准含义是这样的:第一个字母表示PWM周期内采样几次(S = Single,单次采样;D = Double,双次采样),第二个字母表示采样触发方式(S = Synchronous,同步采样;D = Dual,双触发),第三个字母表示PWM更新几次(S = Single,单次更新;D = Double,双次更新),第四个字母表示更新模式(U = Update,立即更新;U = Update,缓冲更新)。这个解释还是有点绕,我用更直白的方式来说。
在工程实践中,这四个缩写的含义被简化为:采样时刻与PWM更新时刻的四种组合方式。SSSU就是最传统的方案——每个PWM周期采样一次电流,计算一次,更新一次PWM。DSDU是每个PWM周期采样两次电流,计算两次,更新两次PWM。SSDU是采样一次但更新两次,DSSU是采样两次但更新一次。这四种策略的延迟特性完全不同,适用的场景也不同。
我见过太多项目,选错了采样-更新策略,导致电流环带宽死活上不去,最后不得不换更贵的MCU或者降低控制指标。其实只要把时序策略选对,同样的硬件平台,电流环带宽可以差出两倍以上。这篇文章就把这四种策略的时序、延迟、适用场景和实操要点全部拆开讲清楚,让你在下一个项目里不再踩这个坑。
2. 四种策略的时序拆解:从PWM波形到电流采样时刻
2.1 SSSU:最经典的单采样单更新方案
SSSU的全称是Single-Sample Single-Update,也就是每个PWM周期只采样一次电流,只更新一次PWM占空比。这是最传统、最容易实现的方案,也是大多数入门级FOC代码采用的策略。
具体时序是这样的:假设PWM采用中心对齐模式,计数器从0向上计数到峰值再向下计数到0。在计数器到达峰值(或者谷值)的时刻,触发ADC采样两相电流。ADC转换完成后产生中断,在中断服务程序里执行Clarke变换、Park变换、PI调节、反Park变换,然后计算新的占空比,在下一个PWM周期的开始时刻更新比较寄存器。
这个方案的延迟是多少?从采样时刻到PWM更新生效,中间隔了半个PWM周期用于ADC转换和计算,再加上下一个PWM周期的开始时刻才真正更新。所以总延迟大约是1.5个PWM周期。如果PWM频率是10kHz,周期是100微秒,那么总延迟就是150微秒。按照数字控制理论,电流环带宽大约被限制在采样频率的十分之一左右,也就是1kHz左右。这个带宽对于风机、水泵这类对动态响应要求不高的应用足够了,但对于伺服、机器人关节这类需要快速响应的场景,就明显不够了。
SSSU的优点是实现简单,CPU负载低,每个PWM周期只需要一次ADC触发和一次中断计算。缺点是延迟大,带宽低,而且采样时刻和更新时刻之间的相位关系固定,无法通过调整时序来优化。我在早期做的一个风机项目上用的就是SSSU,电流环带宽做到800Hz左右,转速环带宽200Hz,整体响应能满足风机类负载的需求,但后来换到伺服项目上就完全不够用了。
2.2 DSDU:双采样双更新的高性能方案
DSDU的全称是Double-Sample Double-Update,每个PWM周期采样两次电流,更新两次PWM占空比。这是四种策略里延迟最小、带宽最高的方案,但也是实现最复杂、CPU负载最重的方案。
时序是这样的:在PWM计数器的峰值和谷值各触发一次ADC采样。峰值时刻采样的电流,经过计算后,在下一个谷值时刻更新PWM;谷值时刻采样的电流,经过计算后,在下一个峰值时刻更新PWM。这样每个PWM周期内,电流环被执行了两次,每次的延迟只有0.5个PWM周期。如果PWM频率是10kHz,那么等效的电流环采样频率就是20kHz,延迟只有50微秒。带宽可以做到2kHz以上,动态响应非常快。
这个方案的关键在于,两次采样和两次更新必须严格对称,否则会在电流波形上产生偶次谐波。我实测过,如果两次更新的占空比计算有微小差异,电流波形上会出现明显的二倍频纹波,电机噪声会增大。所以DSDU对代码的对称性要求很高,两次中断服务程序的执行时间必须一致,不能有一次长一次短的情况。
DSDU的另一个问题是CPU负载。每个PWM周期要执行两次完整的FOC计算,包括两次Clarke、两次Park、两次PI、两次反Park,如果MCU的主频不够高,可能在半个PWM周期内算不完。我一般建议,如果要用DSDU,MCU的主频至少要在100MHz以上,而且FOC计算要用汇编或者CMSIS-DSP库来优化,否则中断里算不完会导致PWM更新错过时刻,电流波形直接乱掉。
2.3 SSDU:单采样双更新的折中方案
SSDU的全称是Single-Sample Double-Update,每个PWM周期只采样一次电流,但更新两次PWM占空比。这个方案听起来有点奇怪——只采样一次,怎么更新两次?其实它的做法是:在PWM周期的某个固定时刻采样一次电流,计算出占空比后,在接下来的两个更新时刻分别更新。第一次更新用新计算的占空比,第二次更新用同样的占空比(或者做一点预测修正)。
这个方案的延迟介于SSSU和DSDU之间。从采样到第一次更新,延迟大约是0.5到1个PWM周期;从采样到第二次更新,延迟大约是1到1.5个PWM周期。平均延迟大约是1个PWM周期,比SSSU小,但比DSDU大。带宽可以做到1.5kHz左右,比SSSU有明显提升,但不如DSDU。
SSDU的优点是CPU负载比DSDU低,只需要一次ADC采样和一次FOC计算,但PWM更新两次可以减小更新延迟。缺点是第二次更新用的占空比是基于第一次采样计算的,如果电流在这段时间内变化很快,第二次更新的占空比就不够准确,会导致电流波形失真。所以SSDU适合电流变化不太剧烈的应用,比如中低速运行的电机。
我在一个电动工具项目上用过SSDU,PWM频率16kHz,电流环带宽做到1.2kHz,转速环带宽300Hz,整体响应比SSSU好很多,但CPU负载只增加了PWM更新那部分,FOC计算还是只做一次,所以对MCU的要求不高。这个方案适合那些MCU性能有限、但又想提升电流环带宽的场景。
2.4 DSSU:双采样单更新的特殊方案
DSSU的全称是Double-Sample Single-Update,每个PWM周期采样两次电流,但只更新一次PWM占空比。这个方案比较特殊,通常用于需要高采样率但更新频率受限于PWM分辨率的场景。
时序是这样的:在PWM周期的峰值和谷值各采样一次电流,但两次采样结果只用来计算一次占空比,在下一个PWM周期开始时更新。这样采样频率是PWM频率的两倍,但更新频率还是等于PWM频率。延迟大约是1个PWM周期,和SSDU差不多,但采样率更高,电流采样更准确。
DSSU的优点是采样率高,可以更准确地捕捉电流的瞬时变化,适合用于电流谐波分析或者需要高精度电流采样的场景。缺点是更新频率没有提升,电流环带宽还是受限于PWM频率,所以动态响应不如DSDU。另外,两次采样需要两次ADC触发,CPU负载比SSSU高,但比DSDU低,因为FOC计算只做一次。
我见过一些做电机参数辨识的项目用DSSU,因为需要高采样率的电流数据来拟合电机模型,但控制更新频率不需要太高。这个方案在工业变频器里也有应用,因为变频器的PWM频率通常不高(2kHz到8kHz),但电流采样需要较高的精度,DSSU可以在不提高PWM频率的情况下提升采样质量。
2.5 四种策略的延迟对比
把四种策略的延迟和带宽整理成表格,方便对比:
| 策略 | 采样次数/周期 | 更新次数/周期 | 平均延迟 | 等效采样频率 | 电流环带宽 | CPU负载 | 适用场景 |
|---|---|---|---|---|---|---|---|
| SSSU | 1 | 1 | 1.5 Tpwm | fpwm | 0.1 fpwm | 低 | 风机、水泵 |
| DSDU | 2 | 2 | 0.5 Tpwm | 2 fpwm | 0.2 fpwm | 高 | 伺服、机器人 |
| SSDU | 1 | 2 | 1.0 Tpwm | fpwm | 0.15 fpwm | 中 | 电动工具、家电 |
| DSSU | 2 | 1 | 1.0 Tpwm | 2 fpwm | 0.1 fpwm | 中 | 参数辨识、变频器 |
从表格可以看出,DSDU的延迟最小,带宽最高,但CPU负载也最重。SSSU的延迟最大,带宽最低,但实现最简单。SSDU和DSSU是折中方案,分别从更新频率和采样频率两个方向做优化。
注意:表中的带宽是经验值,实际带宽还取决于PI参数、电机参数和MCU性能。一般来说,电流环带宽做到采样频率的十分之一到五分之一是安全的,超过五分之一就容易振荡。
3. 延迟从何而来:采样、计算、更新三段时间的精确分析
3.1 采样延迟:ADC触发到转换完成的时间
采样延迟是指从PWM计数器触发ADC采样,到ADC转换完成、数据可读的时间。这段时间包括ADC的采样保持时间和转换时间。以常见的12位ADC为例,采样保持时间通常是几个ADC时钟周期,转换时间取决于ADC的分辨率和时钟频率。如果ADC时钟是50MHz,12位转换需要12个时钟周期,加上采样保持的3个周期,总共15个周期,也就是0.3微秒。这个时间相对于PWM周期(100微秒)来说很小,可以忽略。
但采样延迟还有一个容易被忽略的部分:PWM触发到ADC实际开始采样的延迟。这个延迟包括触发信号的传播延迟、ADC的启动时间等,通常在几十纳秒到几百纳秒之间。如果PWM频率很高(比如100kHz以上),这个延迟就不能忽略了。我实测过,在100kHz PWM频率下,触发延迟大约0.5微秒,占PWM周期的5%,会导致采样时刻偏移,影响电流采样的准确性。
另外,采样延迟还和采样时刻的选择有关。在中心对齐PWM模式下,峰值和谷值时刻是电流纹波最小的时刻,也是采样最准确的时刻。如果在其他时刻采样,电流纹波会导致采样值偏离平均值,影响控制精度。所以SSSU和SSDU通常选择在峰值或谷值采样,而DSDU在峰值和谷值都采样。
3.2 计算延迟:FOC算法执行时间
计算延迟是指从ADC转换完成到FOC算法计算完成、得到新占空比的时间。这段时间取决于MCU的主频、FOC算法的复杂度、是否使用硬件加速等因素。以常见的FOC算法为例,包括Clarke变换、Park变换、两个PI调节器、反Park变换、SVPWM计算,总共大约需要200到500个时钟周期。如果MCU主频是100MHz,那么计算时间大约是2到5微秒。如果主频是200MHz,计算时间可以降到1到2.5微秒。
计算延迟是四种策略里差异最大的部分。SSSU和SSDU每个PWM周期只计算一次,DSDU计算两次,DSSU计算一次但采样两次。所以DSDU的计算延迟最大,SSSU和SSDU的计算延迟最小。但计算延迟本身并不直接决定总延迟,总延迟还取决于计算完成到PWM更新的等待时间。
我实测过不同MCU的FOC计算时间:STM32F4系列(168MHz)大约3微秒,STM32G4系列(170MHz)大约2.5微秒,TI的C2000系列(200MHz)大约1.5微秒。如果PWM频率是10kHz,周期100微秒,计算时间只占3%到5%,完全可以忽略。但如果PWM频率是50kHz,周期20微秒,计算时间就占到了15%到25%,这时候就必须考虑计算延迟对总延迟的影响了。
3.3 更新延迟:从计算完成到PWM生效的时间
更新延迟是指从FOC计算完成、得到新占空比,到新占空比真正写入PWM比较寄存器并生效的时间。这段时间包括写寄存器的执行时间、PWM模块的缓冲机制、以及等待下一个更新时刻的时间。
写寄存器的执行时间通常很短,几个时钟周期就够了。但PWM模块的缓冲机制会导致额外的延迟。很多MCU的PWM模块有影子寄存器,写入比较寄存器的值不会立即生效,而是要等到下一个PWM周期开始或者计数器归零时才生效。这个缓冲机制是为了防止PWM波形出现毛刺,但也会增加更新延迟。
更新延迟的大小取决于更新时刻的选择。如果计算完成后立即更新(在下一个PWM周期开始前),那么更新延迟就是等待下一个PWM周期开始的时间,最多一个PWM周期。如果计算完成后要等到特定的更新时刻(比如峰值或谷值),那么更新延迟就是等待那个时刻的时间,可能是0.5个PWM周期。
SSSU的更新延迟最大,因为计算完成后要等到下一个PWM周期开始才更新,平均等待0.5个PWM周期。DSDU的更新延迟最小,因为计算完成后在下一个峰值或谷值就更新,平均等待0.25个PWM周期。SSDU和DSSU的更新延迟介于两者之间。
3.4 总延迟的计算实例
以PWM频率10kHz、周期100微秒为例,计算四种策略的总延迟:
- SSSU:采样延迟0.3微秒 + 计算延迟3微秒 + 更新延迟50微秒 = 53.3微秒,约0.53个PWM周期。但实际总延迟还包括从采样到下一个PWM周期开始的等待时间,所以总延迟是1.5个PWM周期,即150微秒。
- DSDU:采样延迟0.3微秒 + 计算延迟3微秒 + 更新延迟25微秒 = 28.3微秒,约0.28个PWM周期。实际总延迟是0.5个PWM周期,即50微秒。
- SSDU:采样延迟0.3微秒 + 计算延迟3微秒 + 更新延迟25微秒 = 28.3微秒,约0.28个PWM周期。实际总延迟是1个PWM周期,即100微秒。
- DSSU:采样延迟0.3微秒 + 计算延迟3微秒 + 更新延迟50微秒 = 53.3微秒,约0.53个PWM周期。实际总延迟是1个PWM周期,即100微秒。
从计算可以看出,采样延迟和计算延迟相对于PWM周期来说很小,总延迟主要由更新延迟决定。所以优化电流环延迟的关键是减小更新延迟,也就是让计算完成后的占空比尽快生效。DSDU之所以延迟最小,就是因为它的更新时刻最接近计算完成时刻。
提示:如果MCU主频足够高,计算延迟可以忽略,那么总延迟就完全由更新时刻决定。这时候选择DSDU可以做到0.5个PWM周期的延迟,比SSSU的1.5个PWM周期小了三倍。
4. 实操配置:如何在代码里实现四种策略
4.1 定时器与ADC的联动配置
实现四种策略的第一步是配置定时器和ADC的联动。以STM32为例,定时器1(TIM1)用于生成PWM,ADC1和ADC2用于采样电流。TIM1的更新事件(UEV)和触发事件(TRGO)可以触发ADC采样。
对于SSSU和SSDU,只需要在定时器的峰值或谷值触发一次ADC。配置方法是:设置TIM1的TRGO输出为更新事件,ADC的外部触发源选择TIM1的TRGO,这样每次定时器更新时触发一次ADC采样。然后在ADC转换完成中断里执行FOC计算。
对于DSDU和DSSU,需要在峰值和谷值各触发一次ADC。配置方法是:设置TIM1的TRGO输出为比较事件(比如CCR4),在峰值和谷值各产生一次触发。或者使用两个ADC,一个在峰值触发,一个在谷值触发。然后在两个ADC转换完成中断里分别执行FOC计算(DSDU)或者只执行一次FOC计算(DSSU)。
我一般推荐用TIM1的CCR4作为触发源,因为CCR4可以独立设置比较值,方便调整触发时刻。比如设置CCR4 = 峰值,那么在峰值触发一次;设置CCR4 = 谷值,那么在谷值触发一次。如果要峰值和谷值都触发,可以设置两个CCR通道,或者用定时器的重复计数器。
4.2 中断服务程序的编写要点
中断服务程序是四种策略的核心,不同的策略对应不同的中断结构。
SSSU的中断服务程序最简单:ADC转换完成中断触发,执行FOC计算,计算完成后等待下一个PWM周期开始,在定时器更新中断里更新PWM占空比。或者直接在ADC中断里更新PWM占空比,但要注意更新时刻是否在PWM周期开始前。
DSDU的中断服务程序最复杂:峰值ADC中断触发,执行第一次FOC计算,计算完成后在谷值更新PWM;谷值ADC中断触发,执行第二次FOC计算,计算完成后在峰值更新PWM。两次中断服务程序的代码必须完全对称,执行时间必须一致,否则会导致电流波形不对称。
SSDU的中断服务程序:ADC转换完成中断触发,执行FOC计算,计算完成后在下一个峰值和谷值各更新一次PWM。第一次更新用新计算的占空比,第二次更新用同样的占空比或者做一点预测修正。
DSSU的中断服务程序:峰值和谷值各触发一次ADC,但只在其中一个时刻执行FOC计算,另一个时刻只采样不计算。计算完成后在下一个PWM周期开始时更新PWM。
我在写DSDU的中断服务程序时,会把两次FOC计算封装成同一个函数,用参数区分是峰值还是谷值,这样代码对称性好,不容易出错。另外,两次中断的优先级要设置成一样,不能一个高一个低,否则会导致执行时间不一致。
4.3 PWM占空比更新的时机控制
PWM占空比更新的时机控制是四种策略里最容易出错的地方。很多MCU的PWM模块有影子寄存器,写入比较寄存器的值不会立即生效,而是要等到特定的时刻才生效。这个时刻通常是定时器的更新事件(计数器归零或达到峰值)。
对于SSSU,计算完成后写入比较寄存器,影子寄存器会在下一个更新事件时生效,也就是下一个PWM周期开始时。这个时机是固定的,不需要额外控制。
对于DSDU,计算完成后需要立即更新PWM,不能等到下一个更新事件。这时候需要配置PWM模块为立即更新模式,或者使用预装载寄存器。有些MCU支持在定时器的比较事件时更新影子寄存器,这样可以实现更灵活的更新时机。
对于SSDU,第一次更新需要在计算完成后立即生效,第二次更新需要在下一个更新事件时生效。这需要配置PWM模块支持两种更新模式,或者用两个比较寄存器,一个立即更新,一个缓冲更新。
对于DSSU,更新时机和SSSU一样,都是在下一个PWM周期开始时更新,不需要额外控制。
我实测过,如果更新时机配置错误,电流波形会出现明显的畸变,甚至导致电机无法正常启动。所以配置完PWM更新时机后,一定要用示波器观察电流波形,确认更新时刻是否正确。
4.4 四种策略的代码框架对比
把四种策略的代码框架整理成表格,方便对比:
| 策略 | ADC触发 | 中断结构 | FOC计算次数 | PWM更新时机 | 代码复杂度 |
|---|---|---|---|---|---|
| SSSU | 峰值一次 | 一个ADC中断 | 1次/周期 | 下周期开始 | 低 |
| DSDU | 峰值+谷值 | 两个ADC中断 | 2次/周期 | 峰值/谷值立即 | 高 |
| SSDU | 峰值一次 | 一个ADC中断 | 1次/周期 | 峰值+谷值 | 中 |
| DSSU | 峰值+谷值 | 两个ADC中断 | 1次/周期 | 下周期开始 | 中 |
从代码复杂度来看,SSSU最简单,DSDU最复杂。如果项目时间紧,建议先用SSSU把功能跑通,再根据性能需求升级到SSDU或DSDU。DSSU适合特殊需求,一般项目用不到。
5. 常见问题与排查技巧实录
5.1 电流波形畸变:更新时机错位的排查
电流波形畸变是四种策略里最常见的问题,表现为电流波形上出现尖峰、凹陷或者不对称。我遇到过好几次,最后发现都是更新时机错位导致的。
排查思路是这样的:先用示波器同时观察PWM波形和电流波形,看电流畸变是否与PWM更新时刻对齐。如果畸变出现在PWM周期开始或峰值附近,说明更新时机有问题。然后检查PWM模块的更新模式配置,确认影子寄存器是在正确的时刻生效。最后检查中断服务程序的执行时间,如果计算时间超过了半个PWM周期,会导致更新错过时刻。
我踩过的一个坑是:DSDU模式下,两次中断服务程序的执行时间不一致,峰值中断比谷值中断多执行了几个微秒,导致两次更新的占空比有微小差异,电流波形上出现了二倍频纹波。后来把两次中断的代码完全对称化,问题就解决了。
5.2 电流环振荡:延迟过大导致的相位裕度不足
电流环振荡是另一个常见问题,表现为电流波形持续振荡,电机发出刺耳噪声。很多人以为是PI参数调得太激进,其实根本原因是延迟过大导致相位裕度不足。
排查思路:先测量电流环的开环频率响应,看相位裕度是否小于45度。如果相位裕度不足,说明延迟过大,需要减小延迟或者降低带宽。减小延迟的方法是升级采样-更新策略,比如从SSSU升级到SSDU或DSDU。降低带宽的方法是减小PI参数,但这样会牺牲动态响应。
我一般建议,如果电流环带宽已经做到采样频率的十分之一,还是振荡,那就不要再加大PI参数了,应该考虑升级采样-更新策略。从SSSU升级到DSDU,延迟从1.5个PWM周期降到0.5个PWM周期,相位裕度可以提升30度以上,振荡问题自然就解决了。
5.3 ADC采样噪声:触发时刻与开关噪声的耦合
ADC采样噪声是四种策略里最隐蔽的问题,表现为电流采样值跳动大,电流波形上有随机毛刺。这个问题通常是因为ADC触发时刻与MOSFET开关时刻重合,导致采样到开关噪声。
排查思路:用示波器观察ADC触发信号和MOSFET开关信号,看两者是否重合。如果重合,说明采样时刻需要调整。在中心对齐PWM模式下,峰值和谷值时刻是MOSFET开关时刻,也是开关噪声最大的时刻。如果在这两个时刻采样,就会采样到开关噪声。
解决方法有两种:一是调整采样时刻,避开开关噪声。比如在峰值后延迟几个微秒再采样,等开关噪声衰减后再采样。二是增加RC滤波,在电流采样电路上加RC低通滤波,滤除高频开关噪声。我一般推荐第一种方法,因为RC滤波会增加采样延迟,影响电流环带宽。
5.4 常见问题速查表
| 问题现象 | 可能原因 | 排查方法 | 解决方法 |
|---|---|---|---|
| 电流波形畸变 | 更新时机错位 | 示波器观察PWM和电流波形 | 检查PWM更新模式配置 |
| 电流环振荡 | 延迟过大 | 测量开环频率响应 | 升级采样-更新策略 |
| ADC采样噪声 | 触发时刻与开关噪声耦合 | 观察ADC触发和开关信号 | 调整采样时刻或加RC滤波 |
| 电流波形不对称 | 两次中断执行时间不一致 | 测量两次中断执行时间 | 对称化中断代码 |
| 电机启动失败 | 采样时刻错误 | 检查ADC触发配置 | 修正ADC触发时刻 |
提示:以上问题在四种策略里都可能出现,但DSDU和DSSU因为涉及两次采样或两次更新,出现问题的概率更高。建议在调试DSDU和DSSU时,先用示波器确认时序正确,再上电机测试。
6. 策略选型与性能优化:从项目需求反推最佳方案
6.1 根据带宽需求选择策略
选型的第一个依据是电流环带宽需求。如果带宽需求在0.1倍PWM频率以下,SSSU就够了;如果在0.1到0.15倍之间,SSDU或DSSU更合适;如果在0.15倍以上,必须用DSDU。
举个例子:PWM频率10kHz,带宽需求1kHz,那么SSSU就够了(0.1倍)。如果带宽需求1.5kHz,SSSU不够,需要SSDU或DSSU(0.15倍)。如果带宽需求2kHz,必须用DSDU(0.2倍)。
我一般建议,选型时留20%的余量。比如带宽需求1.2kHz,虽然SSSU的理论极限是1kHz,但实际做到1kHz已经很勉强了,建议直接用SSDU,做到1.5kHz,留出余量。
6.2 根据MCU性能选择策略
选型的第二个依据是MCU性能。DSDU需要每个PWM周期执行两次FOC计算,对MCU主频要求最高。如果MCU主频低于100MHz,不建议用DSDU,因为计算时间可能超过半个PWM周期,导致更新错过时刻。
SSDU和DSSU每个PWM周期只执行一次FOC计算,对MCU主频要求较低,100MHz以下也能用。SSSU对MCU要求最低,50MHz也能跑。
我实测过,STM32F103(72MHz)跑SSSU没问题,跑SSDU勉强可以,跑DSDU就力不从心了。STM32F4(168MHz)跑DSDU没问题,但要注意优化代码,用CMSIS-DSP库加速。TI的C2000系列(200MHz)跑DSDU很轻松,因为它的FOC计算有硬件加速。
6.3 根据应用场景选择策略
选型的第三个依据是应用场景。风机、水泵这类对动态响应要求不高的场景,SSSU就够了,没必要用DSDU,浪费MCU资源。伺服、机器人关节这类对动态响应要求高的场景,必须用DSDU,否则带宽上不去。
电动工具、家电这类对成本敏感的场景,可以用SSDU,在性能和成本之间取得平衡。参数辨识、电流谐波分析这类需要高采样率的场景,可以用DSSU,在不提高PWM频率的情况下提升采样质量。
我在一个机器人关节项目上用的就是DSDU,PWM频率20kHz,电流环带宽做到4kHz,转速环带宽1kHz,整体响应非常快,关节动作很平滑。后来在一个风机项目上用的SSSU,PWM频率10kHz,电流环带宽800Hz,转速环带宽200Hz,风机启动和调速都很稳,完全满足需求。
6.4 性能优化的几个实操技巧
第一个技巧是用CMSIS-DSP库加速FOC计算。CMSIS-DSP库提供了优化的数学函数,比如arm_sin_cos_f32、arm_sqrt_f32等,比标准库函数快很多。我实测过,用CMSIS-DSP库可以把FOC计算时间缩短30%以上。
第二个技巧是把FOC计算放在RAM里执行。Flash的访问速度比RAM慢,如果FOC计算代码放在Flash里,执行时间会变长。把FOC计算代码复制到RAM里执行,可以缩短计算时间。STM32支持把代码放到RAM里执行,具体方法是在链接脚本里把FOC计算函数放到RAM段。
第三个技巧是用硬件加速器。有些MCU有专门的FOC硬件加速器,比如TI的C2000系列有CLA(控制律加速器),可以独立执行FOC计算,不占用主核资源。如果MCU有硬件加速器,一定要用上,可以大幅缩短计算时间。
第四个技巧是优化中断服务程序的代码。中断服务程序里不要做浮点运算,尽量用定点运算。浮点运算在中断里会保存和恢复浮点寄存器,增加执行时间。如果必须用浮点,确保MCU有FPU(浮点运算单元),并且开启FPU。
注意:优化FOC计算时间时,不要牺牲代码的可读性和可维护性。我见过一些项目为了缩短计算时间,把代码写得非常晦涩,后来维护时根本看不懂。建议在优化前先测量计算时间,确认瓶颈在哪里,再针对性优化。
7. 实测数据与经验总结
7.1 四种策略的实测带宽对比
我在同一个硬件平台上(STM32G474,170MHz,PWM频率10kHz)实测了四种策略的电流环带宽:
| 策略 | 实测带宽 | 阶跃响应上升时间 | CPU负载 |
|---|---|---|---|
| SSSU | 950Hz | 370微秒 | 15% |
| DSDU | 2.1kHz | 170微秒 | 45% |
| SSDU | 1.4kHz | 250微秒 | 25% |
| DSSU | 1.0kHz | 350微秒 | 30% |
从实测数据可以看出,DSDU的带宽最高,是SSSU的两倍多,但CPU负载也最高,是SSSU的三倍。SSDU的带宽比SSSU高50%,CPU负载只增加了10个百分点,性价比很高。DSSU的带宽和SSSU差不多,但CPU负载更高,所以除非需要高采样率,否则不推荐DSSU。
7.2 不同PWM频率下的策略选择
PWM频率也会影响策略选择。PWM频率越高,PWM周期越短,计算延迟占总延迟的比例越大。如果PWM频率很高(比如50kHz以上),计算延迟就不能忽略了,这时候需要选择计算次数少的策略,比如SSSU或SSDU。
我实测过,PWM频率20kHz时,DSDU的带宽可以做到4kHz,但CPU负载达到80%,几乎跑满了。PWM频率50kHz时,DSDU的计算时间超过了半个PWM周期,无法正常工作,只能降级到SSDU。
所以选型时要综合考虑PWM频率和MCU性能。如果PWM频率高、MCU性能有限,建议用SSSU或SSDU。如果PWM频率低、MCU性能充足,可以用DSDU。
7.3 个人经验:从SSSU到DSDU的升级路径
我一般建议项目按这个路径升级:先用SSSU把功能跑通,确认电机能正常启动、调速、制动。然后测量电流环带宽,如果满足需求,就不升级了。如果不满足,先升级到SSDU,因为SSDU的代码改动小,只需要增加PWM更新次数,FOC计算不用改。如果SSDU还不够,再升级到DSDU,这时候需要改中断结构,增加一次FOC计算。
这个升级路径的好处是风险可控,每一步都有明确的性能提升,不会一下子改动太大导致项目失控。我见过一些项目一上来就用DSDU,结果调试了两周还没跑通,最后不得不退回SSSU。所以建议循序渐进,先跑通再优化。
最后分享一个小技巧:在调试四种策略时,一定要用示波器观察PWM波形和电流波形,确认时序正确。我一般会把PWM波形、ADC触发信号、电流波形同时显示在示波器上,这样一眼就能看出时序对不对。如果时序不对,先修时序,再调PI参数,否则调PI参数是白费功夫。