STM32G4片上运放如何解决无刷电机FOC电流采样难题
2026/9/24 13:12:14 网站建设 项目流程

做无刷电机FOC控制,最让人头疼的往往不是电机转不起来,而是电流采样这一环反复出问题。以前做低压驱动板,我一直用外部运放搭电流检测,增益电阻要一个个配对,差分走线怕被PWM干扰,每个采样通道还要单独调偏置。第一版板子调了将近两周,波形还是带着开关毛刺。后来把方案换成STM32G4,芯片里直接集成了3个运放,运放输出还能在芯片内部直接送进ADC,整个电流采样链路才真正干净下来。这篇内容就围绕STM32G4的OPAMP和无刷电机电流采样电路展开,适合正在做直流无刷驱动、想用FOC但被采样精度困扰的朋友,也适合那些准备从STM32F103老方案切换到G4系列、想弄清楚片上运放到底怎么用的人。

1. 电流采样方案先选型:单电阻、双电阻、三电阻的账要算清楚

1.1 为什么无刷电机控制非采相电流不可

无刷电机的FOC控制,核心就是要把三相电流解算到旋转坐标系下,形成电流环、速度环、位置环的级联结构。你哪怕只做方波六步换向,也需要知道当前相的电流大小来做限流保护,否则MOS管说烧就烧。堵转、母线短路、上管直通,这些故障的电流上升速度都在微秒级,靠软件里的延时去扛根本不现实。

而做FOC时,电流环的采样质量直接决定力矩波动和噪声。很多朋友第一次跑FOC,发现电机低速时有哒哒声,八成不是算法问题,而是电流波形上有毛刺和零点漂移,电流环在跟着错误的反馈值做调节。正因为如此,采样电路不是“放个电阻随便量一下”,它需要满足带宽、精度、抗干扰三方面的要求。

这里要纠正一个常见误区:很多人以为只关心相电流的“有效值”,事实恰恰相反,FOC关心的是瞬时电流波形。你要在每一个PWM周期里捕捉电流值,所以采样电路必须真实还原电流在每个开关周期的变化,不能把它当成简单的直流信号处理。

1.2 单电阻、双电阻、三电阻三条路线的取舍

电流采样拓扑直接决定你需要几个运放、几个ADC通道,以及PWM时序怎么配合。下面是三套方案的实际对比:

方案分流电阻数量需要运放通道第三相电流获取方式优点缺点
单电阻1个1路重构成本低、硬件极简单低调制区采样窗口缺失,需要插入无效开关矢量
双电阻2个2路KCL推导硬件成本中等,软件调校适中某一相电流很小或接近零时误差放大
三电阻3个3路直接测量精度最高,每相独立采样硬件复杂,需要3路运放和3个ADC通道

单电阻采样在低成本的电动工具、小功率BLDC里非常常见,因为成本压力大。但它的麻烦在于:当PWM占空比接近边界时,低侧MOS导通时间太短,ADC根本没有足够的采样窗口。解决这个问题的标准做法是单电阻重构算法,在PWM周期里插入额外的零矢量,这会改变输出线电压,属于拿算法复杂度和谐波换成本。

双电阻方案是很多工业伺服驱动里的折中方案,因为三相电流之和为零,知道了任意两相就能推第三相。但它有个隐藏问题:当某一相电流过零交叉时,那一路采样结果的信噪比很低,用这一点数据去推算第三相,误差会明显放大。所以双电阻的软件里通常要判断哪一路在零附近,然后动态切换推算关系。

三电阻方案最直接,每相分流电阻单独采样。STM32G4的片上OPAMP数量正好对应这个需求——一片芯片搞定三路电流采样,不需要在外面再接三四个运放。这也是我在这篇文章里重点展开的方案。

1.3 采样窗口的时序分析:采样点为什么要放在PWM中心

低端三电阻采样,母线电流通过电机绕组、再经过低侧MOS管流到分流电阻再到地。采样发生的瞬间,必须在低侧MOS接通、绕组电流完全流过采样电阻的时候。

但MOS管开通和关断不是理想的,栅极驱动有上升沿和下降沿,二极管反向恢复还会产生振荡尖峰。死区时间内,如果直接采样,读到的不是电流值,而是这个开关过程的瞬态电压噪声。正确的时间窗口是在PWM周期中间、低侧MOS已经稳定导通、续流二极管已经完全截止的时候。

标准做法是把ADC采样触发信号对齐到PWM定时器的周期中断,也就是载波的峰值或谷值位置。这样采样点就落在低侧导通区间的正中央,既躲开了开关振铃,又留出了电流建立时间。如果你的MCU没有这个同步机制,做FOC会非常痛苦,因为你得用软件去猜测当前PWM状态,采样触发点始终漂移。

STM32G4的思路正好是为这个场景优化的:片上OPAMP输入接采样电阻,输出直接送ADC,ADC触发源又能被TIM1、TIM8或HRTIM的TRGO信号精确控制。采样时机、模拟链路、数字转换三件事在硬件层面就串起来了,这也是我转头用G4的最直接原因。

2. 用内部运放替代外部运放:省下的不止是几个元器件

2.1 外部运放方案的隐性代价

先看看传统的外部运放方案到底贵在哪。除了运放芯片本身的BOM成本,你还得考虑:增益电阻需要高精度和低温漂,0.1%精度电阻比普通电阻贵不少;差分走线要远离功率地;运放的电源去耦不能省;如果你需要双极性采样,还要再加一个参考电压芯片或者电阻分压缓冲电路。

这些还不算最要命的,最要命的是运放带宽和压摆率不匹配。有些朋友选了通用运放,GBW只有几十kHz,用来放大几十kHz的PWM信号,出来的波形已经严重畸变。还有些用了宽带运放,但配套的反馈电阻选得太大,反馈节点电容让环路提前衰减,实际带宽根本达不到数据手册标称值。

我在LTspice里做过一个简单仿真,同样的电流信号,用GBW为10MHz和100MHz的两种运放分别放大,输出波形在上升沿的差异肉眼可见。这就说明外部运放方案不是“随便选个型号就行”,你需要为电机电流场景做带宽、压摆率、噪声、失调电压的综合评估。每一个额外器件的引入,都意味着一个可能出故障的环节。

2.2 STM32G4内部OPAMP的核心价值

STM32G4内部集成了3个(部分型号有4个)运放,支持独立模式和PGA模式。PGA模式下,内部电阻网络已经把增益设定好了,你不需要在外面配电阻,省掉了增益精度和温漂两个大坑。

另一个关键点是内部连接。G4的OPAMP输出能直接在芯片内部路由到ADC输入通道,中间不需要经过引脚、走线和外部抗混叠电阻。PCB走线引起的寄生电容和耦合噪声,在这一步直接消失。对于高频开关电路来说,这个优势非常大。

G4的OPAMP还支持启动校准。通过内部DAC和比较器,芯片可以测量并修调每个运放的输入失调电压,校准结果存在寄存器里。这个功能对电流采样太关键了,因为低侧分流电阻的电压往往只有几毫伏到几十毫伏,运放自身哪怕几毫伏的失调都会造成零点漂移。

2.3 内部运放的局限性:别拿螺丝刀当镊子用

内部运放不是万能的。它最大的限制是增益选项有限,PGA模式通常只能选跟随器、2、4、8、16、32倍这几档,不能像外部运放那样用电阻任意设定1.5倍、2.7倍。如果你需要的放大倍数刚好在中间,就得重新选分流电阻阻值,把整个设计一起调整。

第二个限制是通道数量固定。G4最多也就3到4个运放,如果项目里既要三路电流采样,又要一路母线电压检测,那我还得额外想办法,或者把其中一路电流改成双电阻方案来释放运放通道。

第三个限制是输出摆幅。虽然号称轨对轨,但靠近电源轨和地轨的地方精度还是会下降。如果分流电阻选得过大,或者增益设置过高,输出电压可能顶到饱和区附近,ADC读数在顶端变得非线性。所以设计时最好让额定工作点落在输出范围的20%到80%区间内。

看清这些限制,才能在方案设计一开始就做对。用内部运放不是为了省那么几颗芯片,而是要让模拟链路尽可能短、可预测、少调试。

3. 看懂G4内部OPAMP的工作方式:PGA模式、输入连接和输出路由

3.1 PGA模式到底是怎么一回事

PGA模式相当于芯片内部把运放接成了一个固定增益的同相放大器。G4的内部电阻网络是有实际制造精度的,它比外部贴片电阻的匹配性更好,因为同样的工艺、同样的温度漂移方向,误差会被抵消。

要注意的是,PGA模式下运放的同相输入通常接到外部引脚,你需要把分流电阻的电压信号引到这个引脚;反相输入和反馈网络在芯片内部已经连好了。这就带来一个设计习惯的转变:你不需要再考虑反馈电阻怎么接,只需要关心输入信号的地参考点和走线防护。

我刚开始用G4时踩过一个坑:以为PGA模式下所有引脚都用上了,其实有些型号的OPAMP有内部输入矩阵,可以灵活选择同相输入来自引脚还是内部DAC。用CubeMX配置时,选中了多个输入源,代码生成后发现运放输出完全不对。这个问题的根源在于我把输入源的选择当成可以随便切换的开关,其实G4的OPAMP输入多路复用需要配寄存器,而且某些组合在特定型号上是不支持的。

3.2 运放输出如何路由到ADC

G4的OPAMP输出有两条路径:一条是外部引脚,可以接到示波器或者外部电路;另一条是内部连线,直接送到ADC的某个通道。设计电流采样时,优先用内部路径。

为什么?因为外部的任何一段走线,都是一个天线。三相逆变器和电机线缆本身就是强干扰源,几厘米长的采样线就会拾取开关噪声。如果让运放输出引到引脚,再绕一圈回到ADC引脚,等于把好不容易净化过的信号又暴露在污染环境里。走内部路径就等于跳过这部分。

但内部路径不是“全自动”的,你要在CubeMX的ADC配置里选择正确的通道编号,而且不同OPAMP所对应的ADC通道不同,得结合具体型号的数据手册来确认。G431和G474的映射就有差异,换型号时必须重新查。

3.3 校准机制:上电后第一步就该做的事情

G4的每个OPAMP都带校准逻辑。校准过程会利用内部比较器和DAC去测量当前失调,然后生成一组修调值写入寄存器。这相当于给每个运放做一次出厂测试后的现场自校准。

校准有几点要注意。第一,校准需要在OPAMP还没有真正工作在线性放大状态时执行,所以要放在启动序列的最前面。第二,每个运放都要分别校准,不能只校准一个就当全部完成。第三,校准完成后如果需要重新配置增益档位,建议再校准一次,因为失调补偿可能和增益设置有关。

我在代码里一般这样写:

HAL_OPAMP_CalibrationStart(&hopamp1); HAL_OPAMP_CalibrationEnd(&hopamp1); HAL_OPAMP_Start(&hopamp1);

每次上电后都执行,不要跳过。有些优化编译选项会把这段代码优化掉,如果你发现运放输出跟预期差了一个固定偏移,去反汇编里看看到底有没有调用校准。

4. 手把手配置STM32G4:从CubeMX到初始化代码

4.1 CubeMX里的关键配置项

打开STM32CubeMX,选择G4系列型号,先打开OPAMP1、OPAMP2、OPAMP3。每个OPAMP的mode选择PGA模式,这时增益选项会变成2、4、8、16、32这些离散值。以三电阻采样为例,分流电阻用10mΩ,额定相电流20A,那分流电压就是200mV。想让ADC在满量程附近用好大部分量程,可以把增益设成8倍,输出就是1.6V。如果电机峰值电流到40A,输出也才3.2V,贴近3.3V参考但还有余量,这个方案很稳。

输入引脚的选择也要注意。OPAMP的同相输入引脚一般都有好位置,比如PA0、PA1、PA2附近,但为了避免和主功能冲突,我通常把三相采样引脚分配到ADC和OPAMP共用的一组IO上,比如PA0、PA1、PA2配合ADC1的通道IN1、IN2、IN3,这样引脚安排最紧凑。

ADC部分,把采样时间设置得尽量长一些。G4的ADC采样时间可选项很多,从1.5周期到810.5周期都有。内部OPAMP输出驱动的内部走线肯定比外部走线容性小,但为了稳定,我把采样时间设为45周期以上,转换时间多几微秒,对整个FOC的控制周期影响不大。

4.2 初始化代码的启动顺序

CubeMX生成的代码默认已经调用了MX_OPAMP1_Init()MX_OPAMP2_Init()MX_OPAMP3_Init(),但这些只是配置寄存器,并没有真正把运放启动起来。你必须在主循环初始化阶段显式调用校准和启动函数。

推荐的顺序是:

MX_GPIO_Init(); MX_OPAMP1_Init(); MX_OPAMP2_Init(); MX_OPAMP3_Init(); MX_ADC1_Init(); MX_TIM1_Init(); HAL_OPAMP_CalibrationStart(&hopamp1); HAL_OPAMP_CalibrationEnd(&hopamp1); HAL_OPAMP_Start(&hopamp1); HAL_OPAMP_CalibrationStart(&hopamp2); HAL_OPAMP_CalibrationEnd(&hopamp2); HAL_OPAMP_Start(&hopamp2); HAL_OPAMP_CalibrationStart(&hopamp3); HAL_OPAMP_CalibrationEnd(&hopamp3); HAL_OPAMP_Start(&hopamp3); HAL_ADCEx_Calibration_Start(&hadc1);

这里有个容易被忽略的细节:OPAMP的校准要在ADC校准之前还是之后?我的习惯是OPAMP先启动,ADC再校准。因为ADC校准是校准ADC本身的失调,OPAMP输出必须稳定在一个可复现的状态,ADC校准算法才不会被外部源的随机波动干扰。

4.3 PWM触发ADC的时序配置

FOC电流采样要求采样点对齐到PWM周期中间。我用TIM1作为PWM发生器,把TRGO事件配置成Update事件,或者用OCxREF的触发源送到ADC的注入组转换。注入组转换触发后,会自动把三路ADC通道依次转换完,不需要CPU在中断里逐个读取。

CubeMX中的配置方法是:ADC1的injected conversion组选择Trigger为Timer 1 Trigger Out,并且在TIM1的Trigger Output (TRGO)那里选择Update Event。这样每一个PWM周期都会在定时器更新时触发一次注入转换。

注意PWM的模式。如果使用边沿对齐模式,更新事件在计数值到达周期值的时刻,那其实就是PWM周期的中心点。如果使用中心对齐模式,更新事件在计数到0和周期值的时刻都有,反而是底部和顶部都在过零处,需要再通过重复计数器或触发两路来筛选其中一个。实践里很多人用边沿对齐模式配合更新事件触发,这样触发点正好是PWM周期中间。

5. 输入滤波与硬件布局:这里最容易翻车,却极少有人细讲

5.1 RC滤波器参数到底怎么定

分流电阻到OPAMP输入之间,一般要加一个RC低通滤波器。它不是为了滤掉所有高频分量,而是为了滤掉远高于PWM频率的开关毛刺。如果截止频率设得太低,会把电流变化细节削掉,FOC算出来力矩滞后。设得太高,开关振铃又滤不干净。

我常用的一组合适参数是:串联电阻100Ω,并联电容1nF到4.7nF,截止频率在30kHz到200kHz之间。下面是一组简单计算:

R = 100Ω、C = 4.7nF 时,f_c = 1 / (2πRC) = 1 / (2π × 100 × 4.7 × 10⁻⁹) ≈ 338kHz。这个值远高于PWM频率20kHz,又远低于开关振铃的十几MHz,对于电流环带宽几千赫兹来说完全足够。

但这里还有个陷阱:滤波电容对OPAMP输入是一种容性负载,尤其在同相输入模式下,RC网络带来的相移可能让OPAMP环路不稳定。建议用LTspice搭一个小仿真,输入一个方波,看输出有没有振铃。如果振铃明显,就把R稍微加大,或者把C换小,直到示波器上波形干净。

5.2 采样保持时间与滤波电容的相互制约

ADC采样保持电路本质上也是一个RC充电过程。如果外部滤波电容很大,比如10nF以上,ADC的采样开关打开后,不是立刻就能把电压采准,而是需要一定充电时间。如果采样时间设置太短,读到的电压比实际值偏低,而且这个误差随PWM占空比变化,极难在软件里补偿。

所以在定滤波电容时,不要单看截止频率,还要看ADC采样时间。另一个经验是,如果滤波电容大于几个nF,就要把ADC采样周期尽量设到最大值,比如G4里常见的640.5周期或者810.5周期。换算下来在72MHz ADC时钟下大概是8到11微秒,通常够用。

5.3 PCB布局:分流电阻的开尔文接法和大电流路径

分流电阻采样最怕的不是元件参数,而是PCB走线把功率电流串进来了。分流电阻的两个焊盘,一边走母线大电流,一边输出电压反馈,如果用小信号走线和功率走线共用一段铜箔,铜箔电阻就会叠加到采样信号上。

正确做法是开尔文接法,也就是四线制:功率电流从分流电阻的两个大焊盘流过,电压检测线从电阻的内侧端点单独引出,汇合到运放的差分输入。检测线上几乎不流过功率电流,因此不会引入额外压降。

大电流路径和小信号采样线还要注意走线方向。采样线最好从分流电阻引出之后直接走一条短线到OPAMP引脚,中途不要跨过MOS管栅极驱动走线,也不要和大电流环路平行。如果是双层板,下面一层铺完整地平面,采样走线走在顶层,被地平面保护住。

6. 实测与校准:从波形到数值的真实踩坑记录

6.1 上电后看到的第一个波形

我第一版G4驱动板焊接完成后,用示波器接在OPAMP输出引脚上试测,看到的是带着明显毛刺的方波状信号,而不是平滑的正弦包络。这个现象解释起来不复杂:每个PWM周期里,运放输出都在随开关状态跳变。你看到的“毛刺”主要来自死区时间里的体二极管续流和栅极振铃。

把示波器的触发源改成TIM1的PWM信号,再把时基放大到微秒级,能清楚看到在PWM开通瞬间有一个窄的尖峰,持续几百纳秒。这就是为什么采样点必须避开这个区域。让ADC的触发时间设置到PWM周期的中心位置,毛刺不再出现在采样窗口内,电流波形才真正接近理想正弦。

还有一个很隐蔽的问题:三相采样通道之间的相位差。如果三个ADC通道在注入组里依次转换,转换本身需要时间,通道1和通道3之间可能差了十几微秒。在电机高速运转时,这十几微秒对应的电流角度差已经不小,会让电流环解算结果出现纹波。要解决这个问题,PWM触发ADC的同时,可以通过G4的多ADC同步模式来并行转换,或者把电流采样点放在三个通道都最接近同一个时间点的地方。

6.2 偏置问题的两种修法:软件减法只是挡箭牌

如果在零电流状态下,运放输出不是预期的0V,而是几十毫伏的误差,那很可能是运放失调。G4内部校准时已经处理掉一部分,但温度变化、电源电压波动、增益档不同都会让失调再漂出来。

软件校正很简单:在电机启动之前,让三相PWM全部输出低电平,记录三路ADC的读数,作为零电流偏置存起来。之后每次读取相电流,先减去这个偏置。这是几乎所有FOC库都做的最基本操作。

但仅仅做软件偏置扣除,还掩盖了硬件层面的问题。如果偏置随温度变化很大,可以检查OPAMP的电源是否纹波过大。G4的OPAMP电源来自模拟电源引脚VDDA,如果这个引脚的退耦电容太小,或者在电源纹波大的情况下,运放输出电压会产生随纹波抖动的偏置。我的做法是在VDDA引脚就近放一个1µF陶瓷电容加一个100nF高频电容,并且在设计中尽量把VDDA和VREF+分开,避免ADC参考电压被运放电源污染。

6.3 几个能让你少加班的经验

第一,不要把OPAMP输出引脚空着不用。我见过有人只在内部连了ADC,外部pin悬空,结果因为管脚浮空给内部电路引入电容耦合噪声。最好在软件初始化时把OPAMP的外部输出引脚配置为模拟模式,并保持不动。

第二,分流电阻选型时,TCR温度系数比初始精度更重要。电流采样电阻长期工作是会发热的,普通厚膜电阻的阻值随温度明显漂移,这会直接变成电流测量误差。选功率足够的分流电阻,比如5mΩ/2W封装,比选1%精度但扛不住温度的型号可靠得多。

第三,ADC转换结果里的偶发跳变,别急着改滤波参数,先检查看门狗和调试器。我曾经遇到ADC值每隔几百毫秒跳一次,排查了整整三天,最后发现是调试器在后台访问了外设寄存器,把ADC触发源干扰了。断开调试器,波形立刻恢复正常。

第四,如果你的电机在PWM占空比很低时出现电流采样缺失,不要只怀疑硬件。低占空比意味着低侧MOS导通时间很短,ADC来不及完成注入转换。这时要么改用单电阻重构算法,要么把开关频率降低,或者用G4更灵活的HRTIM来做更细致的时间切片。强迫自己为“不超过20%的低占空比区域”强行采样,往往是设计阶段就埋下的雷。

最后一点,也是我每次做新板子都会保留的习惯:在分流电阻和OPAMP之间预留0Ω电阻位。如果实际测试发现RC滤波特性不合适,可以很方便地换不同阻值,而不用重新打板。这个成本几乎为零,但能让你在调试阶段省出一整周的时间。

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

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

立即咨询