2. FOC电流环调试实战要点:电流采样与偏置校准

各位工程师朋友,咱们直接进入正题。电流采样是FOC控制的地基,地基没打好,后面什么SVPWM、观测器全是白搭。我见过太多人花大把时间调PI参数,结果发现是电流采样偏置没校好——那种挫败感,啧,我懂。

这一节咱们就掰开揉碎,把电流采样的原理、偏置误差的来源,以及怎么在校准代码里把它干掉,一次性说清楚。

2.1 相电流采样原理:三种主流方案

先看采样拓扑。目前主流方案就三种:单电阻、双电阻、三电阻。它们各有各的脾气,我按实际项目中的选择优先级来聊。

方案 采样电阻数 成本 精度 适用场景
单电阻 1个(直流母线侧) 最低 中等(需重构) 低成本风机、泵类
双电阻 2个(下桥臂) 中等 较高 通用伺服、机器人关节
三电阻 3个(下桥臂) 最高 最高 高精度、大功率驱动

2.1.1 单电阻采样

单电阻采样只用一个电阻,放在直流母线负端。它的核心逻辑是:在PWM周期的不同时刻,母线电流等于不同相的电流。通过在一个周期内采样两次,就能重构出两相电流。

但这里有个坑——采样窗口不够。当占空比接近0%或100%时,有效采样时间太短,ADC根本来不及稳定。我在做一款低压风机驱动器时就吃过这个亏,低速时电流波形全是毛刺,后来加了最小脉宽限制才解决。

2.1.2 双电阻采样

双电阻是目前最常用的方案。两个电阻分别放在V相和W相的下桥臂,U相电流通过基尔霍夫定律计算得到:Iu = -(Iv + Iw)。

它的优点是:任意时刻都能直接采样两相,不需要像单电阻那样卡采样窗口。缺点是:当某一相占空比接近0时,该相下桥臂没有电流流过,采样值会丢失。我一般会在代码里加一个移相补偿逻辑,把采样点避开死区。

2.1.3 三电阻采样

三电阻方案最直接,每相一个采样电阻,各相独立。精度最高,但成本也最高。一般用在伺服驱动器或大功率场合。它的调试最简单——直接读ADC值就行,不需要重构。

我的建议: 如果你做通用产品,优先选双电阻。性价比最高,调试难度适中。单电阻适合成本敏感且对低速性能要求不高的场景。三电阻?除非甲方明确要求,否则别给自己找麻烦。

2.2 采样偏置误差的来源与影响

好了,原理讲完,咱们聊聊偏置。偏置误差说白了就是:当电流为0时,ADC读到的值不是0。

为什么会这样?三个主要原因:

  • 运放输入偏置电压: 运放不是理想的,输入端总有个几mV到几十mV的偏置。这个偏置会被放大,直接反映在ADC读数上。
  • ADC参考电压漂移: 参考电压Vref如果不够稳,ADC的零点也会跟着飘。我遇到过用板载LDO给ADC供电的情况,温度一上来,零点能飘20个LSB。
  • PCB布局引入的共模噪声: 采样电阻到运放的走线如果太长,或者地线处理不好,共模噪声会叠加到采样信号上。嗯,这个在电机驱动板上尤其常见。

偏置误差的影响有多大?我直接给你算笔账:

  • 假设你的ADC是12位,Vref=3.3V,那么1个LSB对应约0.8mV。
  • 如果偏置是10个LSB,那就是8mV的误差。
  • 对于0.01Ω的采样电阻,这相当于0.8A的电流误差。
  • 在FOC里,这个误差会直接变成转矩波动和转速抖动。

注意: 偏置误差不是固定的!它会随温度、电源电压变化。所以只做一次出厂校准是不够的,最好在每次电机启动前做一次快速校准。

2.3 偏置校准的步骤与代码实现

校准的思路其实很简单:让电机处于静止状态(电流为0),然后采集N次ADC值,取平均作为偏置值。后续每次采样都减去这个偏置值。

具体步骤:

  1. 确保电机静止: 关闭PWM输出,或者让所有下桥臂导通(主动短路)。我个人习惯用主动短路,这样能更快让电流归零。
  2. 采集ADC样本: 连续采集M次(我一般取64次或128次),存入数组。
  3. 剔除异常值: 去掉最大值和最小值,防止偶发噪声干扰。
  4. 计算平均值: 对剩余样本求平均,得到偏置值。
  5. 保存偏置值: 存入全局变量或结构体,供后续采样使用。

下面是我在实际项目中用的一段校准代码,C语言风格,跑在STM32G4上:

/* 电流采样偏置校准函数 */
/* 返回值:0-成功,-1-校准失败 */
int current_offset_calibrate(float *offset_u, float *offset_v, float *offset_w)
{
    #define SAMPLE_COUNT  64
    uint16_t raw_buf_u[SAMPLE_COUNT];
    uint16_t raw_buf_v[SAMPLE_COUNT];
    uint16_t raw_buf_w[SAMPLE_COUNT];
    uint32_t sum_u = 0, sum_v = 0, sum_w = 0;
    uint16_t min_u, max_u, min_v, max_v, min_w, max_w;
    int i;

    /* 1. 关闭PWM,使电机处于静止状态 */
    pwm_disable();
    delay_ms(10);  /* 等待电流衰减 */

    /* 2. 采集原始数据 */
    for(i = 0; i < SAMPLE_COUNT; i++) {
        adc_read_all(&raw_buf_u[i], &raw_buf_v[i], &raw_buf_w[i]);
        delay_us(10);  /* 采样间隔 */
    }

    /* 3. 剔除最大值和最小值 */
    min_u = max_u = raw_buf_u[0];
    min_v = max_v = raw_buf_v[0];
    min_w = max_w = raw_buf_w[0];

    for(i = 0; i < SAMPLE_COUNT; i++) {
        /* U相 */
        if(raw_buf_u[i] < min_u) min_u = raw_buf_u[i];
        if(raw_buf_u[i] > max_u) max_u = raw_buf_u[i];
        /* V相 */
        if(raw_buf_v[i] < min_v) min_v = raw_buf_v[i];
        if(raw_buf_v[i] > max_v) max_v = raw_buf_v[i];
        /* W相 */
        if(raw_buf_w[i] < min_w) min_w = raw_buf_w[i];
        if(raw_buf_w[i] > max_w) max_w = raw_buf_w[i];
    }

    /* 4. 求和(跳过最大值和最小值) */
    for(i = 0; i < SAMPLE_COUNT; i++) {
        if(raw_buf_u[i] != min_u && raw_buf_u[i] != max_u) sum_u += raw_buf_u[i];
        if(raw_buf_v[i] != min_v && raw_buf_v[i] != max_v) sum_v += raw_buf_v[i];
        if(raw_buf_w[i] != min_w && raw_buf_w[i] != max_w) sum_w += raw_buf_w[i];
    }

    /* 5. 计算平均值并转换为电流值(单位:A) */
    /* 假设ADC为12位,Vref=3.3V,运放增益为50,采样电阻0.01Ω */
    *offset_u = (float)sum_u / (SAMPLE_COUNT - 2) * 3.3f / 4096.0f / 50.0f / 0.01f;
    *offset_v = (float)sum_v / (SAMPLE_COUNT - 2) * 3.3f / 4096.0f / 50.0f / 0.01f;
    *offset_w = (float)sum_w / (SAMPLE_COUNT - 2) * 3.3f / 4096.0f / 50.0f / 0.01f;

    /* 6. 恢复PWM */
    pwm_enable();

    return 0;
}

经验之谈: 校准完成后,我习惯再读一次ADC值,验证一下偏置是否真的被消除了。如果发现偏置仍然大于2~3个LSB,我会检查一下运放供电是否稳定,或者采样电阻的焊接有没有虚焊。曾经有一次,我折腾了一整天,最后发现是采样电阻的焊盘裂了——嗯,那感觉,你懂的。

2.4 知识体系总览

为了让你对整个章节的逻辑有个直观印象,我画了一张图。它把采样原理、偏置来源、校准流程串在了一起,方便你对照着看。

电流采样与偏置校准知识体系 单电阻采样 双电阻采样 三电阻采样 运放输入偏置 ADC参考电压漂移 PCB共模噪声 转矩波动 + 转速抖动 校准流程:电机静止 → 采集N次 → 剔除异常 → 平均 → 保存偏置 代码实现:current_offset_calibrate()

这张图从左到右、从上到下,把整个知识链条串起来了。你调试的时候如果遇到问题,可以顺着这个图排查:先看采样方案对不对,再看偏置来源,最后检查校准流程和代码。

好了,这一节的内容就到这儿。偏置校准是电流环调试的第一步,也是最重要的一步。把它做扎实了,后面的电流环带宽、PI参数整定才能有意义。别嫌麻烦,磨刀不误砍柴工。