ARTICLE DETAIL

资讯详情

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

INA226微安级电流测量实战:从硬件选型到零点校准

INA226微安级电流测量实战:从硬件选型到零点校准 简介INA226测量μA级电流驱动程序是一份面向嵌入式开发者的I²C驱动源码重点解决微安级电流与电压采集难题适用于低功耗设备、电池管理及电源监控等场景。压缩包内共2个文件包含1个C源文件与1个头文件提供寄存器配置、量程切换及测量数据读取等核心接口方便直接移植到STM32、Arduino等常见平台。相较仅看手册该驱动可大幅缩短开发调试时间并支持动态配置采样参数以适配不同负载。目前已有9792人学习下载资源包仅2KB结构精炼适合需要快速集成INA226的软硬件工程师代码中融合了芯片内部高精度测量、自动功率计算等特性的调用方法帮助用户理解实际工程中的驱动实现思路。 上次调试一块低功耗无线传感器主板我把INA226接在电源入口想顺便把三档功耗全部量出来。写驱动、读寄存器都正常但看到电流寄存器里那个“-270µA”时我整个人是懵的负载明明只吃了8µA表头也不可能倒灌。后来把示波器换成万用表、又把分流电阻来回换了几次才意识到问题不在I2C时序也不在寄存器配置而在从分流电阻到INA226引脚之间那几十平方毫米的铜箔上。这篇文章就把我用INA226做µA级电流测量的完整思路写出来包括硬件选型、PCB布局、驱动代码和零点校准适合做电池供电设备、传感器节点、或者任何需要记录睡眠电流和工作电流的嵌入式开发者参考。1. uA级测量为什么不是“调大ADC位数”就完事1.1 16bit ADC折算到电流到底能分辨多少INA226的ADC是16位但它的输入范围不是0到5V那种而是分流电压范围固定为±81.92mV。把81.92mV除以2的15次方每个LSB对应的电压是2.5µV。这个数很关键因为电流能不能测出来先看分流电阻能不能把这微安级电流变成足够大的电压摆幅。假设我用10Ω分流电阻1µA电流会产生10µV压降相当于4个LSB10µA就是100µV对应40个LSB。如果换成分流电阻1Ω1µA只有1µV连一个LSB都不到ADC输出基本就是在噪声里打滚软件再怎么滤波也救不回来。所以测µA级电流第一件事就是把分流电阻选大。但选大是有代价的后面会专门说。这里顺手算一笔账用10Ω电阻时电流分辨率 2.5µV / 10Ω 250nA。也就是说一个LSB代表0.25µA纸面上已经可以分辨几百nA的变化了。听着很美好但实际测量中漂移往往是几个甚至几十个LSB地跳这才是µA级测量真正的麻烦所在。1.2 偏置电流和失调电压数据手册不会直接告诉你的误差INA226不是理想电压表它的IN和IN-引脚会流入/流出输入偏置电流规格表里最坏情况可能到10µA级。这个电流流过分流电阻时会产生一个附加压降被ADC当成电流信号读出来。换算一下10µA偏置电流经过10Ω电阻就是100µV等价于10µA的测量误差。这比我们想测的µA级电流本身还大。有人会问那我把零电流时的读数存下来然后每次扣除不就行了可以但这只能扣除固定部分。输入偏置电流和失调电压都会随温度变化天亮和半夜读数差出几个µA并不奇怪。所以做µA级电流驱动不能只关心LSB分辨率还要在硬件和软件里同时处理“偏移”和“漂移”这两个问题。很多第一次上手的朋友把数据手册上的公式敲进代码发现读数完全对不上就是栽在这。2. 分流电阻和PCB布局驱动写之前先解决硬件2.1 分流电阻选择别让量程吃掉分辨率分流电阻的阻值需要同时满足两个条件一是让最小目标电流产生足够多的LSB二是最大电流下压降不能超过81.92mV也不能让系统电压跌得没法用。举个例子如果设备最大工作电流是5mA那分流电阻最多取81.92mV / 5mA ≈ 16Ω取整用10Ω是合理的。最大压降50mV测量分辨率250nA既能覆盖睡眠时的几个µA也能看到正常工作的mA级消耗。如果你要测的最小电流是0.5µA10Ω电阻依然不够0.5µA只能产生5µV压降仅仅2个LSB读数会非常不稳定。这时候要把电阻加大到100Ω甚至更高但代价是最大电流被限制在819µA以内稍微跑一个射频收发就超量程了。实测中这是很难兼得的点所以我一般建议先明确最小电流和最大电流再反推电阻阻值而不是随手从开发板上拆一个。电阻精度和温漂也不能忽略。1%精度的电阻在校准后虽然可以补偿比例误差但温漂会跟着环境跑如果要长期记录数据至少用0.1%精度、25ppm/°C或者更好温漂的低温漂电阻。功率上也要留余量比如10Ω、5mA通过的功耗只有0.25mW选0603封装就够但如果是大电流档位就一定要算一下。2.2 开尔文接法与防漏电走线INA226这类芯片本身适合四线测量也就是让大电流走线和小信号感测走线分开。分流电阻两端的焊盘应该各自引出一对走线一对走负载电流一对专门给INA226的IN和IN-采样。如果直接把芯片引脚怼在大电流铜皮上铜皮自身的电阻和焊接点的热电势都会变成误差虽然通常只有零点几毫伏对µA级测量来说已经不可接受了。PCB上最容易被忽略的是漏电流。感测节点是高阻节点如果走线附近有助焊剂残留或者板子本身受潮表面会形成一条看不见的漏电路径等效电阻可能只有几百兆欧甚至更低。在3.3V电源轨下几百兆欧漏电阻对应几十nA到几百nA的漏电流这正好落在我们要测量的µA区间里。所以感测线要尽量短不要大面积敷铜过孔越少越好焊完板子用洗板水把助焊剂洗干净潮湿环境再加三防漆。有一点容易被忽略INA226的地和负载地必须走同一条回路。如果芯片GND通过另一条路径回到电源负极而分流器附近的地线又有压差会把地环路噪声引入测量结果。我遇到过一次读数周期性波动最后发现是I2C上拉电阻的接地点和INA226的GND不在同一位置导致。3. 驱动程序的正确写法配置、校准和读数3.1 配置寄存器和平均次数怎么定INA226上电后默认配置是连续测量分流电压和总线电压但每次采样只做一次转换噪声很大。要稳定读µA级电流需要打开内部平均功能。配置寄存器里AVG位可以设成1、4、16、64、128、256、512、1024次平均。我的习惯是设成256次转换时间选1.1ms这样一个周期大概282ms对低功耗设备的电流监控来说足够读出来的原始值也基本不见跳动。如果你要追踪突然唤醒这种瞬态事件就别把平均值开太大否则256次平均会把一个2ms的脉冲摊平电流峰值直接被吞掉。这种场景下配置成16次平均然后在驱动里用软件滤波效果会更好。下面是我常用的初始化写法直接写配置和校准寄存器#define INA226_I2C_ADDR 0x40 #define REG_CONFIG 0x00 #define REG_CURRENT 0x04 #define REG_CALIBRATION 0x05 // 配置AVG256VBUSCT1.1msVSHCT1.1ms连续分流总线测量 #define INA226_CONFIG_AVG256_1MS 0x4A97 // 校准值见下文计算 #define INA226_CAL_VALUE 0x0800 void ina226_init(void) { i2c_write_reg16(INA226_I2C_ADDR, REG_CONFIG, 0x8000); // 复位 delay_ms(2); i2c_write_reg16(INA226_I2C_ADDR, REG_CONFIG, INA226_CONFIG_AVG256_1MS); i2c_write_reg16(INA226_I2C_ADDR, REG_CALIBRATION, INA226_CAL_VALUE); }3.2 校准寄存器数值的计算INA226的电流寄存器不是让我们直接读原始电压再自己除电阻的而是内部用“分流电压寄存器 × 校准寄存器 / 2048”算出一个电流值。校准寄存器怎么填是驱动里最容易写错的地方。手册给出公式Calibration 0.00512 / (Current_LSB × Rshunt)其中Current_LSB单位是安培。Current_LSB的选择思路是先用满量程电压除以分流电阻得到最大可测电流I_MAX再把I_MAX除以32768得到每个LSB对应的电流。以10Ω电阻为例I_MAX 81.92mV / 10Ω 8.192mACurrent_LSB 8.192mA / 32768 250nACalibration 0.00512 / (250nA × 10Ω) 2048 0x0800这里要特别注意Current_LSB取得越小校准值会越大但不要为了“分辨率好看”随便缩小Current_LSB否则电流寄存器在最大电流时会溢出。反过来Current_LSB取得太大微安级变化又看不出来。用I_MAX / 32768这个方式选LSB可以让满量程读数刚好对应0x7FFF是最稳妥的做法。3.3 一个能直接改的读取代码骨架读取电流寄存器时要注意它是有符号16位负值代表反向电流。代码里我加了一个零点偏移变量专门用来扣除前面说的偏置电流和失调电压带来的固定偏差。校准零点要在设备真正进入零电流状态时做比如睡眠前或者负载开关断开后。static int16_t zero_offset_lsb 0; void ina226_calibrate_zero(void) { int32_t sum 0; for (int i 0; i 16; i) { sum i2c_read_reg16(INA226_I2C_ADDR, REG_CURRENT); delay_ms(20); } zero_offset_lsb (int16_t)(sum / 16); } float ina226_read_current_ua(void) { int16_t raw i2c_read_reg16(INA226_I2C_ADDR, REG_CURRENT); int16_t corrected raw - zero_offset_lsb; return (float)corrected * 250e-6f; // LSB250nA换算成µA就是×0.25 }这里再补一句如果你不想让芯片内部做电流换算也可以不写校准寄存器直接读分流电压寄存器然后用“电压 / 电阻”自己算。两种方式都行但内部电流寄存器能顺带得到功率寄存器值而且四字节的原始分流电压在调试时更容易看出问题所以我通常先把分流电压寄存器打印出来对照再决定用哪个读数。4. 实测典型漂移和排查思路4.1 开机电流失真/负数零点偏移我第一次上电读到的“-270µA”就是典型的零点偏移问题。INA226的输入偏置电流方向不固定加上芯片和PCB上的微小压差会让零电流时的读数不是0而是一个正的或负的常数。最好的验证方式就是在不接负载的情况下持续打印分流电压和电流寄存器原始值。不要只看电流寄存器电流寄存器经过了校准系数放大会把偏移一起放大容易误判成“芯片坏了”。解决办法就是上面代码里的零点校准。要注意校准时机必须在负载真实断电的情况下执行比如电源管理芯片把负载轨关断后或者MCU自己进入关机模式前。如果你在负载还在消耗电流时采集零点这个“零点”里其实包含了背景功耗后面所有读数都会错一个定值。4.2 数据缓慢爬升温度、漏电、地环路零点校准后读数可能在一个小时内缓慢爬升几百nA。这种漂移通常是温度变化引起的。芯片靠近发热元件、分流电阻自身发热都会让输入偏置电流和失调电压发生变化。解决思路是在硬件上让INA226远离功率管和射频功放在软件上不要只存一个永久零点而是利用系统已知的低功耗窗口定时重新校准。还有一种情况是漏电。我遇到过一块板子洗完板读数正常放了一个晚上再测睡眠电流从6µA涨到了12µA。后来发现是感测点附近有残留助焊剂吸收了空气中的水分。重新清洗并烘干后读数恢复。如果产品要过湿热环境感测走线周围做一圈等电位护环比换任何软件滤波都管用。地环路也需要排查。用示波器探头钩在INA226的GND和电源负极之间如果看到几十毫伏的纹波说明两个地之间有大电流回路。这种问题大多出在线缆连接或PCB地平面割裂上优先保证INA226和分流器的地线形成单点连接。4.3 软件滤波的正确姿势芯片内部平均已经能压掉大部分白噪声但如果你设的是16次或64次平均读出来的数据在最低位还会跳动。这时候可以在驱动里做一个环形缓冲区取最后8次或16次读数的均值。这个滤波不能消除漂移但能让串口打印的数据稳定下来。#define FILTER_TAPS 16 static int16_t ring[FILTER_TAPS]; static uint8_t head 0; float ina226_read_filtered_ua(void) { int16_t raw i2c_read_reg16(INA226_I2C_ADDR, REG_CURRENT); ring[head] raw; head % FILTER_TAPS; int32_t sum 0; for (int i 0; i FILTER_TAPS; i) { sum ring[i]; } int16_t avg (int16_t)(sum / FILTER_TAPS) - zero p a hrefhttps://download.csdn.net/download/qq404662849/10535219 stylecolor:#ec7500;font-size:14px; 本文还有配套的精品资源点击获取 /a img altmenu-r.4af5f7ec.gif srchttps://csdnimg.cn/release/wenkucmsfe/public/img/menu-r.4af5f7ec.gif stylewidth:16px;margin-left:4px;vertical-align:text-bottom;cursor:text; /p
返回列表