4、电流采样与重构:单电阻、双电阻、三电阻采样原理,相电流重构算法,采样时序与死区补偿
做FOC控制,说白了就是在跟电流打交道。你算得再准,PWM给得再漂亮,要是电流采回来就是错的,那整个系统就是空中楼阁。我刚开始做电机驱动那会儿,就吃过这个亏——算法调了半个月,波形怎么看怎么不对劲,最后发现是采样时序没搞对,白白浪费了时间。
这一章,咱们就把电流采样这件事彻底讲透。单电阻、双电阻、三电阻,这三种方案我都实际用过,各有各的脾气。我会把原理、算法、时序、补偿这些关键点,结合我踩过的坑,一次性说清楚。
4.1 三种采样方案的核心差异
先看一张总览图,把三种方案的结构和适用场景理清楚。
从上图可以看得很清楚:三电阻最贵但最省心,单电阻最便宜但最折腾,双电阻是中间路线。我个人习惯,如果项目对成本不敏感,优先选三电阻;如果是消费级产品,双电阻是主流;只有在小功率、极致成本要求的场景下,我才会考虑单电阻。
4.2 三电阻采样:最直接,也最可靠
三电阻采样的原理很简单:在三个下桥臂的MOSFET源极和GND之间,各串联一个精密采样电阻。当某一相的下管导通时,该相的电流就会流过对应的采样电阻,产生一个压降。ADC测量这个压降,除以电阻值,就得到了电流。
这里有个关键点——采样时机。你想想看,下管导通的时候才能采到电流,那如果某一相的上管一直开着、下管一直关着,这相电流就采不到。所以采样必须发生在PWM周期的特定时刻。
采样窗口的计算:
假设PWM周期为Tpwm,死区时间为Tdead,下管最小导通时间为Ton_min,那么有效采样窗口为:
T_sample = Tpwm - Tdead - Ton_min
这个窗口必须大于ADC的采样转换时间,否则数据就是错的。
我在做一款伺服驱动器时,遇到过一个问题:PWM频率设到了20kHz,周期只有50μs,死区占了2μs,ADC采样需要1μs,算下来采样窗口只有47μs,看起来够用。但实际调试时发现,在低占空比区域,下管导通时间太短,采样窗口被压缩到只有几百纳秒,ADC根本来不及转换。后来我加了一个采样保持电路,才把这个问题解决掉。
4.3 双电阻采样:性价比之王
双电阻采样只用了两个采样电阻,通常放在V相和W相的下桥臂。U相的电流通过基尔霍夫电流定律计算得到:
Iu = -(Iv + Iw)
这个公式看起来简单,但实际用起来有几个坑。我一个个说。
第一个坑:当某一相的占空比接近0%或100%时,该相下管的导通时间太短,采样窗口不够。这时候你只能采到两相电流,第三相靠算。但如果两相都采不到呢?那就麻烦了。
第二个坑:计算出来的第三相电流,精度取决于前两相的测量精度。如果前两相有噪声,第三相就是噪声的叠加。我曾经在一个项目中,发现U相电流的噪声比V相和W相大了将近一倍,就是因为这个原因。
我的建议:双电阻采样时,尽量让采样时刻对齐在PWM周期的中间点。这时候三相电流都比较稳定,噪声最小。具体做法是在PWM定时器的中间点触发ADC采样,而不是在边沿触发。
4.4 单电阻采样:最省钱,也最烧脑
单电阻采样只在直流母线上放一个采样电阻。它的原理是利用PWM开关状态的变化,在不同时间段内,母线电流等于不同相的相电流。通过在一个PWM周期内多次采样,可以重构出三相电流。
举个例子:当U相上管和V相下管导通时,母线电流等于U相电流;当U相上管和W相下管导通时,母线电流等于U相电流的负值。通过在不同开关状态下采样,再结合PWM占空比信息,就能算出三相电流。
这个算法的核心是:在一个PWM周期内,至少需要两次有效的采样。而且这两次采样必须对应不同的相电流。
注意:单电阻采样有一个著名的「不可观测区域」问题。当三相占空比非常接近时(比如都在50%附近),所有开关状态变化都很短,你根本找不到两个足够宽的采样窗口。这时候重构算法会失效。
解决办法有两种:一是修改PWM模式,插入额外的开关状态;二是采用预测算法,用上一周期的数据推算本周期的电流。我一般两种方法结合用,效果最好。
4.5 相电流重构算法详解
这里我以双电阻采样为例,给出一个完整的相电流重构流程。单电阻的算法更复杂,但思路是一样的。
// 双电阻采样相电流重构
// 假设采样电阻在 V相 和 W相
typedef struct {
float Iu; // U相电流
float Iv; // V相电流
float Iw; // W相电流
} PhaseCurrent_t;
PhaseCurrent_t ReconstructCurrent(float adc_v, float adc_w) {
PhaseCurrent_t current;
// 1. 直接读取V相和W相电流
current.Iv = adc_v / R_SHUNT / GAIN_AMP;
current.Iw = adc_w / R_SHUNT / GAIN_AMP;
// 2. 计算U相电流
current.Iu = -(current.Iv + current.Iw);
// 3. 检查是否在不可观测区域
// 如果某相占空比接近0或100%,该相采样可能无效
if (IsInDeadZone(duty_v) || IsInDeadZone(duty_w)) {
// 进入补偿模式
current = CompensateWithPrediction(current);
}
return current;
}
这段代码看起来简单,但实际工程中要考虑的事情很多。比如ADC的偏移校准、增益校准、滤波处理等等。我习惯在初始化时做一次自动校准,把ADC的零漂和增益误差存下来,后续每次采样都做补偿。
4.6 采样时序与死区补偿
采样时序是电流采样中最容易被忽视、但影响最大的环节。我见过太多工程师,算法写得漂亮,硬件设计也没问题,就是采样时序没搞对,导致整个系统性能上不去。
先看一个典型的采样时序图:
从图中可以看到,采样点通常选在PWM周期的中间位置。为什么?因为这时候三相电流已经稳定,开关噪声最小。如果你在边沿采样,正好赶上开关管的上升沿或下降沿,那噪声会直接灌进ADC,采出来的数据根本不能用。
死区补偿是另一个关键点。死区是为了防止上下管直通而插入的延迟时间,但它会导致输出电压的畸变。这种畸变会反映在电流波形上,表现为电流的过零失真。
我常用的死区补偿方法有两种:
- 电压前馈补偿:根据电流方向,在PWM占空比中叠加一个补偿量。电流为正时加一个正补偿,为负时加一个负补偿。
- 电流反馈补偿:实时检测电流过零点,在过零点附近调整补偿量的大小。
死区补偿的工程经验:
我曾经在一个项目中,死区时间设了3μs,结果电机在低速运行时噪音特别大。后来我用示波器抓了电流波形,发现过零点附近有明显的「台阶」。通过引入自适应死区补偿算法,根据当前转速和负载动态调整补偿量,噪音问题才彻底解决。
具体的补偿量计算公式:
V_comp = sign(I) * T_dead * V_dc / T_pwm
其中sign(I)是电流方向,T_dead是死区时间,V_dc是母线电压,T_pwm是PWM周期。
4.7 采样电路的硬件设计要点
最后聊几句硬件。采样电路设计不好,软件再怎么补偿也白搭。
- 采样电阻的选择:阻值不能太大,否则功耗高、发热严重;也不能太小,否则信噪比不够。一般取几毫欧到几十毫欧,具体看电流范围。
- 运放的选择:要选低失调电压、低温漂的运放。我常用的有AD8418、INA240这些。
- PCB布局:采样电阻到运放的走线要短,要远离功率走线。差分走线最好,能抑制共模噪声。
- 滤波电容:在运放输入端加RC滤波,截止频率一般设在几MHz,滤掉开关噪声。
一个小技巧:在采样电阻两端并联一个小电容(几十pF),可以滤掉高频噪声。但电容不能太大,否则会影响采样信号的建立时间。我一般取47pF到100pF之间,具体值要根据实际波形调整。
好了,电流采样这部分就讲到这里。三种方案各有优劣,选哪种取决于你的项目需求。但不管选哪种,采样时序和死区补偿都是绕不开的坎。把这些搞明白了,你的FOC控制就成功了一半。