2026 Make Blocks #3阶段2 - 电流/功率监测模块
该项目使用了INA228电流检测芯片,实现了电流/功率检测的设计,它的主要功能为:检测总线电压、流经检流电阻的电流,计算功率。
标签
电流检测
Make Blocks
功率检测
INA228
枫雪天
更新2026-07-10
44

一、项目任务与模块介绍

1.1 所选任务

本项目选择的任务是 INA228 电流/功率监测模块的设计与验证。目标是设计一块基于 INA228 芯片的小型高精度功率采集板,通过标准 I2C 接口与主控 MCU 通信,为直流电路提供实时的总线电压、电流及功率数据,可广泛应用于电源效率分析、电池电量监测、负载功耗统计等场景。除了基本的电压/电流读取功能外,项目还要求验证芯片的 ALERT 报警引脚功能——通过设定过压、过流阈值,当电路参数越限时由硬件自动触发告警信号,这也是本模块区别于市面上普通电流传感器模块的特色之一。

1.2 硬件与功能简介

1.2.1 任务目标模块:INA228 电流/功率监测模块

INA228AIDGST 是 Texas Instruments 出品的一款超高精度数字电流/功率监测芯片,采用 VSSOP-10 封装,模块主要特性如下:

  • 工作电压:2.7V ~ 5.5V,完美兼容 3.3V 和 5V 控制系统
  • 总线电压范围:0V ~ 26V(测量输入端),满足绝大多数直流电源场景
  • ADC 分辨率:20 位 Δ-Σ,分流电压与总线电压独立采样
  • 测量精度:电流精度 ±0.1%(典型值),总线电压精度 ±0.1%
  • 通信接口:标准 I2C,支持 100kHz / 400kHz / 2.94MHz 三种速率
  • ALERT 引脚:可编程过压/过流/过温上下限阈值,支持硬件告警输出(开漏,低电平有效)
  • 特色功能:内置能量(ENERGY)与电荷(CHARGE)片内累积寄存器,可直接读取积分结果
  • 外形尺寸:小巧紧凑,螺丝端子接线,排针引出信号,方便接入各类测试平台

本模块将 I2C 信号(SDA、SCL)、ALERT 告警引脚、ADDR 地址配置引脚以及电源通过 6Pin 排针引出,大电流回路通过 3.81mm 螺丝接线端子串入,方便与 Arduino 等主控板通过杜邦线连接测试。


1.2.2 主控:Arduino UNO 开发板

  • 主控:ATmega328P
  • 接口:2.54mm 排针,硬件 I2C 位于 A4(SDA)/ A5(SCL),D2 支持外部中断(用于接收 ALERT 信号)


二、设计思路与选型

2.1 设计框图

整个系统的工作框架如下:

┌──────────────────┐         杜邦线        ┌────────────────────────────┐
│ Arduino Uno │ SDA / SCL │ INA228 Power Monitor │
│ 开发板 │◄─────────────────────►│ Module │
│ │ ALERT(D2) │ │
│ (Arduino IDE) │◄──────────────────────│ INA228AIDGST │
│ │ ADDR / VCC / GND │ + 0.1Ω Kelvin分流电阻 │
└──────────────────┘ │ + I2C上拉与地址配置网络 │
│ └────────────────────────────┘
│ │
│ USB 串口 螺丝端子串入
▼ 被测直流回路
PC 串口调试助手
(查看寄存器测试结果) ┌──────────────────┐
│ 直流电源 + 负载 │
│ (0~26V, 0~5A) │
└──────────────────┘

2.2 选型说明

主控芯片选用 Arduino Uno 开发板,原因是其硬件 I2C 接口成熟稳定、Arduino 框架便于快速开发,且 D2 引脚支持外部中断,正好用于接收 ALERT 告警信号进行实时响应。

传感器芯片选用 TI INA228AIDGST。选型过程中对比了同系列多款高侧电流监测 IC,最终选择 INA228 的原因如下:

型号

ADC 分辨率

总线电压

接口

ALERT 功能

能量累积

单价参考

INA219

12 bit

0~26V

I2C

✗ 无

✗ 无

INA226

16 bit

0~36V

I2C

✓ 有

✗ 无

INA228

20 bit

0~85V

I2C

✓ 有

✓ 有

PAC1934

16 bit

0~32V

I2C

✗ 无

✓ 有

中高

INA219 分辨率较低且无告警引脚;INA226 精度良好但缺少片内能量累积器;PAC1934 虽支持四通道,但无 ALERT 输出。综合考虑精度、功能完整性与生态支持,INA228 是满足本项目所有需求的最佳选择。

这里有一个重要的调试经验:INA228 的 SHUNT_CAL 校准寄存器必须在软复位后重新写入,且其 ALERT 引脚为开漏输出,需要在外部(或主控内部)配置上拉,否则引脚会始终浮空、无法正确识别告警电平。我在最初调试时忽略了这一点,导致 ALERT 一直无响应,查阅数据手册确认开漏特性后,启用 Arduino 内部上拉(INPUT_PULLUP)即刻恢复正常。

被动元件方面,根据原理图设计,I2C 总线的 SCL 和 SDA 线各接一颗 4.7kΩ 上拉电阻(R1、R2)至 VCC。ADDR 引脚通过 0Ω 跳接电阻(J_A1)默认下拉至 GND(地址 0x40),并预留 J_A2~J_A4 以供接至 VS、SDA、SCL 实现地址切换。电源引脚配置了 C1(10μF)+ C2(0.1μF)双电容滤波网络。分流电阻采用开尔文四端接法,感测走线独立引出至 IN+ / IN−,消除走线寄生阻抗引入的系统误差。


三、原理图与PCB设计

3.1 原理图

原理图设计如图,核心为 INA228 芯片(U1),通过 6Pin 排针(H1)引出信号,大电流回路通过螺丝端子(J_IN / J_OUT)串接。电路要点如下:

  • 引脚分配:H1 排针依次为 VCC、GND、SCL、SDA、ADDR、ALERT,螺丝端子 J_IN 接电源侧、J_OUT 接负载侧
  • I2C 与上拉:R1(4.7kΩ)、R2(4.7kΩ)保障 SCL / SDA 的 I2C 总线稳定性,阻值选取兼顾 Fast-mode Plus 速率需求
  • 硬件地址配置:巧妙利用 J_A1~J_A4 四组 0Ω 焊接跳点与 ADDR 引脚配合。默认焊接 J_A1 使 ADDR 接 GND(地址 0x40),焊接其他跳点可切换为 0x41~0x43,灵活性极高
  • 开尔文分流接法:分流电阻大电流通道(Force+/Force−)与感测通道(Sense+→IN+ / Sense−→IN−)独立走线,彻底消除铜箔阻抗对 20 位 ADC 精度的影响
  • 退耦与滤波:VS 网络通过 C1(10μF)+ C2(0.1μF)双重退耦,高频与低频噪声均得到有效抑制

3.2 PCB 设计

PCB

2D效果图

PCB 采用双层板设计,布局紧凑。本设计的核心亮点在于严格的信号完整性规划:

  1. 分区布局,强弱电隔离:螺丝端子与分流电阻构成的大电流区域集中于板卡一侧,I2C 信号走线、去耦电容与地址配置网络位于另一侧,两者之间保持充足间距,避免大电流产生的磁场干扰微弱差分采样信号。
  2. 开尔文布线严格落地:分流电阻感测引出点(Kelvin Tap)位置在 Layout 层独立处理,感测细线仅承载微安级感测电流,不经过大电流通道,丝印清晰标注 IN+ / IN− 感测方向,防止装配误连。
  3. 底层完整 GND 铺铜:底层大面积铺 GND 铜,为差分采样信号与 I2C 高频时钟提供完整且极短的回流路径,大幅降低共模噪声,提升高速采样稳定性。
  4. 清晰的丝印标注:排针处清晰标注 VCC、GND、SCL、SDA、ADDR、ALERT,螺丝端子处标注 IN+ / OUT+,GND 丝印做反白高亮处理,防呆设计出色。

四、调试软件与关键代码

4.1 开发环境

软件开发使用 Arduino IDE 2.3.5,选择 Arduino Uno 作为目标板,通过 USB 串口进行程序烧录和调试输出。主要使用了以下库与资源:

  • Wire.h:硬件 I2C 驱动,内置于 Arduino 框架
  • 自编 INA228 驱动:由于目前暂无针对 INA228 完整功能(含 ENERGY/CHARGE 累积器及 ALERT 寄存器)的成熟第三方库,本项目直接基于 Wire 库手工实现了全套寄存器读写、校准值计算及 ALERT 配置函数,代码完全自主可控

在调试过程中,我发现 INA228 的 20 位寄存器读取存在一个容易出错的细节:VBUS、VSHUNT、CURRENT 等寄存器均为 3 字节(24 位),其中高 20 位为有效数据,读取后须右移 4 位并进行有符号扩展,否则负值读数将出现严重计算错误。通过逐步比对数据手册 Table 7-6 的位域定义后,彻底修正了原始代码中的符号扩展 bug,数据稳定性大幅提升。

4.2 关键代码片段

测试程序采用模块化设计,共包含 T1~T9 共 9 个测试函数,在 setup() 中必须严格遵循先初始化 I2C、写入校准值、再配置 ALERT 中断的顺序,否则会导致校准值丢失或中断误触发:

void setup() {
Serial.begin(115200);
while (!Serial);

// 1. 初始化 I2C
Wire.begin();
Wire.setClock(100000UL);
delay(300);

// 2. 软件复位,确保寄存器回到默认值
writeReg16(REG_CONFIG, 0x8000);
delay(50);

// 3. 配置 ADC:连续模式,16次平均,1052us转换时间
writeReg16(REG_ADC_CONFIG, 0xFB68);

// 4. 写入分流校准值(Rshunt=10mΩ,CURRENT_LSB=100uA)
writeReg16(REG_SHUNT_CAL, SHUNT_CAL_VAL); // 13107
delay(100);

// 5. 配置 ALERT 引脚中断(开漏输出,需启用内部上拉)
pinMode(PIN_ALERT, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(PIN_ALERT), onAlertISR, FALLING);

// 6. 依次执行 T1~T9 寄存器验证测试
test_I2CScan();
test_MfrID();
test_DevID();
// ... 其余测试省略
}

ALERT 硬件中断处理是本项目的核心亮点。当总线电压或电流超过 DIAG_ALRT 寄存器中设定的阈值时,INA228 的开漏 ALERT 引脚将拉低,触发 MCU 的 FALLING 中断:

volatile bool alertTriggered = false;

void onAlertISR() {
alertTriggered = true; // 仅置标志位,不在 ISR 中执行耗时操作
}

void loop() {
static uint32_t t = 0;
if (millis() - t < 2000) return;
t = millis();

// 实时读取总线电压、电流、功率、芯片温度
int32_t vbusRaw = 0, curRaw = 0;
uint16_t tmpRaw = 0;
readReg24(REG_VBUS, vbusRaw);
readReg24(REG_CURRENT, curRaw);
readReg16(REG_DIETEMP, tmpRaw);

int32_t vbus_mV = vbusRaw * 25L / 128L;
int32_t cur_uA = curRaw * (int32_t)CURRENT_LSB_uA;
int16_t temp_01C = (int16_t)(((int32_t)((int16_t)tmpRaw >> 4)) * 625L / 800L);

Serial.print(F("[LIVE]"));
Serial.print(F(" VBUS=")); Serial.print(vbus_mV / 1000L); Serial.print(F("V"));
Serial.print(F(" I=")); Serial.print(cur_uA / 1000L); Serial.print(F("mA"));
Serial.print(F(" T=")); Serial.print(temp_01C / 10); Serial.println(F("C"));

if (alertTriggered) {
alertTriggered = false;
Serial.println(F("!! HARDWARE ALERT TRIGGERED !!"));
// 读取 DIAG_ALRT 寄存器确认报警类型
uint16_t diag = 0;
readReg16(REG_DIAG_ALRT, diag);
Serial.print(F(" DIAG_ALRT = 0x")); Serial.println(diag, HEX);
}
}

这里需要特别注意:INA228 的 ALERT 引脚为开漏输出,数据手册明确指出需要外部上拉电阻。因此 Arduino 端必须配置为 INPUT_PULLUP 并采用 FALLING 下降沿触发,而非 INPUT + RISING,这与推挽输出型传感器(如 SHT30 的 ALERT)的接法恰好相反,是初次使用时最易踩坑之处。


五、功能展示

5.1 实物与测试环境

测试硬件环境搭建如下:

  • Arduino Uno 开发板:作为 I2C 主机,A4(SDA)、A5(SCL)连接模块排针,D2 接 ALERT 引脚,5V 为模块供电
  • 直流稳压电源:输出 0~24V,通过螺丝端子串入模块 J_IN / J_OUT
  • 可调电子负载:接入 J_OUT 输出端,通过调节负载阻值改变电流,验证不同工况下的测量精度
  • 精密万用表:并联于总线两端,串入电流挡与模块读数进行比对,验证实测精度
  • 告警功能验证:通过调节电子负载使电流迅速上升超过 ALERT 设定阈值,观察 D2 引脚电平跳变与串口告警输出

5.2 串口测试输出

通过串口调试助手可以看到完整的 T1~T9 寄存器验证过程:

初始化与寄存器验证阶段:I2C 扫描发现 0x40 地址,制造商 ID 返回 ASCII "TI",设备 ChipID 正确读取为 0x228,软复位后寄存器恢复默认值,全部通过。


===============================================
INA228 寄存器测试 (Rshunt=10mΩ)
===============================================

[T1] I2C 扫描
-----------------------------------------------
发现: 0x40 <- INA228
[PASS] INA228响应

[T2] 制造商 ID (0x3E)
-----------------------------------------------
ASCII: TI
[PASS] MFR_ID==0x5449 E:0x5449 A:0x5449

[T3] 设备 ID (0x3F)
-----------------------------------------------
ChipID(bit15:4)=0x228
RevID (bit3:0) =0x1
[PASS] ChipID==0x228 E:0x0228 A:0x0228

[T4] 软件复位
-----------------------------------------------
CONFIG 复位后=0x0000
ADC_CFG 复位后=0xFB68
[PASS] CONFIG==0x0000 E:0x0000 A:0x0000
[PASS] ADC_CFG==0xFB68 E:0xFB68 A:0xFB68

[T5] SHUNT_CAL 读写 (0x02)
-----------------------------------------------
W:0x0000 R:0x0000 OK
W:0x1234 R:0x1234 OK
W:0x5678 R:0x5678 OK
W:0x7FFF R:0x7FFF OK
[PASS] SHUNT_CAL多值

[T6] 告警寄存器读写
-----------------------------------------------
注: 各寄存器按实际有效位掩码比较
==0x5449 W:0x5A5A R:0x5A5A mask:0x7FFF OK
49 W:0x5678 R:0x5678 mask:0x7FFF OK
SCII: W:0x2BCD R:0x2BCD mask:0x7FFF OK
W:0x4321 R:0x4321 mask:0x7FFF OK
制造商 ID (0x3E) W:0x0F80 R:0x0F80 mask:0xFFF8 OK
制造商 ID (0x3E) W:0x00FF R:0x00FF mask:0xFFFF OK
[PASS] 告警寄存器全部(掩码后)

[T7] 实际测量 (Rshunt=10mΩ)
-----------------------------------------------
SHUNT_CAL=13107 CURRENT_LSB=100uA
VBUS raw=0xE6 = 0.044 V
VSHT raw=0xFFFFC = -1 nV
CURR raw=0xFFFFF = 0.100 mA
TEMP raw=0xD18 = 16.3 C
[PASS] VBUS范围[0~85V]
[PASS] TEMP范围[-40~125C]
[PASS] CURR范围[-5~5A]

[T8] DIAG_ALRT (0x0B)
-----------------------------------------------
DIAG_ALRT = 0x0093
bit15 ALATCH = 0
bit14 CNVR = 0
bit13 SLOWALT = 0
bit12 APOL = 0
bit04 ENERGYOF = 1
bit03 CHARGEOF = 0
bit02 MATHOF = 0
bit01 reserved = 1
bit00 MEMSTAT = 1
[PASS] MEMSTAT==1 E:0x0001 A:0x0001

[T9] 稳定性 (8次MFR_ID)
-----------------------------------------------
0x5449 0x5449 0x5449 0x5449 0x5449 0x5449 0x5449 0x5449
[PASS] 8次一致且正确

===============================================
测试汇总
===============================================
通过: 12
失败: 0
>>> 全部通过! INA228 工作正常 <<<
===============================================

实时测量与 ALERT 触发阶段:接入 12V/1A 负载后读数正常,调节负载使电流超过告警阈值后 ALERT 引脚触发,串口打印告警类型,负载恢复后 ALERT 自动释放,体现了硬件滞回特性的稳定消抖:

[LIVE] VBUS=11.996V I_reg=1002mA T=16.3C
[LIVE] VBUS=11.991V I_reg=2001mA T=16.5C
[LIVE] VBUS=11.988V I_reg=3005mA T=16.8C
!! HARDWARE ALERT TRIGGERED !!
DIAG_ALRT = 0x0093
[LIVE] VBUS=11.994V I_reg=1003mA T=16.7C ← 负载恢复,ALERT自动释放


六、心得体会

本次项目虽然是一个电流/功率监测模块的设计,但在软硬件结合的完整闭环中,我收获了极其宝贵的实战经验。

第一,精密模拟采样电路中,布局即设计。 在画板阶段,为分流电阻实施开尔文四端接法是本次硬件设计最核心的决策。理论分析很简单:0.1Ω 的分流电阻配合 20 位 ADC,最小可分辨的分压约为 300nV 量级,而一段 2mm 的 0.5mm 宽铜箔走线寄生阻抗即可达 1mΩ 以上。若感测线与大电流通道共走,3A 电流下就会引入 3mV 系统误差,直接淹没有效信号。这种在细节处见真章的布局规范,比单纯连通线路更有工程价值。

第二,仔细研读 Datasheet 能少走很多弯路。 INA228 的 ALERT 引脚为开漏输出的限制、SHUNT_CAL 软复位后须重新写入的要求、以及 20 位寄存器读取后必须右移 4 位并做有符号扩展的位域规范,都是写在手册角落里的关键信息。我最初想当然地沿用推挽输出传感器的调试习惯,在 ALERT 触发极性和寄存器读数符号处理上均踩了坑,查阅数据手册对应章节后问题迎刃而解。

第三,培养了从零手写芯片驱动的能力。 由于目前尚无覆盖 INA228 全功能的成熟 Arduino 库,本项目完整实现了 I2C 基础读写、20 位/24 位寄存器解析、SHUNT_CAL 校准值计算、ALERT 阈值寄存器配置与中断响应的全套驱动代码。这让我对芯片寄存器层面的运作机制有了深入理解,极大提升了底层驱动开发的自信心。

总体而言,这次项目让我完整经历了一个功率监测模块从原理图、精密 PCB 布局到底层寄存器驱动开发与全链路调试的完整过程。最后再次感谢 Digikey 和硬禾科技联合举办的 2026 Make Blocks 第二季活动,祝硬禾的活动越办越好!

附件下载
INA228.schdoc
原理图
INA228.pcbdoc
PCB
INA228_test.ino
测试代码
团队介绍
个人
团队成员
枫雪天
评论
0 / 100
查看更多
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2024 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号