INA219 드라이브, STM32 기반(STM8 마이그레이션 사용 가능)

49645 단어
이전에 전량계를 만들어야 했는데 INA219전류검측칩을 사용했다. 인터넷 대신의 코드를 참고한 후에 STM32에서 사용할 수 있는 것을 발견했다. STM8에 이식한 후에 사용할 수 없는 것을 발견했다. 나중에 공식적인 예시 demo를 찾았다. 인터넷 대신코드를 종합하여 디버깅한 후에 성공적으로 구동했고 전류, 전압, 출력을 측정했고 정확도가 높았다.
지금 공유해서 참고하시고 코드를 직접 붙이세요.
main.c
int main(void)
{
    ina219_init();
   
    while(1)
   {  
        //                 
   }  
}

 
 ina219.c
#include "ina219.h"

u8  ina219_busVolt_LSB_mV = 4;   // Bus Voltage LSB value = 4mV
u8  ina219_shuntVolt_LSB_uV = 10;  // Shunt Voltage LSB value = 10uV
unsigned short ina219_calValue = 0;

u32 ina219_current_LSB_uA;
u32 ina219_power_LSB_mW;

INA219_DATA ina219_data;

void INA_SCL_OUT(void)
{
    GPIO_InitTypeDef  GPIO_InitStructure;

    RCC_APB2PeriphClockCmd(INA219_I2C_GPIO_CLOCK, ENABLE);
    
    /* Configure I2C1 pins: PB12->SCL->OUT */
    GPIO_InitStructure.GPIO_Pin = INA219_I2C_SCL_PIN;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_Init(INA219_I2C_PORT, &GPIO_InitStructure);
    GPIO_SetBits(INA219_I2C_PORT, INA219_I2C_SCL_PIN);
}

void INA_SDA_OUT(void)
{
    GPIO_InitTypeDef  GPIO_InitStructure;

    RCC_APB2PeriphClockCmd(INA219_I2C_GPIO_CLOCK, ENABLE);
    
    /* Configure I2C1 pins: PB14->SDA-OUT */
    GPIO_InitStructure.GPIO_Pin = INA219_I2C_SDA_PIN;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_Init(INA219_I2C_PORT, &GPIO_InitStructure);
    GPIO_SetBits(INA219_I2C_PORT, INA219_I2C_SDA_PIN);
}

void INA_SDA_IN(void)
{
    GPIO_InitTypeDef  GPIO_InitStructure;

    RCC_APB2PeriphClockCmd(INA219_I2C_GPIO_CLOCK, ENABLE);
    
    /* Configure I2C1 pins: PB14->SDA-IN */
    GPIO_InitStructure.GPIO_Pin = INA219_I2C_SDA_PIN;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
    GPIO_Init(INA219_I2C_PORT, &GPIO_InitStructure);
}

void INA_IIC_Start(void)
{
  INA_SDA_OUT();
  INA_SCL_OUT();
  
  INA_SDA_SET;
  INA_SCL_SET;
  INA_SDA_CLR;
  INA_SCL_CLR;
}

void INA_IIC_Stop(void)
{
    INA_SDA_OUT();

    INA_SDA_CLR;
    INA_SCL_SET;
    INA_SDA_SET;
}

void INA_IIC_Set_Ack(unsigned char ack)
{
    INA_SDA_OUT();
    
    if(ack)
    {
      INA_SDA_SET;
    }
    else
    {
      INA_SDA_CLR;
    }
    
    INA_SCL_SET;
    INA_SCL_CLR;
}

unsigned char INA_IIC_Get_Ack(void)
{
    unsigned char ack;

    INA_SDA_IN();
    INA_SDA_SET;
    INA_SCL_SET;
    if(INA_SDA_TST)
    {
      ack = 1;
    }
    else
    {
      ack = 0;
    }
    
    INA_SCL_CLR;

    return(ack);
}

void INA_IIC_Write_8bits(unsigned char dat)
{
  unsigned char i;
  
  INA_SDA_OUT();
  for(i = 8; i; i--)
  {
    if(dat & 0x80)
    {
      INA_SDA_SET;
    }
    else
    {
      INA_SDA_CLR;
    }
    
    INA_SCL_SET;
    dat <<= 1;
    INA_SCL_CLR;
  }
}

unsigned char INA_IIC_Read_8bits(void)
{
    unsigned char i, dat;

    INA_SDA_IN();
    INA_SDA_SET;
    dat = 0;
    for(i = 8; i; i--)
    {
        INA_SCL_SET;
        dat <<= 1;
        if(INA_SDA_TST)
          dat++;
        INA_SCL_CLR;
    }
    
    return(dat);
}

void INA_IIC_Write_Byte(unsigned char reg, unsigned char dat)
{
  unsigned char dev = INA219_I2C_ADDRESS;
  
  INA_IIC_Start();
  
  //  dev &= ~0x01;
  INA_IIC_Write_8bits(dev);
  INA_IIC_Get_Ack();
  
  INA_IIC_Write_8bits(reg);
  INA_IIC_Get_Ack();
  
  INA_IIC_Write_8bits(dat);
  INA_IIC_Get_Ack();
  
  INA_IIC_Stop();
}

unsigned char INA_IIC_Read_Byte(unsigned char reg)
{
  unsigned char dat;
  unsigned char dev = INA219_I2C_ADDRESS;
  
  INA_IIC_Start();
  
  //  dev &= ~0x01;
  INA_IIC_Write_8bits(dev);
  INA_IIC_Get_Ack();
  
  INA_IIC_Write_8bits(reg);
  INA_IIC_Get_Ack();
  
  INA_IIC_Start();
  
  dev |= 0x01;
  INA_IIC_Write_8bits(dev);
  INA_IIC_Get_Ack();
  
  dat = INA_IIC_Read_8bits();
  INA_IIC_Set_Ack(1);
  
  INA_IIC_Stop();
  
  return (dat);
}

void INA_IIC_Write_Bytes(unsigned char reg, unsigned char *dat, unsigned char num)
{
  unsigned char dev = INA219_I2C_ADDRESS;
  
  INA_IIC_Start();
  
  //  dev &= ~0x01;
  INA_IIC_Write_8bits(dev);
  INA_IIC_Get_Ack();
  
  INA_IIC_Write_8bits(reg);
  INA_IIC_Get_Ack();
  
  while(num--)
  {
    INA_IIC_Write_8bits(*dat);
    INA_IIC_Get_Ack();
    dat++;
  }
  
  INA_IIC_Stop();
}

void INA_IIC_Read_Bytes(unsigned char reg, unsigned char *dat, unsigned char num)
{
  unsigned char *tmp = dat;
  unsigned char dev = INA219_I2C_ADDRESS;
  
  INA_IIC_Start();
  
  //  dev &= ~0x01;
  INA_IIC_Write_8bits(dev);
  INA_IIC_Get_Ack();
  
  INA_IIC_Write_8bits(reg);
  INA_IIC_Get_Ack();
  
  INA_IIC_Start();
  
  dev |= 0x01;
  INA_IIC_Write_8bits(dev);
  INA_IIC_Get_Ack();
  
  while(num--)
  {
    *tmp = INA_IIC_Read_8bits();
    if(num == 0)
      INA_IIC_Set_Ack(1);
    else
      INA_IIC_Set_Ack(0);
    tmp++;
  }
  
  INA_IIC_Stop();
}

void ina219_Write_Register(unsigned char reg, unsigned int dat)
{
    unsigned char val[2];
    
    val[0] = (unsigned char)(dat >> 8);
    val[1] = (unsigned char)(dat & 0xFF);
    INA_IIC_Write_Bytes(reg, val, 2);
}

void ina219_Read_Register(unsigned char reg, signed short *dat)
{
    //printf("read reg == %d\r
",reg);
unsigned char val[2]; INA_IIC_Read_Bytes(reg, val, 2); *dat = ((unsigned int)(val[0]) << 8) + val[1]; //printf("data1 == %x\r
",val[0]);
//printf("data2 == %x\r
",val[1]);
} // INA219 Set Calibration 16V/16A(Max) 0.02¦¸ void ina219_SetCalibration_16V_16A(void) { u16 configValue; // By default we use a pretty huge range for the input voltage, // which probably isn't the most appropriate choice for system // that don't use a lot of power. But all of the calculations // are shown below if you want to change the settings. You will // also need to change any relevant register settings, such as // setting the VBUS_MAX to 16V instead of 32V, etc. // VBUS_MAX = 16V (Assumes 16V, can also be set to 32V) // VSHUNT_MAX = 0.32 (Assumes Gain 8, 320mV, can also be 0.16, 0.08, 0.04) // RSHUNT = 0.02 (Resistor value in ohms) // 1. Determine max possible current // MaxPossible_I = VSHUNT_MAX / RSHUNT // MaxPossible_I = 16A // 2. Determine max expected current // MaxExpected_I = 16A // 3. Calculate possible range of LSBs (Min = 15-bit, Max = 12-bit) // MinimumLSB = MaxExpected_I/32767 // MinimumLSB = 0.00048 (0.48mA per bit) // MaximumLSB = MaxExpected_I/4096 // MaximumLSB = 0,00390 (3.9mA per bit) // 4. Choose an LSB between the min and max values // (Preferrably a roundish number close to MinLSB) // CurrentLSB = 0.00050 (500uA per bit) // 5. Compute the calibration register // Cal = trunc (0.04096 / (Current_LSB * RSHUNT)) // Cal = 4096 (0x1000) ina219_calValue = 0x1000; // 6. Calculate the power LSB // PowerLSB = 20 * CurrentLSB // PowerLSB = 0.01 (10mW per bit) // 7. Compute the maximum current and shunt voltage values before overflow // // Max_Current = Current_LSB * 32767 // Max_Current = 16.3835A before overflow // // If Max_Current > Max_Possible_I then // Max_Current_Before_Overflow = MaxPossible_I // Else // Max_Current_Before_Overflow = Max_Current // End If // // Max_ShuntVoltage = Max_Current_Before_Overflow * RSHUNT // Max_ShuntVoltage = 0.32V // // If Max_ShuntVoltage >= VSHUNT_MAX // Max_ShuntVoltage_Before_Overflow = VSHUNT_MAX // Else // Max_ShuntVoltage_Before_Overflow = Max_ShuntVoltage // End If // 8. Compute the Maximum Power // MaximumPower = Max_Current_Before_Overflow * VBUS_MAX // MaximumPower = 1.6 * 16V // MaximumPower = 256W // Set multipliers to convert raw current/power values ina219_current_LSB_uA = 500; // Current LSB = 500uA per bit ina219_power_LSB_mW = 10; // Power LSB = 10mW per bit = 20 * Current LSB // Set Calibration register to 'Cal' calculated above ina219_Write_Register(INA219_REG_CALIBRATION, ina219_calValue); // Set Config register to take into account the settings above configValue = ( INA219_CFG_BVOLT_RANGE_16V | INA219_CFG_SVOLT_RANGE_320MV | INA219_CFG_BADCRES_12BIT_16S_8MS | INA219_CFG_SADCRES_12BIT_16S_8MS | INA219_CFG_MODE_SANDBVOLT_CONTINUOUS ); ina219_Write_Register(INA219_REG_CONFIG, configValue); } void ina219_configureRegisters(void) { DelayMs(15); ina219_SetCalibration_16V_16A(); } void ina219_gpio_init(void) { INA_SCL_OUT(); INA_SDA_OUT(); } void ina219_init(void) { ina219_gpio_init(); ina219_configureRegisters(); } /* ÕâÀïÒÔÉÏÊdzõʼ»¯º¯Êý */ /* ´ÓÕâÀïÍùÏÂÊǹ¦Äܺ¯Êý */ signed short ina219_GetBusVoltage_raw(void) { signed short val; ina219_Read_Register(INA219_REG_BUSVOLTAGE, &val); val >>= 3; // Shift to the right 3 to drop CNVR and OVF return (val); } signed short ina219_GetCurrent_raw(void) { signed short val; // Sometimes a sharp load will reset the INA219, which will // reset the cal register, meaning CURRENT and POWER will // not be available ... avoid this by always setting a cal // value even if it's an unfortunate extra step ina219_Write_Register(INA219_REG_CALIBRATION, ina219_calValue); // Now we can safely read the CURRENT register! ina219_Read_Register(INA219_REG_CURRENT, &val); return (val); } signed short ina219_GetBusVoltage_mV(void) { signed short val; ina219_Read_Register(INA219_REG_BUSVOLTAGE, &val); val >>= 3; // Shift to the right 3 to drop CNVR and OVF val *= ina219_busVolt_LSB_mV; // multiply by LSB(4mV) return (val); } s32 ina219_GetShuntVoltage_uV(void) { s32 val; s16 reg; ina219_Read_Register(INA219_REG_SHUNTVOLTAGE, &reg); val = (s32)reg * ina219_shuntVolt_LSB_uV; // multiply by LSB(10uV) return (val); } s32 ina219_GetCurrent_uA(void) { s32 val; s16 reg; // Sometimes a sharp load will reset the INA219, which will // reset the cal register, meaning CURRENT and POWER will // not be available ... avoid this by always setting a cal // value even if it's an unfortunate extra step ina219_Write_Register(INA219_REG_CALIBRATION, ina219_calValue); // Now we can safely read the CURRENT register! ina219_Read_Register(INA219_REG_CURRENT, &reg); val = (s32)reg * ina219_current_LSB_uA; return (val); } s32 ina219_GetPower_mW(void) { s32 val; s16 reg; // Sometimes a sharp load will reset the INA219, which will // reset the cal register, meaning CURRENT and POWER will // not be available ... avoid this by always setting a cal // value even if it's an unfortunate extra step ina219_Write_Register(INA219_REG_CALIBRATION, ina219_calValue); // Now we can safely read the POWER register! ina219_Read_Register(INA219_REG_POWER, &reg); val = (s32)reg * ina219_power_LSB_mW; return (val); } void INA_Process(void) { if(INA219process_flag == Open) { INA219process_flag = Close; ina219_data.voltage_ina219 = ina219_GetBusVoltage_mV(); printf("voltage_ina219 is %d\r
",ina219_data.voltage_ina219); ina219_data.shunt_ina219 = ina219_GetShuntVoltage_uV(); printf("shunt_ina219 is %ld\r
",ina219_data.shunt_ina219); ina219_data.current_ina219 = ina219_GetCurrent_uA(); printf("current_ina219 is %ld\r
",ina219_data.current_ina219); ina219_data.power_ina219 = ina219_GetPower_mW(); printf("power_ina219 is %ld\r
",ina219_data.power_ina219); } }

 
ina219.h
#ifndef __INA219_H
#define __INA219_H
#include "main.h"

#define INA219_I2C_PORT                        GPIOB
#define INA219_I2C_GPIO_CLOCK            RCC_APB2Periph_GPIOB
#define INA219_I2C_SCL_PIN                GPIO_Pin_12
#define INA219_I2C_SDA_PIN                GPIO_Pin_14

#define INA_SCL_SET     GPIO_SetBits(INA219_I2C_PORT,INA219_I2C_SCL_PIN)
#define INA_SDA_SET     GPIO_SetBits(INA219_I2C_PORT, INA219_I2C_SDA_PIN)

#define INA_SCL_CLR     GPIO_ResetBits(INA219_I2C_PORT,INA219_I2C_SCL_PIN)
#define INA_SDA_CLR     GPIO_ResetBits(INA219_I2C_PORT,INA219_I2C_SDA_PIN)

#define INA_SDA_TST     GPIO_ReadInputDataBit(INA219_I2C_PORT,INA219_I2C_SDA_PIN)

/*----------------------------------------------------------------------------*/
// 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_I2C_ADDRESS                      INA219_I2C_ADDRESS_CONF_0


/*----------------------------------------------------------------------------*/
// Register Addresses
#define INA219_REG_CONFIG                       (u8)(0x00)      // CONFIG REGISTER (R/W)
#define INA219_REG_SHUNTVOLTAGE                 (u8)(0x01)      // SHUNT VOLTAGE REGISTER (R)
#define INA219_REG_BUSVOLTAGE                   (u8)(0x02)      // BUS VOLTAGE REGISTER (R)
#define INA219_REG_POWER                        (u8)(0x03)      // POWER REGISTER (R)
#define INA219_REG_CURRENT                      (u8)(0x04)      // CURRENT REGISTER (R)
#define INA219_REG_CALIBRATION                  (u8)(0x05)      // CALIBRATION REGISTER (R/W)


/*----------------------------------------------------------------------------*/
// Macros for assigning config bits
#define INA219_CFGB_RESET(x)                    (u16)((x & 0x01) << 15)     // Reset Bit
#define INA219_CFGB_BUSV_RANGE(x)               (u16)((x & 0x01) << 13)     // Bus Voltage Range
#define INA219_CFGB_PGA_RANGE(x)                (u16)((x & 0x03) << 11)     // Shunt Voltage Range
#define INA219_CFGB_BADC_RES_AVG(x)             (u16)((x & 0x0F) << 7)      // Bus ADC Resolution/Averaging
#define INA219_CFGB_SADC_RES_AVG(x)             (u16)((x & 0x0F) << 3)      // Shunt ADC Resolution/Averaging
#define INA219_CFGB_MODE(x)                     (u16) (x & 0x07)            // Operating Mode


/*----------------------------------------------------------------------------*/
// Configuration Register
#define INA219_CFG_RESET                        INA219_CFGB_RESET(1)            // Reset Bit

#define INA219_CFG_BVOLT_RANGE_MASK             INA219_CFGB_BUSV_RANGE(1)       // Bus Voltage Range Mask
#define INA219_CFG_BVOLT_RANGE_16V              INA219_CFGB_BUSV_RANGE(0)       // 0-16V Range
#define INA219_CFG_BVOLT_RANGE_32V              INA219_CFGB_BUSV_RANGE(1)       // 0-32V Range (default)

#define INA219_CFG_SVOLT_RANGE_MASK             INA219_CFGB_PGA_RANGE(3)        // Shunt Voltage Range Mask
#define INA219_CFG_SVOLT_RANGE_40MV             INA219_CFGB_PGA_RANGE(0)        // Gain 1, 40mV Range
#define INA219_CFG_SVOLT_RANGE_80MV             INA219_CFGB_PGA_RANGE(1)        // Gain 2, 80mV Range
#define INA219_CFG_SVOLT_RANGE_160MV            INA219_CFGB_PGA_RANGE(2)        // Gain 4, 160mV Range
#define INA219_CFG_SVOLT_RANGE_320MV            INA219_CFGB_PGA_RANGE(3)        // Gain 8, 320mV Range (default)

#define INA219_CFG_BADCRES_MASK                 INA219_CFGB_BADC_RES_AVG(15)    // Bus ADC Resolution and Averaging Mask
#define INA219_CFG_BADCRES_9BIT_1S_84US         INA219_CFGB_BADC_RES_AVG(0)     // 1 x 9-bit Bus sample
#define INA219_CFG_BADCRES_10BIT_1S_148US       INA219_CFGB_BADC_RES_AVG(1)     // 1 x 10-bit Bus sample
#define INA219_CFG_BADCRES_11BIT_1S_276US       INA219_CFGB_BADC_RES_AVG(2)     // 1 x 11-bit Bus sample
#define INA219_CFG_BADCRES_12BIT_1S_532US       INA219_CFGB_BADC_RES_AVG(3)     // 1 x 12-bit Bus sample (default)
#define INA219_CFG_BADCRES_12BIT_2S_1MS         INA219_CFGB_BADC_RES_AVG(9)     // 2 x 12-bit Bus samples averaged together
#define INA219_CFG_BADCRES_12BIT_4S_2MS         INA219_CFGB_BADC_RES_AVG(10)    // 4 x 12-bit Bus samples averaged together
#define INA219_CFG_BADCRES_12BIT_8S_4MS         INA219_CFGB_BADC_RES_AVG(11)    // 8 x 12-bit Bus samples averaged together
#define INA219_CFG_BADCRES_12BIT_16S_8MS        INA219_CFGB_BADC_RES_AVG(12)    // 16 x 12-bit Bus samples averaged together
#define INA219_CFG_BADCRES_12BIT_32S_17MS       INA219_CFGB_BADC_RES_AVG(13)    // 32 x 12-bit Bus samples averaged together
#define INA219_CFG_BADCRES_12BIT_64S_34MS       INA219_CFGB_BADC_RES_AVG(14)    // 64 x 12-bit Bus samples averaged together
#define INA219_CFG_BADCRES_12BIT_128S_68MS      INA219_CFGB_BADC_RES_AVG(15)    // 128 x 12-bit Bus samples averaged together

#define INA219_CFG_SADCRES_MASK                 INA219_CFGB_SADC_RES_AVG(15)    // Shunt ADC Resolution and Averaging Mask
#define INA219_CFG_SADCRES_9BIT_1S_84US         INA219_CFGB_SADC_RES_AVG(0)     // 1 x 9-bit Shunt sample
#define INA219_CFG_SADCRES_10BIT_1S_148US       INA219_CFGB_SADC_RES_AVG(1)     // 1 x 10-bit Shunt sample
#define INA219_CFG_SADCRES_11BIT_1S_276US       INA219_CFGB_SADC_RES_AVG(2)     // 1 x 11-bit Shunt sample
#define INA219_CFG_SADCRES_12BIT_1S_532US       INA219_CFGB_SADC_RES_AVG(3)     // 1 x 12-bit Shunt sample (default)
#define INA219_CFG_SADCRES_12BIT_2S_1MS         INA219_CFGB_SADC_RES_AVG(9)     // 2 x 12-bit Shunt samples averaged together
#define INA219_CFG_SADCRES_12BIT_4S_2MS         INA219_CFGB_SADC_RES_AVG(10)    // 4 x 12-bit Shunt samples averaged together
#define INA219_CFG_SADCRES_12BIT_8S_4MS         INA219_CFGB_SADC_RES_AVG(11)    // 8 x 12-bit Shunt samples averaged together
#define INA219_CFG_SADCRES_12BIT_16S_8MS        INA219_CFGB_SADC_RES_AVG(12)    // 16 x 12-bit Shunt samples averaged together
#define INA219_CFG_SADCRES_12BIT_32S_17MS       INA219_CFGB_SADC_RES_AVG(13)    // 32 x 12-bit Shunt samples averaged together
#define INA219_CFG_SADCRES_12BIT_64S_34MS       INA219_CFGB_SADC_RES_AVG(14)    // 64 x 12-bit Shunt samples averaged together
#define INA219_CFG_SADCRES_12BIT_128S_68MS      INA219_CFGB_SADC_RES_AVG(15)    // 128 x 12-bit Shunt samples averaged together

#define INA219_CFG_MODE_MASK                    INA219_CFGB_MODE(7)             // Operating Mode Mask
#define INA219_CFG_MODE_POWERDOWN               INA219_CFGB_MODE(0)             // Power-Down
#define INA219_CFG_MODE_SVOLT_TRIGGERED         INA219_CFGB_MODE(1)             // Shunt Voltage, Triggered
#define INA219_CFG_MODE_BVOLT_TRIGGERED         INA219_CFGB_MODE(2)             // Bus Voltage, Triggered
#define INA219_CFG_MODE_SANDBVOLT_TRIGGERED     INA219_CFGB_MODE(3)             // Shunt and Bus, Triggered
#define INA219_CFG_MODE_ADCOFF                  INA219_CFGB_MODE(4)             // ADC Off (disabled)
#define INA219_CFG_MODE_SVOLT_CONTINUOUS        INA219_CFGB_MODE(5)             // Shunt Voltage, Continuous
#define INA219_CFG_MODE_BVOLT_CONTINUOUS        INA219_CFGB_MODE(6)             // Bus Voltage, Continuous
#define INA219_CFG_MODE_SANDBVOLT_CONTINUOUS    INA219_CFGB_MODE(7)             // Shunt and Bus, Continuous (default)


/*----------------------------------------------------------------------------*/
// Bus Voltage Register
#define INA219_BVOLT_CNVR                       (u16)(0x0002)       // Conversion Ready
#define INA219_BVOLT_OVF                        (u16)(0x0001)       // Math Overflow Flag

typedef struct
{
  signed short voltage_ina219;
  signed long shunt_ina219;
  signed long current_ina219;
  signed long power_ina219;
}INA219_DATA;


extern u8  ina219_busVolt_LSB_mV;
extern u8  ina219_shuntVolt_LSB_uV;
extern unsigned short ina219_calValue;

extern u32 ina219_current_LSB_uA;
extern u32 ina219_power_LSB_mW;

extern void ina219_init(void);
extern void INA_Process(void);
extern signed short ina219_GetBusVoltage_raw(void);
extern signed short ina219_GetCurrent_raw(void);
extern signed short ina219_GetBusVoltage_mV(void);
extern s32 ina219_GetShuntVoltage_uV(void);
extern s32 ina219_GetCurrent_uA(void);
extern s32 ina219_GetPower_mW(void);

#endif

드라이버를 쓴 지 한동안 기억이 잘 안 나는데, 다른 사람을 오도하지 않도록 코드를 설명하지 않겠습니다.공식 구동 코드에는 상세한 주석이 있는데, 여기에는 여전히 남아 있다.
샘플링 저항에 따라 설정값이 다르기 때문에 레지스터의 구체적인 계산 방법 매뉴얼에 명확하게 적혀 있다.
 
전재 대상:https://www.cnblogs.com/fly2199/p/8460817.html

좋은 웹페이지 즐겨찾기