ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

电流采样电路设计实战:采样电阻选型、差分放大与STM32 ADC/DMA采集全解析

电流采样电路设计实战:采样电阻选型、差分放大与STM32 ADC/DMA采集全解析 做电机驱动、电池管理或者电源项目电流采样都是绕不开的一环。我以前做无刷电机驱动器起初用最简单的方式——低边采样加同相放大调试时总被地弹和共模噪声折腾得怀疑人生。后来换成差分放大方案配合STM32内置ADC做多通道DMA采集整个采样链路才真正稳下来。这篇就把我从硬件选型到软件配置的完整经验整理出来给要在电流采样这条路上少踩坑的朋友做个参考。1. 方案选型为什么是“采样电阻差分放大ADC”1.1 电流采样的几种主流手段做电流采样第一步是选传感器。行业内最常用的三类是采样电阻分流器、霍尔传感器和电流互感器。三者的对比我整理成了一个表方便你做初期选型参考方式精度成本带宽隔离典型场景采样电阻高可达0.1%低高可达MHz无板级电源、电机驱动、电池管理霍尔传感器中1%-5%中高中数十kHz有大电流、需要隔离的场合电流互感器中1%-5%中中仅交流有交流电流检测、电力系统多数嵌入式项目根本用不着隔离采样电阻加运放是性价比最高的路径。采样电阻的优势是线性度和温漂都容易做得好而且体积小、成本低缺点是采样电阻上有功耗电流太大时发热明显而且电阻本身不提供隔离。1.2 高边采样与低边采样采样电阻放的位置直接决定了你的信号调理电路怎么设计。我把两种方式都试过各自的优缺点很清楚低边采样是把采样电阻放在负载和地之间。优点是采样电压以GND为参考用普通的同相放大器就能处理共模电压很低非常方便。缺点是负载没有直接接到GND负载的“地”其实被抬高了I x R这在某些对地参考有严格要求的场合是不允许的。而且地弹噪声会串进你的采样信号里走线不讲究的话测量误差特别明显。高边采样是把采样电阻放在电源正极和负载之间。这种方式保持了负载对地的参考是绝大多数工业应用的“标准姿势”。但代价是采样信号本身处在较高的共模电压上——比如电源是24V采样点电压在23.9V到24V之间浮动你要测的是这0.1V的差分电压同时却要承受24V的共模电压。这时候普通同相放大器就无能为力了必须上差分放大或者专门的电流检测放大器。1.3 采样电阻阻值怎么定采样电阻的阻值选择是个权衡活。从ADC角度看阻值越大、满量程压降越大信噪比就越好。但压降越大意味着损耗越大在低压大电流场合还会导致负载端电压被拉低。我一般按“满量程压降控制在50mV-100mV”这个经验值来选。举个例子如果系统最大电流是10A我选10毫欧的采样电阻满量程压降就是100mV。这个压降在电机驱动里通常可以接受对系统效率的影响大约是0.2%-0.5%基本可以忽略。选阻值的时候还要看功率。10A电流流过10毫欧电阻功耗是P I^2 x R 10^2 x 0.01 1W。这时候必须选2W或以上的电阻否则温升会吃掉精度。我之前吃过这个亏一开始选了个2512封装的精密电阻工作一段时间之后读数漂了2%以上查了半天才发现是电阻自热导致的后来换了功率余量更大的封装才解决。提示采样电阻建议选金属箔或者低温漂的合金电阻康铜、锰铜温漂系数要控制在50ppm/℃以内。普通厚膜电阻温漂动辄200ppm/℃以上温度一变化你的采样精度就全完了。2. 差分放大电路设计精度从这里开始2.1 为什么必须用差分结构高边采样的核心矛盾是信号是共模电压很高的微小差分信号。普通运放的输入端对地只能承受很小的共模电压直接接上去轻则饱和重则烧毁。差分放大器的本质是一个减法器它只放大两个输入端的差值对共模信号只会做一定的抑制不会放大。这个抑制能力叫共模抑制比CMRR单位是dB。CMRR越高说明对共模干扰的抑制能力越强。比如你的24V共模电压里叠加了一个纹波理论上差分结构能把大部分纹波抑制掉只留下微小的差分信号。设计差分放大电路时CMRR主要由两个因素决定运放本身的CMRR指标以及外围四个电阻的匹配精度。很多人只盯着运放的指标忽略了电阻匹配的影响。四个电阻哪怕是1%精度实际CMRR也会被限制在40dB左右远低于运放本身能提供的100dB。想要好的CMRR要么用0.1%精度的电阻要么直接用集成差分放大器或电流检测放大器内部集成了经过激光调校的匹配电阻网络。2.2 单运放差分放大器的设计与误差分析经典的单个运放差分放大电路如下图所示单电源供电增加了一个偏置电压VrefV ----[R1]--------[R3]---- Vout | |-\ | -------- Vout |-/ | | | V- ----[R2]---- | | Vref ----[R4]-------------用文本描述一下两个输入端分别通过电阻接运放的正相和反相输入端反相端通过反馈电阻接输出正相端通过电阻接地或接参考电压构成偏置当R1R2且R3R4时输出公式是 Vout (V - V-) x (R3/R1) Vref这个公式很直观差分增益由R3/R1决定Vref用来叠加一个直流偏置使输出信号能落在ADC的输入范围内。实际设计时我常用这种结构来把差分信号放大到ADC的满量程附近。例如选用10毫欧采样电阻满量程电流10A差分电压就是100mV。如果ADC是3.3V参考电压前级最大允许输入约3V理论上增益做到30倍就够了。但实际设计时我留了20%余量把增益设为25倍左右这样满量程输出是2.5V不会削顶同时留出偏置调整空间。增益的具体实现是选择电阻比值。R3/R1 25常见取值是R11kΩR325kΩ。但要注意R1、R2一般取1kΩ或更大太小了会增加前级负载影响采样电阻上的电压分布太大了运放的输入偏置电流会在电阻上产生额外压降导致误差。误差分析上有一个容易被忽略的点输入偏置电流的影响。假设运放输入偏置电流是10nA在R110kΩ上产生的压降是 10nA x 10kΩ 0.1mV相对100mV的满量程信号已经是0.1%了。如果用高阻值电阻比如100kΩ误差就直接飙到1mV也就是1%。所以做精密电流采样优先选低偏置电流的运放比如FET输入的运放偏置电流在pA级别基本可以忽略。2.3 单电源供电下的偏置电压设计如果系统是单电源供电最常见的3.3V或5V负电流方向的信号就没法直接处理必须抬升一个直流偏置。最稳妥的做法是用基准电压源或者高精度LDO生成一个稳定的Vref通常是电源电压的一半1.65V或2.5V。然后把Vref接到同相输入端的偏置电阻上。我通常用ADC的参考电压——如果ADC的参考电压是3.3V那我把Vref设为1.65V这样双向电流的信号可以在0~3.3V范围内摆动正负方向都有满量程的动态范围。假设置放的零点输出是1.65V正向电流10A时输出2.5V反向电流10A时输出0.8VADC读到的数字就能完整覆盖正反两个方向。这里有个细节Vref的纹波会直接叠加到输出信号上而且不受差分结构的抑制。如果Vref是从DCDC的3.3V直接分压来的DCDC的开关纹波会100%出现在你的采样信号里ADC读数上能看到明显的毛刺。我实测过直接从DCDC分压出来的Vref会导致ADC跳动10-20个LSB。后来加上一级RC滤波、甚至用专门的基准芯片问题才解决。2.4 运放关键参数与选型清单很多刚接触电路设计的同学不知道运放怎么选我这里直接给一个选型对照表参数我的要求说明VOS失调电压100μV失调电压直接影响零点精度100μV对应满量程100mV就是0.1%温漂1μV/℃温度漂移小才能保证在全温范围内稳定输入偏置电流10nA越小越好减小电阻网络上的压降误差GBW增益带宽积1MHz如果采样频率是几十kHzGBW太低会衰减信号CMRR80dB共模抑制能力尤其高边采样时必须关注电源电压兼容3.3V/5V单电源供电输出摆幅要能到轨实际项目中我用过的型号包括SGM8551零漂移、极低失调OPA333TI零漂移、微功耗AD8628亚德诺零漂移INA240集成差分放大器专为电流检测设计内部增益可选共模范围可达-4V到80V做高边采样非常方便。如果你不想自己搭电阻网络直接用INA240这类专用电流检测放大器省心很多。实操心得仪表放大器如INA128、AD620理论上也能做电流采样但成本和体积都比专用电流检测放大器高。我做低成本产品时优先用“运放精密电阻”的组合做高端电机驱动的电流采样时直接上INA240或类似集成方案研发效率高性能还更稳定。3. 输入滤波与PCB布局小细节决定成败3.1 输入RC滤波的参数计算热词里出现了“电流采样电路输入滤波”这个确实是非常多工程师忽略的点。采样电阻上的电压通常只有几十到几百毫伏很容易耦合进来高频噪声比如开关管的开关尖峰、电机PWM的边沿辐射。这些高频噪声如果不做滤波直接进运放放大器会通过运放的整流效应产生直流偏置误差这个现象在示波器上看不到但ADC采集的数据会“莫名其妙”地偏大或偏小。最常用、最有效的滤波方式是运放输入端的差分RC滤波器。在两个输入端之间并联一个电容在在每个输入端与信号源之间串联电阻组成一个低通滤波器。截止频率公式是 f_c 1 / (2π x R x C)这里的R是每个输入端的串联电阻C是差分电容。注意这里的C是接在两个输入端之间的电容所以高频时两个输入端的噪声基本被短接形成低通。以R1kΩ、C1nF为例截止频率约159kHz。选滤波参数时要注意与信号带宽搭配。如果是电机电流采样PWM频率通常在20kHz左右基波和开关纹波的成分不同你关心的实际电流带宽往往只有几kHz到几十kHz。我一般把截止频率设在信号带宽的3-5倍以上确保有用信号不被衰减同时尽量抑制高频干扰。具体例子电机电流信号带宽5kHz滤波器截止频率设计在30kHz左右R1kΩC5.6nF。3.2 采样电阻的开尔文接法采样电阻的引脚和走线本身是有电阻的哪怕只有0.5mΩ在大电流下也会产生不小的压降这部分压降如果混入采样回路就会引入误差。解决办法是开尔文接法也叫四线制接法把采样电阻上的电流路径和电压检测路径分开。具体做法是大电流走线从采样电阻的两端焊盘外侧进出而采样电压的引线则从焊盘内侧单独引出避免大电流在检测回路上产生压降。这是精密电流测量的基本功很多设计人员直接在采样电阻的焊盘上打了两根走线一根走大电流另一根做电压检测效果就很好。大电流进 ----[采样电阻]---- 大电流出 || 采样 ----|-----|---- 采样- 电压检测走线禁止走大电流PCB布线时检测线要尽量短远离大电流路径两个检测线要平行走线形成一个小的差分对减少磁耦合干扰。3.3 布局要避开的那些坑PCB布局决定了电路的最终性能这一点在模拟采集上体现得最彻底。我踩过几个代表性的坑列出来供大家参考第一运放的地线千万不要和功率地直接混在一起。功率地有巨大的电流突变会在PCB铜箔上产生地电位波动。如果运放的GND引脚和功率地接在同一段铜箔上这个波动会直接串入运放等效于在输入端注入了一个共模噪声。正确做法是模拟区域独立铺地单点接地——模拟地通过一个磁珠或0Ω电阻连接到功率地。第二差分输入走线要等长且靠近。差分信号最怕不对称两边的寄生电容、走线长度不一致会把共模噪声部分转换成差模干扰。我通常让两个输入走线并行走保持一样的长度线宽尽量一致。第三反馈电阻要靠近运放放置减小寄生电容对高频稳定性的影响。这个细节主要是为了防止运放自激振荡。特别是增益较大时比如25倍反馈电阻和输入电容会产生额外的相位延迟如果布局不好非常容易振荡。第四电源去耦电容要贴近运放电源引脚。我习惯在运放电源引脚旁放一个0.1μF陶瓷电容再并联一个1μF电容。去耦电容的地孔要直接打到模拟地上不能绕路。注意采样电阻下面尽量要铺地吗不一定。如果采样电阻正下方有铺地大电流的高频分量会通过寄生电容耦合到地平面可能干扰周围的模拟信号。我通常会在采样电阻的下方留空铜皮不铺地以减少寄生耦合。4. 软件侧STM32CubeMX配置ADC多通道DMA采集4.1 CubeMX中如何配置ADC硬件电路完成后软件侧的第一步是把ADC配好尤其是多通道采集配置。我以STM32系列最常用的ADC为例配合CubeMX工具详细走一遍配置过程。在Pinout Configuration页面里先选ADC1打开你要用到的通道比如IN0、IN1、IN2每个通道都作为单端输入。需要特别注意的是如果电路板上已经有了运放的偏置电压输出这个引脚对应的通道就不能同时被配置为别的功能。接着在ADC1的Configuration里按以下参数设置Clock PrescalerADC时钟分频同步时钟分频为4ADC时钟约4.5MHz取决于系统时钟Resolution分辨率12位Scan Conversion Mode扫描转换模式EnableContinuous Conversion Mode连续转换模式Enable配合DMA用Discontinuous Conversion Mode间断转换模式DisableDMA Continuous RequestsEnableEnd of Conversion Selection设置成Single即每个通道转换完就发出一次EOC事件然后在DMA Settings里添加ADC1的DMA请求模式设为Circular循环模式数据宽度都选Half Word半字对应12位采样的数据宽度是16位。Parameter Settings页面里还需要设置每个通道的采样时间。采样时间决定了ADC内部采样电容的充电时间。如果信号源阻抗较高采样时间太短会导致充电不充分采集结果偏低。我一般把采样周期设置为最大例如480.5个时钟周期这样虽然单通道转换速度慢一点但精度明显更稳。4.2 DMA模式下的数据搬运逻辑为什么要用DMA因为CPU直接读ADC数据寄存器会占用大量CPU时间尤其多通道、连续采集时每一个通道转换完成都要触发中断CPU被频繁打断。DMA的职责是自动把ADC的数据寄存器内容搬到SRAMCPU只需要等DMA完成中断即可。配置DMA时有一个关键点DMA的数据宽度要跟ADC的数据寄存器匹配。STM32的ADC数据寄存器是16位所以DMA的Peripheral数据宽度和Memory数据宽度都设为Half Word。如果你把宽度配成Byte数据会错位读出来的值完全不对这是新手最容易犯的错误。多通道扫描模式下ADC按通道编号顺序转换DMA按同样的顺序把数据依次写入数组。比如开启IN0、IN1、IN2DMA接收数组就是adc_buf[0]对应IN0adc_buf[1]对应IN1adc_buf[2]对应IN2。如果通过半传输中断和传输完成中断分别处理可以实现双缓冲一边处理数据一边继续采样效率更高。4.3 典型的DMA采集代码示例CubeMX生成的初始化代码骨架是固定的这里给出核心的启动和数据处理代码。// ADC和DMA初始化由CubeMX生成这里只列出关键调用 #define ADC_BUF_SIZE 8 uint16_t adc_buf[ADC_BUF_SIZE]; // 启动ADC的DMA采集 HAL_ADC_Start_DMA(hadc1, (uint32_t *)adc_buf, ADC_BUF_SIZE); // DMA半传输完成回调可以在这里处理前半段数据双缓冲思路 void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef *hadc) { if (hadc-Instance ADC1) { process_adc_data(adc_buf, ADC_BUF_SIZE / 2); } } // DMA传输完成回调处理后一半数据 void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc) { if (hadc-Instance ADC1) { process_adc_data(adc_buf ADC_BUF_SIZE / 2, ADC_BUF_SIZE / 2); } }process_adc_data是在回调里对每个通道的多个样本做平均值滤波。多通道扫描模式下采样数组里不同通道的数据是交叉排列的比如IN0、IN1、IN2循环所以处理时要按通道索引递增的规律提取数据不能直接整块平均。void process_adc_data(uint16_t *buf, uint16_t len) { static uint32_t sum[3] {0, 0, 0}; static uint16_t cnt[3] {0, 0, 0}; uint16_t i; for (i 0; i len; i) { uint8_t channel i % 3; // 三个通道IN0-0, IN1-1, IN2-2 sum[channel] buf[i]; cnt[channel]; } // 当计数满足要求时计算平均值并更新到全局变量 if (cnt[0] 16) { adc_avg[0] sum[0] / cnt[0]; adc_avg[1] sum[1] / cnt[1]; adc_avg[2] sum[2] / cnt[2]; sum[0] sum[1] sum[2] 0; cnt[0] cnt[1] cnt[2] 0; } }软件滤波我这里用了最直接的均值滤波16个点求平均。如果你要更高的响应速度可以考虑FIR或滑动平均滤波但均值滤波对随机噪声的抑制效果已经能满足大多数电机驱动的需求了。实操心得DMA的平均值滤波虽然能消除随机噪声但如果噪声是系统性的比如运放的偏置误差或者参考电压偏差滤波是滤不掉的必须通过硬件和标定来解决。别指望软件滤波“妙手回春”它只能解决噪声问题不能解决精度问题。5. 标定流程与实测数据5.1 零点校准不能只靠“调零电阻”高精度电流采样系统需要做零点校准。差分放大器的失调电压、ADC的偏移误差、Vref的误差叠加在一起输入端电流为0时ADC读数大概率不是理论值比如1.65V对应的2048需要标定修正。零点校准的做法是保证采样电流为0在代码里采集ADC原始值记为zero_offset。之后每次读取都减去这个偏移量。我一般不在硬件上调零电阻因为生产一致性差而且温度变化后硬件零点会漂移。更好的做法是软件校准在生产测试阶段每个板子测一次零点存到Flash里运行时自动补偿。温度变化导致的零漂主要由运放VOS温漂决定选零漂移运放后这个偏差可以控制在很小范围内。5.2 增益校准用一个精密恒流源零点校准完成后还需要校准增益。增益误差来源包括采样电阻的精度误差、运放电阻网络的比值误差即使1%精度也有1%的增益误差以及ADC参考电压的偏差。增益校准的方法是用一个精密恒流源精度优于0.1%给系统通入已知电流采集ADC读数计算实际增益。具体公式是 实际增益 (adc_reading - zero_offset) x Vref / (4096 x R_sense x I_known)然后把这个实际增益值存到校准参数里运行时通过换算公式从ADC读数反推电流 I (adc_reading - zero_offset) x Vref / (4096 x 实际增益 x R_sense)这个校准最好在温箱里做三个温度点的校准拟合温漂曲线。不过大多数消费级产品只做室温单点校准就够了。工业产品通常要求全温范围需要额外的温度补偿。5.3 实测数据示例我用一个5V供电的系统做了一组实测数据采样电阻10mΩ运放增益25倍Vref2.5VADC参考电压3.3V12位分辨率。用精密电子负载拉载不同电流记录ADC读数换算后的电流值对比结果如下预设电流AADC原始值均值换算电流A误差0.00031020.0020.002A1.00028740.993-0.007A2.00026451.984-0.016A3.00024152.974-0.026A4.00021853.966-0.034A5.00019554.957-0.043A可以看到满量程5A的误差约0.86%在校准之后可以控制在0.3%以内。这个精度水平在电机控制、电池管理里已经完全够用。需要说明的是上面的数据是未经校准的原始换算结果已经比很多初版设计好不少主要归功于低温漂采样电阻和零漂移运放的使用。如果采用1%普通电阻和通用运放误差会明显增加甚至达到3%-5%。提示换算电流的ADC原始值是16次均值滤波后的结果不是单次采集值。单次采集跳动通常在±3LSB左右均值后可以稳定到±1LSB以内。6. 常见问题与排查技巧实录6.1 运放自激振荡现象输出波形上有高频正玄波或杂波频率通常在几百kHz到几MHzADC读数明显异常。排查思路先用示波器看运放输出确认是否有不需要的高频振荡。振荡原因一般是增益较大时反馈回路相位裕度不足或者PCB布局引入过多寄生电容。解决办法增大反馈电阻与反相输入端之间的阻值但要注意不要太大会引入噪声增益增加。在反馈电阻上并联一个小电容几pF到几十pF降低高频增益。这是最有效的手段但电容太大会影响信号带宽需要折中。缩小反馈电阻到运放的距离减少寄生电感。如果使用INA240这类集成电流检测放大器内部已经做好稳定性设计外部只要布好线就行。6.2 ADC读数跳变严重现象同一个恒定电流下ADC读数波动超过10个LSB而且带有明显的周期或毛刺。排查思路先判断噪声来源是外部还是内部。用示波器测量运放输出端看波形是否干净如果输出端就脏问题在硬件前端如果输出干净但ADC读数跳问题在ADC配置或参考电压。常见原因和解决参考电压来自DCDC纹波太大。换用专门的基准电压源如REF3030、TL431或加LC滤波。采样时间太短。把采样周期调到最大我一般直接选最长的采样时间。电源去耦不良。检查运放和MCU电源引脚的电容是否贴近引脚3mm。采样线走线过长且未做保护。在输入走线周围包地加上RC滤波。6.3 DMA数据错位现象多通道采集时各通道数据相互“串位”明明没加电流通道1却显示大电流过一会又恢复正常。排查思路多通道扫描模式下DMA按通道顺序搬运数据如果通道初始化顺序和实际硬件通道顺序不一致就会出现错位。另一个常见原因是DMA数据宽度不对比如ADC是16位但你设成了8位数据就会错乱。解决办法在CubeMX中严格按照硬件连接的通道顺序配置并在第一次上电时读取DMA回调的第一个缓冲区数据打印对比确认每个通道的数据都对应正确的引脚。6.4 温漂导致零点漂移现象设备冷启动时零点正常工作半小时后零点漂移了几个毫安甚至几十毫安。排查思路热源主要有两个一是采样电阻自热二是运放附近的其他发热器件比如功率MOS管。如果是采样电阻自热说明电阻功率余量不足需要换更大功率封装如果是外部热源就要从布局上隔离让运放远离功率器件。我做过一个版本为了结构紧凑把运放放在功率管边上不到5mm的位置结果温漂非常明显后来重新布局加入热隔离才解决。这种问题靠设计阶段是很难完全避免的早期打板时一定要留出热测试时间。6.5 采集值偏低现象实际电流是1AADC换算出来的电流只有0.8A而且随着电流增大误差比例基本恒定。排查思路这种系统性偏差通常是增益偏小。可能原因运放增益电阻精度不高实际增益低于设计值。ADC参考电压偏高例如手册标称3.3V实际3.4V。采样电阻实际阻值偏小。解决办法用高精度万用表实测采样电阻和参考电压代入换算公式修正。如果要批量生产直接通过增益校准解决不需要逐板换电阻。写在最后电流采样电路的设计难点在于“精度”这个目标贯穿了从选型、电路、布局到软件的全链路。任何一个环节马虎最终呈现出来的数据都可能差之千里。回头看我自己做过的几版电流采样设计最大的体会是早期的原理图问题往往不是原理图本身而是对误差来源的认知不够。采样电阻的温漂、运放的失调和偏置电流、电阻网络的匹配、PCB地线的走向、参考电压的纹波每一项单独看都是小问题但叠加起来就可能让你的系统完全不可用。如果你正准备做电流采样我的建议是第一轮打板就把差分放大、输入滤波、开尔文接法、独立模拟地这些基础做扎实不要等到实测出问题了再回头改板。软件侧把DMA多通道采集和均值滤波配好再准备好零点校准和增益校准的流程。整套链路走通之后你就会发现所谓“精确的电流采集”其实就是一个把每个环节的误差都控制住的过程。如果你实际调试中遇到这里没覆盖的问题欢迎带着现象和数据来找我聊我会继续补充这个主题的实战经验。
返回列表