INA226 测量电压和电流

       INA226 是德州仪器 (TI) 的一款 IC,可以轻松、超精确地测量电流、电压和功率。 接口为 I2

                   。

   可以获取四种类型的电压:电压 (Bus Voltage)、分流电阻电压 (Shunt Voltage)、电流 (Current) 和功率 (Power)。 功率、分流电压→电流的转换和平均处理由 IC 内部完成。 为了计算电流和功率,必须在初始化时将分流电阻常数写入校准寄存器。         

#include <Wire.h>

#define NELEMS(arg) (sizeof(arg) / sizeof((arg)[0]))

const int   INA226_ADDR         = 0x40;                 // INA226 I2C Address (A0=A1=GND)
const word  INA226_CAL_VALUE    = 0x0A00;               // INA226 Calibration Register Value

// INA226 Registers
#define INA226_REG_CONFIGURATION_REG            0x00    // Configuration Register (R/W)
#define INA226_REG_SHUNT_VOLTAGE                0x01    // Shunt Voltage (R)
#define INA226_REG_BUS_VOLTAGE                  0x02    // Bus Voltage (R)
#define INA226_REG_POWER                        0x03    // Power (R)
#define INA226_REG_CURRENT                      0x04    // Current (R)
#define INA226_REG_CALIBRATION                  0x05    // Calibration (R/W)
#define INA226_REG_MASK_ENABLE                  0x06    // Mask/Enable (R/W)
#define INA226_REG_ALERT_LIMIT                  0x07    // Alert Limit (R/W)
#define INA226_REG_DIE_ID                       0xFF    // Die ID (R)

// Operating Mode (Mode Settings [2:0])
#define INA226_CONF_MODE_POWER_DOWN             (0<<0)  // Power-Down
#define INA226_CONF_MODE_TRIG_SHUNT_VOLTAGE     (1<<0)  // Shunt Voltage, Triggered
#define INA226_CONF_MODE_TRIG_BUS_VOLTAGE       (2<<0)  // Bus Voltage, Triggered
#define INA226_CONF_MODE_TRIG_SHUNT_AND_BUS     (3<<0)  // Shunt and Bus, Triggered
#define INA226_CONF_MODE_POWER_DOWN2            (4<<0)  // Power-Down
#define INA226_CONF_MODE_CONT_SHUNT_VOLTAGE     (5<<0)  // Shunt Voltage, Continuous
#define INA226_CONF_MODE_CONT_BUS_VOLTAGE       (6<<0)  // Bus Voltage, Continuous
#define INA226_CONF_MODE_CONT_SHUNT_AND_BUS     (7<<0)  // Shunt and Bus, Continuous (default)

// Shunt Voltage Conversion Time (VSH CT Bit Settings [5:3])
#define INA226_CONF_VSH_140uS                   (0<<3)  // 140us
#define INA226_CONF_VSH_204uS                   (1<<3)  // 204us
#define INA226_CONF_VSH_332uS                   (2<<3)  // 332us
#define INA226_CONF_VSH_588uS                   (3<<3)  // 588us
#define INA226_CONF_VSH_1100uS                  (4<<3)  // 1.1ms (default)
#define INA226_CONF_VSH_2116uS                  (5<<3)  // 2.116ms
#define INA226_CONF_VSH_4156uS                  (6<<3)  // 4.156ms
#define INA226_CONF_VSH_8244uS                  (7<<3)  // 8.244ms

// Bus Voltage Conversion Time (VBUS CT Bit Settings [8:6])
#define INA226_CONF_VBUS_140uS                  (0<<6)  // 140us
#define INA226_CONF_VBUS_204uS                  (1<<6)  // 204us
#define INA226_CONF_VBUS_332uS                  (2<<6)  // 332us
#define INA226_CONF_VBUS_588uS                  (3<<6)  // 588us
#define INA226_CONF_VBUS_1100uS                 (4<<6)  // 1.1ms (default)
#define INA226_CONF_VBUS_2116uS                 (5<<6)  // 2.116ms
#define INA226_CONF_VBUS_4156uS                 (6<<6)  // 4.156ms
#define INA226_CONF_VBUS_8244uS                 (7<<6)  // 8.244ms

// Averaging Mode (AVG Bit Settings[11:9])
#define INA226_CONF_AVG_1                       (0<<9)  // 1 (default)
#define INA226_CONF_AVG_4                       (1<<9)  // 4
#define INA226_CONF_AVG_16                      (2<<9)  // 16
#define INA226_CONF_AVG_64                      (3<<9)  // 64
#define INA226_CONF_AVG_128                     (4<<9)  // 128
#define INA226_CONF_AVG_256                     (5<<9)  // 256
#define INA226_CONF_AVG_512                     (6<<9)  // 512
#define INA226_CONF_AVG_1024                    (7<<9)  // 1024

// Reset Bit (RST bit [15])
#define INA226_CONF_RESET_ACTIVE                (1<<15)
#define INA226_CONF_RESET_INACTIVE              (0<<15)

static void writeRegister(byte reg, word value)
{
  Wire.beginTransmission(INA226_ADDR);
  Wire.write(reg);
  Wire.write((value >> 8) & 0xFF);
  Wire.write(value & 0xFF);
  Wire.endTransmission();
}

static void setupRegister(void)
{
  writeRegister(INA226_REG_CONFIGURATION_REG, 
        INA226_CONF_RESET_INACTIVE
      | INA226_CONF_MODE_CONT_SHUNT_AND_BUS
      | INA226_CONF_VSH_1100uS
      | INA226_CONF_VBUS_1100uS
      | INA226_CONF_AVG_64
      );
  
  writeRegister(INA226_REG_CALIBRATION, INA226_CAL_VALUE);
}

static word readRegister(byte reg)
{
  word res = 0x0000;
  
  Wire.beginTransmission(INA226_ADDR);
  Wire.write(reg);
  
  if(Wire.endTransmission() == 0) {
    if(Wire.requestFrom(INA226_ADDR, 2) >= 2) {
      res = Wire.read() * 256;
      res += Wire.read();
    }
  }
  
  return res;
}

typedef struct tagREG_INFO {
  byte	reg;
  const char*	name;
}REG_INFO;

const static REG_INFO   st_aRegs[] = {
  { INA226_REG_CONFIGURATION_REG,   "Configuration Register"    },
  { INA226_REG_SHUNT_VOLTAGE,       "Shunt Voltage"             },
  { INA226_REG_BUS_VOLTAGE,         "Bus Voltage"               },
  { INA226_REG_POWER,               "Power"                     },
  { INA226_REG_CURRENT,             "Current"                   },
  { INA226_REG_CALIBRATION,         "Calibration"               },
  { INA226_REG_MASK_ENABLE,         "Mask/Enable"               },
  { INA226_REG_ALERT_LIMIT,         "Alert Limit"               },
  { INA226_REG_DIE_ID,              "Die ID"                    },
};

static void dumpRegisters(void)
{ 
  int i;
  const REG_INFO* pInfo;
  static word REGS[NELEMS(st_aRegs)];
  static char  buf[64];
  
  for(i = 0; i < NELEMS(REGS); i++) {
    pInfo = &st_aRegs[i];
    REGS[i] = readRegister(pInfo->reg);
  }
  
  Serial.println("---INA226 Registers ---");
  
  for(i = 0; i < NELEMS(REGS); i++) {
    pInfo = &st_aRegs[i];
    snprintf(buf, NELEMS(buf), "%24s (%02Xh) : %04Xh (%u)", pInfo->name, pInfo->reg, REGS[i], REGS[i]);
    Serial.println(buf);
  }
}

void setup()
{
  // Initialize I2C with IO22 as SCL and IO21 as SDA
  Wire.begin(21, 22);
  Serial.begin(9600);
  
  setupRegister();
}

void loop()
{
  char  buf[64];
  long  voltage;   // Bus Voltage (mV)
  short current;   // Current (mA)
  long  power;     // Power (uW)
  
  voltage  = (long)((short)readRegister(INA226_REG_BUS_VOLTAGE)) * 1250L;    // LSB=1.25mV
  current  = (short)readRegister(INA226_REG_CURRENT);
  power    = (long)readRegister(INA226_REG_POWER) * 25000L;                  // LSB=25mW
  
  Serial.println();
  snprintf(buf, NELEMS(buf)
    , "V:%5ldmV, I:%5dmA, P:%5ldmW"
    , (voltage + (1000/2)) / 1000
    , current
    , (power + (1000/2)) / 1000
    );
    
  Serial.println(buf);

  dumpRegisters();
  
  delay(1000);
}

### INA226 测量电压电流的工作原理 #### 1. 工作概述 INA226 是一种高精度、低功耗的电流/电压监测芯片,广泛应用于电力监控场景。其核心功能是通过集成的电流传感器差分放大器电路实现对电流电压的精确测量,并通过 I²C 接口将数字化的结果传输到主控设备。 --- #### 2. 电流测量原理 INA226电流测量依赖于一个外置的检测电阻(Shunt Resistor)。当电流流经此电阻时,在其两端会产生一个小的压降(即分流电压),这个压降与电流成正比关系: \[ V_{shunt} = R_{shunt} \times I \] 其中: - \( V_{shunt} \) 表示分流电阻两端的电压, - \( R_{shunt} \) 表示分流电阻的阻值, - \( I \) 表示待测电流INA226 内部集成了一个精密的差分放大器,用于测量分流电阻两端的微小电压差异,并将其转化为比例放大的信号[^1]。随后,该信号会被送入内部 ADC 转换为数字形式以便进一步处理。 为了提高测量精度,用户可以根据实际需求调整分流电阻的阻值以及校准参数。例如,假设分流电阻为 \( R_{shunt} = 0.02\Omega \),则最大可检测电流可通过下式计算得出: \[ I_{max} = \frac{V_{shunt\_max}}{R_{shunt}} \] 如果设定的最大分流电压 \( V_{shunt\_max} = 320mV \),那么最大电流为: \[ I_{max} = \frac{0.32}{0.02} = 16A \][^3] --- #### 3. 电压测量原理 除了测量电流之外,INA226 还能够实时监测负载端的总线电压(Bus Voltage)。这种测量方式同样基于差分放大技术,具体来说,芯片会采集总线电压相对于地电平的变化情况,并将其转换为相应的数字信号输出。 总线电压的有效范围通常介于 0~36V 之间,且独立于供电电源电压工作[^2]。这意味着即使系统的输入电压发生变化,也不会影响到 INA226 对目标回路中电压水平的评估准确性。 --- #### 4. 数据处理流程 完成初步的模拟信号获取之后,所有来自电流路径或者电压节点的信息都会进入 INA226 自带的一个分辨率高达 14-bit 的模数转换器(ADC) 中进行量化操作。接着这些离散化的数值再经历一系列诸如增益调节、噪声抑制之类的优化步骤最终形成可供外部读取的标准格式化数据包并通过预设好的通信协议发送出去供后续分析使用。 以下是简化版的数据处理逻辑图解说明: ```plaintext 原始物理量 -> 模拟前端(AFE) -> ADC 数字化 -> DSP 处理 -> 寄存器存储 -> 主机查询(I2C/SMBus) ``` --- #### 5. 输出机制 最后一步就是利用标准工业级双向串行通讯链路——I²C 或 SMBus 将前述所得结果传递给上位计算机或者其他类型的嵌入式处理器单元来进行显示记录报警等功能扩展开发了[^2]。 --- ### 示例代码:配置 INA226 并读取当前电流值 下面提供一段 Python 示例程序展示如何初始化并从 INA226 获取瞬时电流强度信息: ```python import smbus def configure_ina226(bus, address): # 设置校准寄存器 (Calibration Register) cal_value = int(0x1000) # Example calibration value based on shunt resistor and expected current range. bus.write_word_data(address, 0x05, cal_value) def read_current(bus, address): # 读取电流寄存器 (Current Register) raw_current = bus.read_word_data(address, 0x04) return raw_current * 0.0001 # Convert to Amps according to LSB definition. # 初始化 I2C 总线 i2c_bus = smbus.SMBus(1) ina_address = 0x40 # 默认地址 configure_ina226(i2c_bus, ina_address) current = read_current(i2c_bus, ina_address) print(f"Measured Current: {current:.3f} A") ``` --- ### 结论 综上所述,INA226 利用了分流电阻配合差分放大技术先进的 AD 转换来达成精准可靠的电量指标跟踪目的;同时借助灵活便捷的数字接口设计使得整个解决方案更加易于集成进现代智能化电子系统之中去发挥重要作用[^1]^。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值