This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

INA219读取电流不正常

Other Parts Discussed in Thread: INA219

1.用INA219读取电流,会读到和分流电阻电压寄存器一样的定值,在没有负载的情况下也是这样

2.按照数据手册计算的配置值没用,随便改对电流电压的测量都不会造成什么影响

3.电流的LSB值,改动会影响其他几个值(正确的电压值,功率值和分流电阻电压值)的读取结果,而且没有规律

  • 您好,
    检验一下对Configuration和Calibration寄存器是否可以正确读写,写进去之后是否可以正确读出来呢
  • 您好,我检查了这两个寄存器,没有问题,如果有问题那我的电压值也应该是读取不正常的,但现在的情况是,读不了电流值和分流电阻的电压值,三个寄存器只有一个能正常读取数据

  • 是不是芯片坏了,可以把电路图附上来吗
  • 芯片应该没坏  因为电压一直可以正常读取。这是ina219部分的电路,实际的采样电阻换成了0.05Ω。

  • 这是我ina219的驱动,我实在找不到问题在哪,求助大神!

    //////////////////////////////////////////////////////////////////

    ina219.c

    #include "ina219.h"

    #ifdef INA_INSIDE_IIC

    void INA_IIC_Delay()
    {
    unsigned char x;

    for(x = 1; x > 0; x--)
    {
    __NOP();__NOP();__NOP();__NOP();__NOP();
    }
    }

    void INA_IIC_INIT(void) //IIC初始化
    {
    GPIO_InitTypeDef GPIO_INIT;
    RCC_APB2PeriphClockCmd(IIC_RCC,ENABLE);

    GPIO_INIT.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_INIT.GPIO_Pin = IIC_SDA | IIC_SCL;
    GPIO_INIT.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(IIC_PORT, &GPIO_INIT);

    IIC_SDA_H;
    IIC_SCL_H;
    }

    void INA_IIC_SDA_OUT(void) //SDA配置为输出
    {
    GPIO_InitTypeDef GPIO_INIT;
    GPIO_INIT.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_INIT.GPIO_Pin = IIC_SDA ;
    GPIO_INIT.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(IIC_PORT, &GPIO_INIT);
    }

    void INA_IIC_SDA_IN(void) //SDA配置为输入
    {
    GPIO_InitTypeDef GPIO_INIT;
    GPIO_INIT.GPIO_Mode = GPIO_Mode_IPU;
    GPIO_INIT.GPIO_Pin = IIC_SDA ;
    GPIO_INIT.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(IIC_PORT, &GPIO_INIT);
    }

    void INA_IIC_Start(void) //开始信号
    {
    IIC_SDA_H;
    IIC_SCL_H;
    INA_IIC_Delay();
    IIC_SDA_L;
    INA_IIC_Delay();
    IIC_SDA_L;
    }

    void INA_IIC_Stop(void) //结束信号
    {
    IIC_SDA_L;
    IIC_SCL_H;
    INA_IIC_Delay();
    IIC_SDA_H;
    INA_IIC_Delay();
    IIC_SCL_L;

    IIC_SCL_H;
    IIC_SDA_H;
    }

    bool INA_IIC_ACK_Read(void) //读取应答信号
    {
    bool ack;

    IIC_SDA_H;
    INA_IIC_SDA_IN();

    IIC_SCL_H;
    INA_IIC_Delay();
    if(IIC_SDA_READ() == SET) //读取iic-sda的电平信号,set为非零
    {
    ack = false;
    }
    else
    {
    ack = true;
    }
    IIC_SCL_L;
    INA_IIC_SDA_OUT();

    return ack;
    }

    void INA_IIC_ACK_Send(bool ack) //发送应答信号
    {
    IIC_SCL_L;
    if(ack == true)
    {
    IIC_SDA_L;
    }
    else
    {
    IIC_SDA_H;
    }
    IIC_SCL_H;
    INA_IIC_Delay();
    IIC_SCL_L;
    }

    void INA_IIC_Send_Byte(unsigned char byte) //IIC发送一位数据
    {
    unsigned char i;

    IIC_SCL_L; //SCL置为低电平
    for(i = 0; i < 8; i ++)
    {
    if(byte & 0x80 )
    {
    IIC_SDA_H;
    }
    else
    {
    IIC_SDA_L;
    }
    IIC_SCL_H;
    INA_IIC_Delay();
    IIC_SCL_L;
    INA_IIC_Delay();
    byte <<= 1;
    }
    INA_IIC_ACK_Read();
    }

    unsigned char INA_IIC_Read_Byte(void) //IIC读取一位数据
    {
    unsigned char i, byte = 0;

    INA_IIC_SDA_IN();
    for(i = 0; i < 8; i++)
    {
    IIC_SCL_H;
    byte <<= 1;
    if(IIC_SDA_READ() == SET)
    {
    byte |= 0x01;
    }
    else
    {
    byte &= 0xFE;
    }
    IIC_SCL_L;
    INA_IIC_Delay();
    }
    INA_IIC_SDA_OUT();

    return byte;
    }

    #endif

    void INA_Read_Byte_s(unsigned char reg, unsigned char *data) //读两位数据
    {
    INA_IIC_Start();
    INA_IIC_Send_Byte(INA219_ADDRESS); //发送INA219地址s
    INA_IIC_Send_Byte(reg);

    INA_IIC_Start();
    INA_IIC_Send_Byte(INA219_ADDRESS + 0x01); //设置iic为读模式
    *data = INA_IIC_Read_Byte();
    data ++;
    INA_IIC_ACK_Send(1);
    *data = INA_IIC_Read_Byte();
    INA_IIC_ACK_Send(0);
    INA_IIC_Stop();
    }

    void INA_REG_Write(unsigned char reg, unsigned int data) //写寄存器 测试成功
    {
    unsigned char data_temp[2];

    data_temp[0] = (unsigned char )(data >> 8); //高八位
    data_temp[1] = (unsigned char )(data & 0xFF); //低八位
    INA_IIC_Start();
    INA_IIC_Send_Byte(INA219_ADDRESS); //发送INA219地址
    INA_IIC_Send_Byte(reg); //发送寄存器地址
    INA_IIC_Send_Byte(data_temp[0]); //发送高8位数据
    data ++;
    INA_IIC_Send_Byte(data_temp[1]) ; //发送低8位数据
    INA_IIC_Stop();
    }

    void INA_Init(void )
    {
    INA_IIC_INIT(); //第一路iic初始化
    INA_IIC_INIT_2(); //第二路iic初始化

    INA_IIC_Delay();
    INA_REG_Write(INA219_REG_CONFIG,0x3c1f); //配置模式
    INA_REG_Write(INA219_REG_CALIBRATION,INA_CAL); //INA_CAL 4096
    }

    unsigned int INA_GET_Voltage_MV(void) //获取电压(单位:mv)
    {
    unsigned char data_temp[2];

    INA_REG_Write(INA219_REG_CONFIG, INA219_CONFIG_value);
    INA_Read_Byte_s(INA219_REG_BUSVOLTAGE, data_temp);
    return (int)((((data_temp[0] << 8) + data_temp[1]) >> 3) * 4); //右移3为去掉:bit2,CNVR,OVF三位,再乘以 4MV (官方文档规定),得到当前总线的电压值
    }

    unsigned int INA_GET_Current_MA(void) //获取电流(单位:mA)
    {
    unsigned char data_temp[2] = {0};

    INA_REG_Write(INA219_REG_CONFIG, INA219_CONFIG_value);
    INA_Read_Byte_s(INA219_REG_CURRENT, data_temp);

    return (int)((((data_temp[0] << 8) + data_temp[1])) * IAN_I_LSB); //得到寄存器的值在乘以每位对应的值(IAN_I_LSB)得到实际的电流
    }

    unsigned int INA_GET_ShuntVoltage_MV(void)
    {
     unsigned char data_temp[2];

     INA_REG_Write(INA219_REG_CONFIG, INA219_CONFIG_value);
     INA_Read_Byte_s(INA219_REG_SHUNTVOLTAGE, data_temp); 
     return (int)(((data_temp[0] << 8) + data_temp[1]));
    }

    unsigned int INA_GET_Power_MW(void) //获取当前功率(单位:mw)
    {
    unsigned char data_temp[2];

    INA_REG_Write(INA219_REG_CONFIG, INA219_CONFIG_value);
    INA_Read_Byte_s(INA219_REG_POWER, data_temp);

    return (int)(((data_temp[0] << 8) + data_temp[1]) * INA_Power_LSB); //得到寄存器的值在乘以每位对应的值(INA_Power_LSB)得到实际的功率
    }

    //////////////////////////////////////////////////////

    ina219.h

    #ifndef _INA219_H_
    #define _INA219_H_
    #include "stm32f10x.h"
    #include "stdbool.h"
    // I2C Address Options
    /*
    #define INA219_I2C_ADDRESS_CONF_0 (u8)(0x40 << 1) // A0 = GND, A1 = GND
    #define INA219_I2C_ADDRESS_CONF_1 (u8)(0x41 << 1) // A0 = VS+, A1 = GND
    #define INA219_I2C_ADDRESS_CONF_2 (u8)(0x42 << 1) // A0 = SDA, A1 = GND
    #define INA219_I2C_ADDRESS_CONF_3 (u8)(0x43 << 1) // A0 = SCL, A1 = GND
    #define INA219_I2C_ADDRESS_CONF_4 (u8)(0x44 << 1) // A0 = GND, A1 = VS+
    #define INA219_I2C_ADDRESS_CONF_5 (u8)(0x45 << 1) // A0 = VS+, A1 = VS+
    #define INA219_I2C_ADDRESS_CONF_6 (u8)(0x46 << 1) // A0 = SDA, A1 = VS+
    #define INA219_I2C_ADDRESS_CONF_7 (u8)(0x47 << 1) // A0 = SCL, A1 = VS+
    #define INA219_I2C_ADDRESS_CONF_8 (u8)(0x48 << 1) // A0 = GND, A1 = SDA
    #define INA219_I2C_ADDRESS_CONF_9 (u8)(0x49 << 1) // A0 = VS+, A1 = SDA
    #define INA219_I2C_ADDRESS_CONF_A (u8)(0x4A << 1) // A0 = SDA, A1 = SDA
    #define INA219_I2C_ADDRESS_CONF_B (u8)(0x4B << 1) // A0 = SCL, A1 = SDA
    #define INA219_I2C_ADDRESS_CONF_C (u8)(0x4C << 1) // A0 = GND, A1 = SCL
    #define INA219_I2C_ADDRESS_CONF_D (u8)(0x4D << 1) // A0 = VS+, A1 = SCL
    #define INA219_I2C_ADDRESS_CONF_E (u8)(0x4E << 1) // A0 = SDA, A1 = SCL
    #define INA219_I2C_ADDRESS_CONF_F (u8)(0x4F << 1) // A0 = SCL, A1 = SCL
    */
    #define INA219_ADDRESS (0x40 << 1) // A0 = GND, A1 = GND

    // 寄存器地址
    #define INA219_REG_CONFIG (u8)(0x00) // 模式配置寄存器 (R/W)
    #define INA219_REG_SHUNTVOLTAGE (u8)(0x01) // 分流电阻电压寄存器 (R)
    #define INA219_REG_BUSVOLTAGE (u8)(0x02) // 总线电压寄存器 (R)
    #define INA219_REG_POWER (u8)(0x03) // 功率寄存器 (R)
    #define INA219_REG_CURRENT (u8)(0x04) // 电流寄存器 (R)
    #define INA219_REG_CALIBRATION (u8)(0x05) // 基准值寄存器 (R/W)

    //寄存器(0x01)参数定义
    #define INA219_CONFIG_RESET (0x8000) // Reset Bit

    #define INA219_CONFIG_BVOLTAGERANGE_MASK (0x2000) // Bus Voltage Range Mask
    #define INA219_CONFIG_BVOLTAGERANGE_16V (0x0000) // 0-16V Range
    #define INA219_CONFIG_BVOLTAGERANGE_32V (0x2000) // 0-32V Range

    #define INA219_CONFIG_GAIN_MASK (0x1800) // Gain Mask
    #define INA219_CONFIG_GAIN_1_40MV (0x0000) // Gain 1, 40mV Range //配置检测电阻上的最大检测电压
    #define INA219_CONFIG_GAIN_2_80MV (0x0800) // Gain 2, 80mV Range
    #define INA219_CONFIG_GAIN_4_160MV (0x1000) // Gain 4, 160mV Range
    #define INA219_CONFIG_GAIN_8_320MV (0x1800) // Gain 8, 320mV Range

    #define INA219_CONFIG_BADCRES_MASK (0x0780) // Bus ADC Resolution Mask
    #define INA219_CONFIG_BADCRES_9BIT (0x0080) // 9-bit bus res = 0..511
    #define INA219_CONFIG_BADCRES_10BIT (0x0100) // 10-bit bus res = 0..1023
    #define INA219_CONFIG_BADCRES_11BIT (0x0200) // 11-bit bus res = 0..2047
    #define INA219_CONFIG_BADCRES_12BIT (0x0400) // 12-bit bus res = 0..4097

    #define INA219_CONFIG_SADCRES_MASK (0x0078) // Shunt ADC Resolution and Averaging Mask
    #define INA219_CONFIG_SADCRES_9BIT_1S_84US (0x0000) // 1 x 9-bit shunt sample
    #define INA219_CONFIG_SADCRES_10BIT_1S_148US (0x0008) // 1 x 10-bit shunt sample
    #define INA219_CONFIG_SADCRES_11BIT_1S_276US (0x0010) // 1 x 11-bit shunt sample
    #define INA219_CONFIG_SADCRES_12BIT_1S_532US (0x0018) // 1 x 12-bit shunt sample
    #define INA219_CONFIG_SADCRES_12BIT_2S_1060US (0x0048) // 2 x 12-bit shunt samples averaged together
    #define INA219_CONFIG_SADCRES_12BIT_4S_2130US (0x0050) // 4 x 12-bit shunt samples averaged together
    #define INA219_CONFIG_SADCRES_12BIT_8S_4260US (0x0058) // 8 x 12-bit shunt samples averaged together
    #define INA219_CONFIG_SADCRES_12BIT_16S_8510US (0x0060) // 16 x 12-bit shunt samples averaged together
    #define INA219_CONFIG_SADCRES_12BIT_32S_17MS (0x0068) // 32 x 12-bit shunt samples averaged together
    #define INA219_CONFIG_SADCRES_12BIT_64S_34MS (0x0070) // 64 x 12-bit shunt samples averaged together
    #define INA219_CONFIG_SADCRES_12BIT_128S_69MS (0x0078) // 128 x 12-bit shunt samples averaged together

    #define INA219_CONFIG_MODE_MASK (0x0007) // Operating Mode Mask
    #define INA219_CONFIG_MODE_POWERDOWN (0x0000)
    #define INA219_CONFIG_MODE_SVOLT_TRIGGERED (0x0001)
    #define INA219_CONFIG_MODE_BVOLT_TRIGGERED (0x0002)
    #define INA219_CONFIG_MODE_SANDBVOLT_TRIGGERED (0x0003)
    #define INA219_CONFIG_MODE_ADCOFF (0x0004)
    #define INA219_CONFIG_MODE_SVOLT_CONTINUOUS (0x0005)
    #define INA219_CONFIG_MODE_BVOLT_CONTINUOUS (0x0006)
    #define INA219_CONFIG_MODE_SANDBVOLT_CONTINUOUS (0x0007)
    //INA配置的参数
    #define INA_R 0.025 //阻值大小(单位ohm)
    #define INA_I_MAX 12 //硬件最大检测电流(单位:A) INA219_CONFIG_GAIN_电压/INA_R
    #define IAN_I_LSB 0.2 //(0x04)检测出值对应每位电流值 选择接近 = (INA_I_MAX/32767(2^15))*1000(为了得到单位为A) (A)
    #define INA_Power_LSB 8 //(0x03)检测出值对应每位功率值 = 12.8 * IAN_I_LSB (MW)
    #define INA_CAL 4096 //(0x05)寄存器基准值
    //根据上面定义设置 配置寄存器(0x00)的值:0x3C1F 0011 1100 0001 1111
    #define INA219_CONFIG_value INA219_CONFIG_BVOLTAGERANGE_32V|INA219_CONFIG_GAIN_8_320MV|INA219_CONFIG_BADCRES_12BIT|INA219_CONFIG_SADCRES_12BIT_1S_532US|INA219_CONFIG_MODE_SANDBVOLT_CONTINUOUS

    /*
    V_bus_max = 32
    V_shunt_max = 0.32
    R_shunt = 0.025
    MAXpossible_I = V_shunt_bus/R_shunt
    MAXpossible_I = 12.8
    MAX_Expected_I = 10
    MIN_LSB = MAX_Expected_I/32767
    MIN_LSB = 3.05e-4 = 0.000305(每位305uA)
    MAX_LSB = MAX_Expected_I/4096
    MAX_LSB = 24.4e-4 = 0.00244(每位2440uA)

    Current_LSB = 4e-4 = 0.0004(每位400uA)
    Cal = 4096
    Power_LSB = 20Current_LSB
    Power_LSB = 80e-4 = 0.008(每位8mW)
    Max_Current = Current_LSB*32767
    Max_Current = 13.11A
    If Max_Current ≥ Max Possible_I
    then
    Max_Current_Before_Overflow = MaxPossible_I
    Else
    Max_Current_Before_Overflow = Max_Current
    End If
    (Note that Max_Current is greater than MaxPossible_I in this example.)

    Max_Current_Before_Overflow = 12.8A

    Max_ShuntVoltage = Max_Current_Before_Overflow * R_shunt

    Max_ShuntVoltage = 0.32V

    If Max_ShuntVoltage >= V_shunt_max

    Max_ShuntVoltage_Before_Overflow = V_shunt_max
    Else
    Max_ShuntVoltage_Before_Overflow = Max_ShuntVoltage
    End If
    (Note that Max_ShuntVoltage is greater than V_shunt_max in this example.)

    Max_ShuntVoltage_Before_Overflow = 0.32

    MaximumPower = Max_Current_Before_Overflow * V_bus_max
    MaximumPower =12.8 *32 = 409.6

    INA219_Curren = 13.11
    MeaShuntCurrent =
    */

    #define INA_INSIDE_IIC //使用自带的io模拟iic
    #ifdef INA_INSIDE_IIC
    #define IIC_PORT GPIOB //IIC IO端口
    #define IIC_RCC RCC_APB2Periph_GPIOB //端口时钟
    #define IIC_SDA GPIO_Pin_7 //SDA引脚
    #define IIC_SDA_H GPIO_SetBits(IIC_PORT, IIC_SDA) //拉高SDA
    #define IIC_SDA_L GPIO_ResetBits(IIC_PORT, IIC_SDA) //拉低SDA
    #define IIC_SDA_READ() GPIO_ReadInputDataBit(GPIOB, IIC_SDA) //读取SDA

    #define IIC_SCL GPIO_Pin_6 //SCL引脚
    #define IIC_SCL_H GPIO_SetBits(IIC_PORT, IIC_SCL) //拉高SCL
    #define IIC_SCL_L GPIO_ResetBits(IIC_PORT, IIC_SCL) //拉低SCL
    #endif

    #endif

    void INA_Init(void);
    unsigned int INA_GET_Voltage_MV(void); //获取电压(单位:mv)
    unsigned int INA_GET_Current_MA(void); //获取电流(单位:mA)
    unsigned int INA_GET_Power_MW(void); //获取当前功率(单位:mw)

    void INA_REG_Write(unsigned char reg, unsigned int data);

    void INA_Read_Byte_s(unsigned char reg,unsigned char *data);

    void INA_IIC_Delay(void);
    void INA_IIC_SDA_OUT(void); //SDA配置为输出
    void INA_IIC_SDA_IN(void); //SDA配置为输入
    void INA_IIC_Start(void); //开始信号
    void INA_IIC_Stop(void);
    bool INA_IIC_ACK_Read(void);
    void INA_IIC_ACK_Send(bool ack);
    void INA_IIC_Send_Byte(unsigned char byte);
    unsigned char INA_IIC_Read_Byte(void);

    void INA_REG_Write(unsigned char reg, unsigned int data);

    unsigned int INA_GET_ShuntVoltage_MV(void);

    #endif

  • 您好,
    电路图没有显示出来,需“使用高级编辑器编辑文本”上传图片。
    您可以附出写入和读取寄存器的波形图吗,需要检查您的I2C通信是否有问题。