☰
PMSM FOC双电阻电流采样方案:从硬件设计到代码落地的完整实践
2026/9/29 17:01:29 网站建设 项目流程

上周帮朋友调一块自制的无刷驱动板,他照着某个开源项目抄了一套单电阻电流重构方案,结果在低速大扭矩段怎么调都抖,示波器上重构出来的电流波形在扇区边界毛刺一片。我让他把采样改回双电阻,硬件只加了一颗采样电阻和一级放大电路,代码里删掉了大半补盲区的逻辑,半天就转顺了。

这个场景我猜很多人遇到过。在PMSM FOC驱动里,电流采样是整个闭环的地基,电流反馈不准,后面Id/Iq算得再漂亮也是空中楼阁。网上搜“stm32f103rct6无刷电机foc驱动代码”、“FOC电流采样”,一大半教程都在讲单电阻重构,好像不搞单电阻就显得不够高级。但真实项目里,单电阻的采样盲区问题会消耗你大量时间,而双电阻方案多一颗采样电阻,省掉的是重构算法、窄脉冲补偿、矢量插入这一大堆补救逻辑。这篇我把双电阻采样从硬件布线、PWM采样时序到代码落地的完整链路拆开讲,都是实际项目里验证过的东西。

1. 为什么我不再死磕单电阻电流重构

1.1 电流采样在FOC里的地位

FOC控制的核心是让电机定子电流矢量始终和转子磁场保持期望的角度关系。要算出准确的直轴电流Id和交轴电流Iq,先得有准确的相电流。三相电流满足基尔霍夫电流定律,i_a + i_b + i_c = 0,所以实际上只要测到任意两相,第三相就能算出来。这也是双电阻方案最底层的依据。

采样信号链通常长这样:采样电阻上的压降先经过运放放大,再送进MCU的ADC,ADC采完数后在中断里完成零漂扣除、标定、Clarke变换和Park变换,最后交给两个PI调节器。任何一环引入误差,最后都会以电流纹波、转矩脉动、甚至电机啸叫的形式暴露出来。你去看任何一个成熟的FOC库,代码里最讲究的部分一定不是SVPWM算法本身,而是电流采样那一刻“采到的值到底靠不靠谱”。

1.2 单电阻重构的“温柔陷阱”

单电阻方案只有一个采样电阻,串在逆变器的母线回路上,硬件成本确实最低。它的原理是:PWM周期内不同电压矢量下,流过母线电阻的电流对应不同的相电流,通过多次采样再拼接出完整的三相电流。听起来很聪明,但工程实现里有一堆隐性成本。

第一个问题是采样盲区。SVPWM的一个扇区里有两个相邻的基本电压矢量,外加零矢量。低调制比时,有效矢量作用时间很短,母线电流中相电流的有效信息存在时间远小于ADC的转换时间,这时候根本采不出可信的电流。高调制比时,零矢量时间又太短,同样出问题。为了绕过盲区,要插入额外矢量、做脉冲移相、限制最小占空比,这些操作每一件都会引入额外噪声、增加开关损耗,而且让代码逻辑凭空复杂一大截。

第二个问题是重构误差累加。单电阻重构出来的电流是“拼”出来的,不同扇区之间、不同PWM周期之间,采样时刻、电流路径都不一样,误差分布也不一致。低速小电流时,采样电阻上的压降本身就只有几十毫伏,再经过重构的折损,信噪比很难看。很多人在低速段抖、啸叫,根子不在PI参数,而是电流反馈本身就在“跳”。

1.3 双电阻采样:多一个小电阻,省掉一大片逻辑

双电阻方案在下桥臂的两相上各串一个采样电阻,当两相下管同时导通时,两个电阻上的压降正好反映这两相的相电流,第三相用基尔霍夫定律算出来。硬件多了一颗电阻和一路运放,但采样点天然固定在PWM中心附近,不需要重构,也不存在扇区插值补盲区的问题。我在实际项目里体会最深的是:删掉单电阻补盲区逻辑之后,电流环的调试时间大幅缩短,而且低速性能稳定得多。

三种方案的取舍用一张表看更直观:

方案硬件成本采样鲁棒性软件复杂度适用场景
单电阻最低低,存在盲区高,需重构与补偿极致成本敏感的小功率家电/玩具
双电阻中等高,采样窗口稳定低大多数中小功率PMSM驱动
三电阻高最高,任意状态可测最低高性能伺服、大功率变频器

双电阻不是所有场合的最优解,但对绝大多数中小功率PMSM驱动来说,它处在“成本可控”和“性能可靠”的交集里。下面重点说硬件和代码怎么落地。

2. 硬件设计:把采样电路一次做对

2.1 采样电阻的位置、阻值与功率怎么定

采样电阻的位置放在逆变器低压侧,也就是每相下桥臂MOSFET的源极和功率地之间。这样电阻两端对地的电压都比较低,运放不至于要处理几百伏的共模电压。这里是整条采样链路最容易做错的地方——很多人把采样电阻放到上桥臂去做高端采样,运放输入端会承受母线电压的快速跳变,对共模抑制比要求非常高,普通运放根本扛不住。

阻值的选择要在信噪比和损耗之间折中。电流越大,电阻可以选得越小,以免发热;但电阻太小,小电流时压降又不够看。以一块额定相电流10A、峰值15A的电机驱动板为例,我常用10mΩ ±1%的合金采样电阻。运放增益按20倍算,满量程对应(3.3V) / (10mΩ × 20) = 16.5A,留了10%左右的裕量。

电阻功率要按真实工况算,不能光看峰值。15A峰值电流下的瞬时功耗是I²R = 2.25W,但正常运行时RMS电流远低于峰值,我按峰值功耗的三分之一左右降额,选3W封装的合金电阻,长期可靠性才够。如果峰值电流只有5A级别,可以换成20mΩ电阻,把信噪比提上去,功耗也只有0.5W。

采样电阻的连接方式很关键,必须用开尔文连接,也就是采样用的两根细走线直接从电阻两个焊盘内侧引出,单独走到运放输入端,绝不能和流过功率电流的粗铜皮共用一段走线。功率电流在铜皮上会产生mV级的压降,一旦这段压降被串联到采样信号里,误差根本无法校准。

2.2 运放选型与RC滤波参数

运放是整个采样链路的核心。我强烈建议不要用通用运放搭差分放大电路,而要选用专门的电流检测放大器,比如TI的INA240、ADI的AD8418这一档。这类放大器内置了针对PWM共模瞬态的抑制电路,增益固定,温漂小,且支持双向电流检测。通用运放在开关节点附近很容易被共模跳变打穿,或者输出出现几十微秒的饱和恢复,那段时间采到的电流全是废数据。

滤波电路的参数要慎重。很多人的第一反应是把RC滤波常数调大,滤得干干净净,但电流信号本身是持续变化的,过大的时间常数会让运放输出跟不上实际电流,表现为大电流阶跃时波形发钝,电流环带宽上不去。我常用22Ω串阻加1nF电容,转折频率约720kHz,配合运放内部自带的滤波,既能滤掉一部分开关毛刺,又不至于把FOC需要的电流信息滤掉太多。这个参数可以按你的开关频率微调,但原则是转折频率必须远高于电流环带宽,同时远低于开关噪声频率。

单电源供电时还有一个细节:相电流是双向的,刹车、倒拖、发电状态下电流会反向。MCU内置ADC只能采0到VREF的电压,所以运放输出需要加一个直流偏置,把零电流点抬到VREF的一半附近。比如3.3V ADC用1.65V偏置,软件里先减去偏置再乘回电流标定系数,就能得到带符号的电流值。有两个办法:一是用电压基准给运放的Vref引脚供1.65V,二是用两个精密电阻分压加一个电压跟随器。前者精度更高,也更好调试。

2.3 PCB布线里最容易翻车的三个点

布线层面有三个坑,我几乎每次帮人调板子都能遇到,提前写在这里,你们做板的时候对照检查。

第一是地弹。下桥MOSFET开关瞬间,巨大的di/dt流过功率地平面,地电位会瞬间上下跳动几十甚至上百毫伏。采样运放的地参考如果直接接在这个区域,采样信号就会被地弹污染。正确做法是功率地走粗铜皮,采样电阻的地引脚单独走一条细线到运放附近的模拟地,最后整个控制部分的模拟地和功率地单点汇聚到母线电容的负端。这样功率回流的噪声不会叠加到采样参考地上。

第二是采样走线被开关节点污染。运放的输入走线必须远离三相桥臂中点VS1、VS2、VS3,那里是整个板子上dv/dt最凶的地方。也不要贴着栅极驱动电阻走线走。如果板子面积紧张绕不开,就在采样走线两侧铺接地铜皮做屏蔽,保证走线下方有完整的参考地平面。

第三是运放输出到ADC引脚的走线过长。这个距离超过2厘米,就很容易耦合进其他噪声。实在绕不开时,可以在靠近MCU的ADC引脚处再加一颗几十皮法的小电容做二次去耦,但不要加大,否则会把信号拉钝。ADC的参考电压和模拟供电建议单独用LC滤波,不要直接和数字电源混在一起。

3. 采样窗口与PWM时序:双电阻采样的物理基础

3.1 中心对齐PWM的天然采样点

双电阻采样能稳定工作的前提,是采样时刻必须落在“两相下桥臂同时导通、且开关瞬态已经结束”的时间窗内。这就要在PWM的时序设计上做文章。

FOC主流通用中心对齐PWM,也就是定时器先向上计数再向下计数,产生三角载波,三相占空比在载波中心处对称。当某一相的比较值比较小时,下管导通时间近半个周期;比较值接近周期值时,下管导通时间短。对于空间矢量调制来说,任意一个开关周期内,在三角载波的顶点或底点附近,三相下管接通状态会出现“两相导通、一相关断”或者“三相导通”的组合,这正是双电阻采样需要的窗口。

很多基础教程只会告诉你“采样点放在PWM中心”,但真正设计时要理解:PWM中心就是定时器计数到达顶点或底点的时刻,此时开关动作刚刚发生或即将发生。如果直接用更新事件触发ADC,采样时刻可能正好落在开关振铃区间。我通常的做法是让ADC触发稍微滞后于顶点时刻,留出几百纳秒到几微秒的窗口,等振铃衰减后再开始转换。

3.2 死区、开关振铃与最小采样窗口

采样窗口的下限由三件事决定:死区时间、开关振铃衰减时间、ADC的采样保持时间。死区是为了防止上下桥臂直通而插入的,死区期间下管不一定完全导通;开关管在开通瞬间,栅极驱动电流会在采样信号上感应出振铃,需要时间衰减;ADC要对电平进行采样保持,也需要固定的转换时间。

以20kHz开关频率、死区1.5μs的典型配置为例,PWM半周期是25μs,死区加振铃衰减大概占2~3μs,采样窗口充裕得很。但当调制比接近极限时,某一相下管导通时间会被压缩到只有几微秒,这时必须检查最小导通时间是否还大于“死区+振铃衰减+ADC转换时间”。如果小于这个值,双电阻采样在那个特定阶段就会退化,需要做最小脉宽限制,或者接受这一小段内的采样误差。这也是双电阻方案在高调制比极端工况下的已知软肋。

3.3 两相采样的时间差与补偿

双电阻要采两相电流,如果MCU只有一个ADC,注入组会按顺序把两个通道逐个转换,两相采样之间存在一个转换周期的时间差。对STM32F103来说,ADC时钟12MHz、采样时间1.5周期加转换12.5周期,单次转换大约1.17μs,两相之间就差出1μs左右。

这个时间差在什么情况下可以忽略?要换算成电角度。假设电机极对数是4,最高转速6000rpm,电频率是400Hz,一个电周期2500μs,1μs只对应0.14度的电角度,对电流环来说完全可以接受。但如果是极对数少、转速极高的电机,比如2极对、80000rpm的高速电机,电频率接近2667Hz,1μs对应接近1度电角度,这时候就必须做插值补偿,或者在硬件上改用双ADC同步采样。STM32F4、G4系列支持双ADC同步注入模式,两个通道同一时刻转换,从根本上消除了这个问题。如果用的芯片不支持双ADC,也可以在软件里按当前电角速度对第二相采样值做角度插值补偿,工程上够用。

4. 代码落地:从ADC触发到电流环的一整条链路

4.1 TIM1与ADC注入组的配合

下面以STM32F103为例讲代码,因为太多人拿这颗芯片入门FOC。F103用高级定时器TIM1输出六路互补PWM,同时用TIM1的触发事件去触发ADC的注入组转换。注入组比规则组更适合做电流采样,因为注入组支持外部触发后立即转换,转换完成中断优先级可以设置得比较高。

TIM1的配置要点是:计数模式设为Center Aligned mode 2,PWM模式1,死区根据MOS管栅极电荷和驱动芯片的传播延迟设置,典型值1~2μs。TRGO选择Update事件,在载波顶点和底点都会产生更新事件,触发ADC。但要注意,更新事件产生的时刻和开关动作的振铃时刻几乎重合,所以要给ADC触发加偏移。

更精确的做法是使用TIM1的第四个比较通道CC4产生延迟触发。把CC4的比较值设成“顶点时刻之后的某个点”,通过事件CC4IF触发ADC注入组,采样点就能精确落在振铃衰减后的稳定窗口里。CC4比较值可以用当前占空比和预定偏移量动态计算,这也是很多商业驱动器常用的方式。CubeMX里配置ADC注入组时,外部触发源选TIM1 Trigger Out或CC4事件,注入通道序列设置成两个采样通道,触发后自动转换,转换完成触发JEOC中断。

4.2 ADC中断里真正该做的事

注入组转换完成中断是整个FOC控制循环的心脏。以20kHz开关频率为例,每50μs进入一次中断,要在这段时间里完成电流读取、坐标变换和双PI运算。伪代码大概是这样的:

void ADC1_2_IRQHandler(void) { if (ADC_GetITStatus(ADC1, ADC_IT_JEOC)) { ADC_ClearITPendingBit(ADC1, ADC_IT_JEOC); int16_t adc_a = ADC_GetInjectedConversionValue(ADC1, ADC_InjectedChannel_1); int16_t adc_b = ADC_GetInjectedConversionValue(ADC1, ADC_InjectedChannel_2); float ia = (adc_a - offset_a) * current_per_lsb; float ib = (adc_b - offset_b) * current_per_lsb; float ic = -(ia + ib); float ialpha = ia; float ibeta = (ia + 2.0f * ib) / 1.7320508f; float id = ialpha * cosf(theta) + ibeta * sinf(theta); float iq = -ialpha * sinf(theta) + ibeta * cosf(theta); float vd = PI_Id(id_ref, id); float vq = PI_Iq(iq_ref, iq); float valpha = vd * cosf(theta) - vq * sinf(theta); float vbeta = vd * sinf(theta) + vq * cosf(theta); // 更新TIM1三个比较寄存器,并做限幅和扇区判断 set_pwm_duty(valpha, vbeta); } }

这里有一个很多人忽视的地方:零漂偏置offset_a、offset_b必须在电机启动前采集,而且要在全部PWM输出关闭的状态下采集多次取平均。否则运放的偏置电压、ADC自身的偏置都会变成电流误差,直接导致Id/Iq里有固定的直流偏置,电流越大电机越热。

4.3 零漂校准与电流方向这两个最容易忽视的环节

零漂校准说起来简单,但有个细节:如果运放用了1.65V偏置,零漂点不是ADC零值,而是偏置对应的ADC值。上电后先关PWM,连续采几百次注入组数据取平均,得到的就是零漂基准。注意每次上电都要校准一次,因为偏置电压随温度、电源电压都会漂,不能一次标定终身使用。

电流方向的一致性比很多人想象的重要。采样电阻在下桥臂,下管导通时电流从电机相线流经下管和采样电阻到负母线,运放测到正压;续流阶段电流方向可能反向。如果你的运放输出做的是“零电流在中间、反向电流低于偏置点”的方案,软件里直接减偏置再乘以标定系数就能得到带符号电流。但如果这里方向约定和Clarke变换、Park变换里的旋转方向约定不一致,Id/Iq会反号,电流环会变成正反馈,一上电就飞车或者剧烈震荡。我在代码里会用堵转测试验证方向:给定正d轴电压,看反馈的Id是否为正,不对就把某个标定系数取反。

4.4 电流环PI参数与限幅

电流环PI参数的整定不是靠“试到不抖”就行的。双电阻采样把电流反馈的质量提上来之后,PI参数可以按工程经验初算:比例系数Kp约等于Lq乘以期望的电流环带宽,积分系数Ki约等于Rs乘以带宽。比如电机Lq为100μH,Rs为10mΩ,带宽目标1kHz,Kp可以取0.628左右。这个初值还需要在实测里微调,但有了起点总比盲试强。

电流环输出要限幅,限幅值要跟SVPWM的线性调制范围对齐。超过线性区之后,电压矢量会进入过调制区,电流环输出饱和,这时再去加大PI只会让积分饱和更严重。建议在代码里做积分抗饱和,当输出达到限幅值时冻结积分器,防止电流环从饱和恢复时出现大的超调。

5. 调试期避坑实录:从毛刺到地弹的真实排查过程

5.1 采样毛刺:从“ADC值跳变”定位到“采样点落在振铃区”

第一次上电测电流波形最常见的现象是:相电流波形大体正确,但某些角度位置出现尖刺,或者电流环在某一转速段突然发出明显的噪声。很多人第一反应是加大滤波,但我的排查链路一般是这样的:

第一步,先把采样触发时刻移开开关动作点。用CC4比较值把ADC触发时间往后推,看毛刺是否消失。如果不消失,再检查RC滤波参数;如果触发点已经足够靠后仍不行,再考虑是不是死区续流改变了电流路径。第二步,用示波器的差分探头同时看运放输入和PWM驱动信号,眼见为实,确认采样点到底落在开关波形的哪个位置。第三步,如果是只在扇区边界出现的毛刺,要检查是不是该相下管导通时间过短,触发了最小脉宽限制逻辑。

有个真实案例:某块板子采样毛刺只在转速1200rpm附近出现,查了几天,最后发现是CC4的触发偏移量是固定值,但更新时刻随调制比变化后,采样点在某些扇区落回振铃区。把CC4触发偏移改成随调制比动态调整后,毛刺彻底消失。

5.2 地弹与共模干扰:波形上叠加的诡异噪声

地弹的表现比毛刺更隐蔽。运放输出波形整体“毛茸茸”的,像蒙了一层噪声,加大滤波电容效果也不明显,因为噪声是叠加在参考地上的。调试方法也很直接:用示波器的两个通道分别量运放输出和功率地电位,做差之后再看余数。如果余数里还有大量高频噪声,基本可以确认是地平面切割不合理或采样地参考点选错。

解决方向有两个:一是物理上把采样信号回路面积缩到最小,采样走线紧挨着地回线走;二是在软件上尽量把采样时刻安排在高dv/dt事件结束之后,避开噪声最强的时段。这两个方向要一起做,不要指望软件能完全扛住硬件布线的账。

5.3 低速斩波噪声与最小脉宽限制的兜底

低速段双电阻方案总体比单电阻稳,但也不是完全省心。低速大电流时,占空比很小,下管导通时间在大部分周期内很长,两相下管同时导通的窗口很宽;但SVPWM里某个相邻矢量作用时间仍然可能变得极短,那一小段窗口里的采样可靠性会下降。我在代码里会做一个兜底:当计算出来的最小采样窗口小于某个阈值时,主动限制该相占空比的极限值,用一点点波形失真换来稳定的采样质量,数值上再配合电流环的抗饱和,实际运行中几乎感觉不到。

如果是无感FOC,低速段还要叠加转子初始位置辨识和高频注入的逻辑,这个时候电流采样噪声会被观测器放大。双电阻方案因为采样质量高,滑模观测器或龙贝格观测器在这种工况下的表现比单电阻好很多。这也是很多人在低速段单电阻调不通、换个采样方案就调通了的内在原因。

5.4 快速确认采样值是否可信的验证方法

最后给一套我每次调试新板都会做的验证流程,按顺序跑一遍就能确认采样链路是否健康。第一步,电机不动,不开PWM,连续采集零漂数据,观察标准差,如果波动超过正负一个LSB很多,先把供电和地线问题解决。第二步,开环给定一个很小的d轴电压让电机轴慢慢锁死,然后用电流钳夹住一根相线,对比钳表读数和ADC解析电流。这一步能一次性验证零漂、标定系数和电流方向三件事。

第三步,让电机带着一个轻负载转起来,通过串口以20kHz上报Id和Iq,正常情况下Id和Iq应该是平滑的直流量,只在负载波动时有小幅变化。如果波形里有明显的固定频率正弦波动,大概率是角度采样和电流采样之间存在相位误差,比如上一节提到的两相采样时间差没有补偿。

6. 几句实在话:双电阻方案的应用边界

写了这么多,还是想泼一点冷水:双电阻采样不是银弹。如果你的产品目标是几个美元还带PMSM驱动的玩具电机,单电阻方案的低成本优势仍然存在,通过注入谐波、动态移相等手段也可以把性能做到能出货的水准,代价是开发周期长、维护成本高。如果你做的是高端伺服或几十千瓦的变频器,三电阻采样甚至隔离式采样才是正路,双电阻在下桥臂的采样方式在极端工况下仍会面临采样窗口不足的问题。

双电阻的甜点区间就是中小功率PMSM驱动:电动工具、风机、水泵、小型机器人关节、滑板车电机控制器。在这个区间里,多花一颗采样电阻的成本,换来的却是采样链路的高可靠性和开发进度的确定性,这笔账划算得很。我自己现在的默认方案就是“双电阻起步”,只有在硬件成本被压得非常紧时才回头评估单电阻。

另外说一个可以继续扩展的方向:双电阻方案验证成熟后,迁移到三电阻只需要在PCB上预留第三个采样电阻和一路运放的位置,代码里改一下采样通道和触发逻辑,电流环和观测器几乎不用动。如果你打算之后做高性能无感FOC,画板的时候建议提前把三电阻的焊盘和运放位置都留好,省得下一版大改。这是在双电阻上踩过坑之后,我最想回头跟自己做的一件事。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询