首页 / 驱动算法 / 进阶篇

电流采样:单电阻/双电阻/三电阻方案与单电阻重构

FOC 是一个"电流环决定性能、采样决定电流环"的系统。三电阻、双电阻、单电阻——三种采样拓扑,三种成本与精度的取舍。本文讲清它们各自怎么采、什么时候采、为什么单电阻要"重构"、以及采样窗口不够时怎么办,配 PWM 周期采样窗口仿真器与 C 代码。

1. 为什么电流采样是 FOC 的地基

FOC 的电流环是最内环,也是最"快"的环:电流环带宽上不去,速度环、位置环再好的参数都被架在空中。而电流环的所有运算——Clarke/Park 变换、PI 调节、反 Park、SVPWM——全部建立在"三个相电流采得准不准"之上

所以电流采样方案的选择与实现质量,直接决定了这台驱动器"能多快、能多稳"。

2. 三种采样方案总览

三相电流的测量方式,核心区别在于采样电阻放几个、放在哪

方案采样电阻怎么得到三相电流成本精度采样窗口约束典型应用
三电阻3 个(每相下桥)直接采 ia、ib、ic最高各相下管导通时各采一次高性能伺服、机器人关节
双电阻2 个(两相下桥)采两相 + 第三相重构 ic=−(ia+ib)两相下管同时导通窗口通用伺服、中高端驱动器
单电阻1 个(直流母线)一个周期内两次采样母线电流,按矢量重构两相中(受窗口限制)需要两个非零矢量窗口,低调制/扇区边界会不足低成本、小功率、无刷电调

一句话:三电阻"最贵最省心",双电阻"性价比之王",单电阻"最便宜但最讲究时机"。

3. 采样电阻位置与电流的关系

3.1 下桥臂采样电阻(三/双电阻)

电阻串在下桥臂 MOSFET 与地之间,只有当该相下管导通时,流过电阻的电流才等于该相相电流。上管导通时该相电流走母线,不经过下桥电阻。

3.2 直流母线采样电阻(单电阻)

单个电阻放在直流母线上,流过的是母线电流。母线电流不等于任何一相电流,它等于当前时刻所有"上管导通相"的相电流之和。巧的是,在 SVPWM 的每个非零矢量作用期间,母线电流恰好等于某一相的相电流

单电阻重构核心:母线电流 = 特定矢量下的相电流

矢量 (1,0,0):Ibus = +ia

矢量 (1,1,0):Ibus = −ic

矢量 (0,1,1):Ibus = +ia(反向)… 依扇区而定

因此在一个 PWM 周期内采两次(分别落在两个相邻非零矢量期间),就能解出两相电流,第三相用基尔霍夫补齐。

4. 采样时刻的选择:为什么要"卡"在开关状态里

无论哪种方案,采样都必须避开开关动作瞬间——MOSFET 开关瞬间有振铃、dv/dt 噪声、死区期间的续流二极管换流,此刻采样的电压是"脏"的。工程上用中心对齐(对称)PWM,在开关状态"稳定"的窗口内采样:

✅ 采样时刻三原则

同步:ADC 触发与 PWM 计数同步,消除抖动的等效延迟;② 避开开关沿:采样点与最近的开关动作间隔 ≥ 几百 ns~1µs(含死区与振铃收敛);③ 稳定窗口:采样必须在目标开关状态持续期内完成,且该窗口要"够宽"。

5. 单电阻电流重构详解(重点)

5.1 重构原理

以中心对齐 PWM 的一个周期为例,七段式 SVPWM 按顺序经历:000 → 非零矢量 U1 → 非零矢量 U2 → 111 → U2 → U1 → 000。若分别在 U1 和 U2 期间各采样一次母线电流:

扇区与重构公式(示例,随扇区旋转)

第 1 扇区:采到 Ibus(U1) = ia、Ibus(U2) = −ic → ib = −(ia+ic)

第 2 扇区:采到 Ibus(U1) = ib、Ibus(U2) = ia → ic = −(ia+ib)

各扇区采样组合按 60° 旋转轮换,查表确定本次采到的是哪两相

5.2 重构失效区:为什么单电阻"挑"工况

对策(工程上常组合使用):

  1. 移相采样:把两个采样点往非零矢量中点偏移,尽量在窗口中心采,提高抗干扰
  2. 注入测量矢量:失效区内额外插入一个短的非零矢量(牺牲一点谐波/噪声)换取可测窗口
  3. 相邻周期补采:本周期缺的相用相邻周期采到的值补(电流变化快时引入误差,需权衡)
  4. 最小脉冲钳位:把过短的矢量脉宽钳位到最小可测宽度,同时按钳位量修正输出电压
  5. 控制层规避:低调制/零速附近改用双电阻或三电阻,或让调制不要长时间停留失效区

6. 偏移与增益校准

采样链路(电阻→运放→ADC)必然有直流偏移增益误差,不校准会直接污染电流环:

校准项做法消除的误差
零电流偏移下桥全关(或全开),三相无电流时采 N 次取平均,存为 offset运放偏置、ADC 失调 → 采样"假电流"
增益校准注入已知电流/已知电压,比对采样值与真实值,算每路增益系数电阻容差、运放增益误差 → 三相不对称
温漂关键场合做温度补偿或在运行中周期性重校零(母线零电流时)运放/电阻随温度漂移
⚠️ 偏移不校准的后果

一个固定的偏移电流,经 Clarke/Park 后会变成一个随电角度旋转的 dq 轴正弦扰动,表现为转矩在一个电周期内波动、零速时 dq 电流"打圈"、定位出现周期性偏差——而且它不会随 PI 消除,只能靠校准干掉。

7. 交互式演示:PWM 周期与采样窗口可视化

下面的仿真器画出一个中心对齐 PWM 周期内三相的开关状态。拖动调制比、切换扇区,观察:① 三相各相占空比如何变化;② 双电阻的"两相下管同时导通窗口"落在哪;③ 单电阻重构依赖的两个非零矢量窗口是否"够宽"(窄到发红=重构失败区)。

SVPWM 周期采样窗口仿真:三/双/单电阻的采样时机
扇区 0 · 双电阻可采窗口 -- · 单电阻重构 --

观察要点:

8. C 语言实现

8.1 三电阻:ADC 同步触发采样(定时器与 PWM 同步)

/* 三电阻采样:PWM 中心对齐,三角波谷值触发 ADC 注入组 */ /* 伪代码:用 PWM 定时器的 TRGO/CC 事件触发 ADC,省去软件对齐 */ /* 1. 定时器配置:中心对齐模式,更新事件(上溢/下溢) → ADC 注入触发 */ static float i_offset[3]; /* 上电校准的零电流偏移 */ void cur_sampling_init(void) { /* PWM 中心对齐,载波频率 f_pwm */ /* ADC1 注入组:通道 A/B/C 下桥采样电阻,定时器 TRGO 触发 */ /* 触发时刻 = 三角波谷值(零矢量中点),此时开关状态最稳定 */ } void cur_offset_calibrate(void) { /* 下桥全关/全开,无电流时采 N 次取平均,存偏移 */ for (int k=0; k<64; k++) { adc_inject_start(); adc_wait_done(); i_offset[0] += adc_read(0); i_offset[1] += adc_read(1); i_offset[2] += adc_read(2); } i_offset[0] /= 64.0f; i_offset[1] /= 64.0f; i_offset[2] /= 64.0f; } void cur_read_3shunt(float *ia, float *ib, float *ic) { float a = adc_read(0) - i_offset[0]; float b = adc_read(1) - i_offset[1]; float c = adc_read(2) - i_offset[2]; float k = 1.0f / shunt_gain(); /* 电流/码值换算系数 */ *ia = a * k; *ib = b * k; *ic = c * k; }

8.2 双电阻:两相采样 + 第三相重构

/* 双电阻:在零矢量中点采 A、B 两相,C 相用基尔霍夫补齐 */ void cur_read_2shunt(float *ia, float *ib, float *ic) { /* 在中心对齐 PWM 的三角波谷值触发 ADC(此时两相下管同时导通) */ float a = adc_read(0) - i_offset[0]; float b = adc_read(1) - i_offset[1]; float k = 1.0f / shunt_gain(); *ia = a * k; *ib = b * k; *ic = -(*ia + *ib); /* i_a + i_b + i_c = 0 */ }

8.3 单电阻:两次采样 + 按扇区重构

/* 单电阻重构:一个周期内两次采样母线电流,按扇区解两相 */ typedef struct { uint8_t sector; /* 当前扇区 0~5 */ float i_bus1; /* 第一次采样(U1 矢量期间) */ float i_bus2; /* 第二次采样(U2 矢量期间) */ } single_shunt_t; /* 扇区 → 两相电流重构映射表(0~5 扇区) */ /* 每行:(第一采样=哪相, 第二采样=哪相),按标准 SVPWM 矢量定义 */ static const int8_t recon_map[6][2] = { { 0, 2 }, /* 扇区0: i_a, -i_c */ { 1, 0 }, /* 扇区1: i_b, i_a */ { 2, 1 }, /* 扇区2: -i_c, i_b */ { 0, 2 }, /* 扇区3: i_a, -i_c(反向) */ { 1, 0 }, /* 扇区4 */ { 2, 1 } /* 扇区5 */ }; void cur_read_1shunt(single_shunt_t *s, float *ia, float *ib, float *ic) { float ia_ = 0.0f, ib_ = 0.0f, ic_ = 0.0f; int8_t p1 = recon_map[s->sector][0]; int8_t p2 = recon_map[s->sector][1]; float i1 = s->i_bus1, i2 = s->i_bus2; /* 把两次采样值放到对应相上(符号由矢量方向决定,见公式) */ float tmp[3] = { 0.0f, 0.0f, 0.0f }; tmp[p1] = i1; tmp[p2] = -i2; /* 第二采样通常为反向相电流(取决于矢量) */ ia_ = tmp[0]; ib_ = tmp[1]; ic_ = tmp[2]; /* 未直接采到的第三相用基尔霍夫补齐;实际符号/相别需按矢量方向核对 */ if (p1 == 0 || p2 == 0) { /* a 相已采,由 i_b 或 i_c 补另一相 */ } *ia = ia_; *ib = ib_; *ic = ic_; }

9. 工程要点与常见误区

要点 1:采样窗口不足是单电阻的第一杀手

低调制、扇区边界处非零矢量时间过短,重构必失败。先按 Tmin ≥ Tadc + Tsetup 算最小可测脉宽(ADC 转换 + 信号建立时间,典型 1~2µs),再决定是否需要注入测量矢量或改用双/三电阻。

要点 2:采样点要落在"开关状态稳定"处

开关沿附近的振铃和死区换流会污染采样。中心对齐 PWM 的三角波谷值/峰值是最佳触发点,用硬件(定时器 TRGO→ADC 注入)同步,避免软件轮询的对齐抖动。

要点 3:偏移校准必须做,且要定期重校

运放偏置/ADC 失调会产生随电角度旋转的 dq 扰动。上电做零电流偏移校准,运行中在母线零电流窗口(如零矢量期间)周期性重校,对抗温漂。

要点 4:增益校准保证三相对称

三个电阻 + 三路运放增益不可能完全一致,增益失配会让 Clarke 变换引入 2 倍频扰动。出厂做增益校准,把每路增益系数归一。

要点 5:采样延迟计入环路设计

采样+计算+更新的总延迟(常为 1~1.5 个 PWM 周期)要计入电流环相位裕度预算(见《三闭环整定与滞后》),不要只调 PI 不看延迟。

误区 1:认为"采样快 = 采样准"

采样时刻选错,采得再快也是采到噪声。关键是"时刻对不对、窗口稳不稳",不是 ADC 多快。

误区 2:单电阻靠"多采几次平均"解决窗口不足

窗口不足是时间上不够 ADC 转换,平均救不了。要注入测量矢量、钳位最小脉宽或换拓扑。

误区 3:重构符号/相别搞错

单电阻重构的"本次采到哪一相、正负方向"随扇区轮换,查表或代码里符号标错会得到相位错乱的电流 → 电流环发散。务必按扇区逐条核对重构映射表。

10. 小结

  1. 电流采样决定电流环性能:噪声、延迟、偏移、增益四项都要管
  2. 三电阻直接采三相(最贵最稳)、双电阻采两相重构(性价比之王)、单电阻采母线按矢量重构(最便宜最讲究时机)
  3. 采样时刻选在中心对齐 PWM 的稳定窗口,避开开关沿,硬件同步触发
  4. 单电阻重构靠一个周期两次采样 + 扇区查表;低调制/扇区边界会失效,需注入测量矢量等对策
  5. 零电流偏移与增益校准是出厂必备,运行期重校抗温漂
  6. 采样延迟要计入电流环相位预算,不能只靠调 PI