ROS专栏—基于STM32F103的INA219电源数据采集

news2024/11/16 13:02:24

一、专栏介绍

这篇博客为ROS小车专栏第一篇,自己想要做一个ROS小车,同时通过CSDN平台记录我的制作过程,为后来者提供一些参考吧,恩我也是从零开始摸索,可能会有很多错误和问题,希望大家多多包涵。

二、本文内容

本文主要内容介绍如何通过STM32使用I2C接口通过INA219采集电池数据,主要包含功率、电压、电流等关键数据。

硬件是我自己设计的,我这边也会展示相应的硬件设计原理图,可以作为模块加入到自己的设计中,感兴趣的伙伴一起看下去吧!

三、硬件设计

硬件设计已经开源,文末会提供链接

硬件设计原理图(嘉立创)  

 PCB的3D图大概这个样子

 这个硬件设计已经经过实际测试了,没啥毛病,有需要的朋友可以直接拿过去用,INA219有两种封装,使用嘉立创的图给大家展示一下:SOT-23-8、SOIC-8

这两种封装区别不大,我都试过差不多,个人根据自己的选择即可。 

注意:A0\A1决定了INA219的地址,个人可以根据需求设计,手册上面很清晰

手册文末也会提供,直接减少搜索资料的麻烦

电源部分,我这里给到3.3V,因为一般都是配合单片机使用嘛,感觉3.3V也比较方便 

四、代码部分

代码网上有很多,这部分怎么说呢基本都一个样,也没必要重复造轮子。软件I2C,根据手册去操作对应寄存机就好了。个人感觉有时候代码可以直接复制,修修改改也就熟悉了这部分的具体操作,CV工程师就是我了,哈哈哈哈。

//这个头文件名字无所谓,我是临时使用一个工程改的,就这个名字吧,自己用可以改一下
#include "bsp_i2c_gpio.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;
 
u8 ram_for_ina219[60];
u8 INA219process_flag;

#define Open 1
#define Close 0
 
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\n",reg);
  unsigned char val[2];
  
  INA_IIC_Read_Bytes(reg, val, 2);
  *dat = ((unsigned int)(val[0]) << 8) + val[1];
  
    //printf("data1 == %x\r\n",val[0]);
    //printf("data2 == %x\r\n",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 = 0x0D90;  //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 = 100;     // Current LSB = 500uA per bit
  ina219_power_LSB_mW = 2;        // 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 delay_ms(vu32 m)
{
  u32 i;
  
  for(; m != 0; m--)	
       for (i=0; i<50000; i++);
}
void ina219_configureRegisters(void)
{
  delay_ms(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();
}


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);
}

这段代码网上很常见,我们需要做的就是从这段驱动代码中提取我们需要的部分也就是有效函数。我一般就是明确目标找到:初始化函数、数据获取函数,只要找到这两个就OK了!

观察上面的代码,我们主要需要下面几个函数:

1、void ina219_init(void)

初始化函数,函数内容主要是调用了其他两个函数:

ina219_gpio_init(); ina219_configureRegisters();,这两个函数感兴趣的可以继续进去看,我这边就不深究了。

2、数据获取函数

ina219_GetBusVoltage_mV();         ina219_GetShuntVoltage_uV();      
ina219_GetCurrent_uA();        ina219_GetPower_mW();

这几个函数我们直接进去看就知道大概怎么调用了。

接下来给大家补充一下.h文件

#ifndef __bsp_i2c_gpio_H
#define __bsp_i2c_gpio_H
#include "stm32f10x.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_rcc.h"

#define INA219_I2C_PORT                        GPIOB
#define INA219_I2C_GPIO_CLOCK            RCC_APB2Periph_GPIOB
#define INA219_I2C_SCL_PIN                GPIO_Pin_8
#define INA219_I2C_SDA_PIN                GPIO_Pin_9
 
#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

这个头文件里面有一个结构体,可以直接使用这个结构体去接上面获取到的数据:

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

这里给大家举个例子:

int main(void)
{
	ina219_init();
	
	while(1)
	{
		ina219_data.voltage_ina219 = ina219_GetBusVoltage_mV();
	}
}

注意:调试过程我发现了一个问题,就是数据获取得放在一个while循环里,并且不能加延时,目前还不清楚什么问题,如果加了延时会读不到数据,手册也没仔细研究,应该有什么原因的,不过这个代码我用在freertos里面的,目前是单独写了一个线程来读数据,等后面再修改。

调试结果:

2024年5月5日19:27:33

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1643934.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python 全栈系列241 GFGo Lite迭代

说明 随着整个算网开发逐渐深入&#xff0c;各个组件、微服务的数量、深度在不断增加。由于算网是个人项目&#xff0c;我一直按照MVP(Minimum Viable Product )的原则在推进。由于最初的时候对架构、算法和业务的理解并没有那么深刻&#xff0c;所以MVP的内容还是在不断变化&…

数据结构十:哈希表

本次将从概念上理解什么是哈希表&#xff0c;理论知识较多&#xff0c;满满干货&#xff0c;这也是面试笔试的一个重点区域。 目录 一、什么是哈希表 1.0 为什么会有哈希表&#xff1f; 1.1 哈希表的基本概念 1.2 基本思想 1.3 举例理解 1.4 存在的问题 1.5 总结 二、…

基于TL431基准电压源的可调恒压恒流源的Multisim电路仿真设计

1、线性电源的工作原理 在我们日常应用里&#xff0c;直流电是从市电或电网中的交流电获取的。例如15V直流电压源、24V直流电压源等等。交流电变为直流电的过程大概分为一下几步&#xff1a; 首先&#xff0c;交流电通过变压器降低其电压幅值。接着&#xff0c;经过整流电路进…

01_SpringBoot简单搭建入门程序

目录 1、先创建一个java项目2、导入依赖3、将Java项目修改为SpringBoot项目4、编写一个测试的Controller5、测试(创建一个*.http的文件)方式1&#xff1a;方式2&#xff1a;可以直接在浏览器访问该地址方式3&#xff1a;使用postman也可以 1、先创建一个java项目 我的项目结构…

智能化工单助力业务运作:亿发解析工单系统的功能与适用场景

在现代企业管理中&#xff0c;工单系统扮演着至关重要的角色。面对市面上众多的工单系统&#xff0c;我们可以根据不同的依据进行分类&#xff0c;以更好地满足企业的需求。 1、按部署方式分类&#xff1a; 按照部署方式可以分为本地化部署工单系统和云端SaaS服务工单系统。 …

步态识别论文(6)GaitDAN: Cross-view Gait Recognition via Adversarial Domain Adaptation

摘要: 视角变化导致步态外观存在显着差异。因此&#xff0c;识别跨视图场景中的步态是非常具有挑战性的。最近的方法要么在进行识别之前将步态从原始视图转换为目标视图&#xff0c;要么通过蛮力学习或解耦学习提取与相机视图无关的步态特征。然而&#xff0c;这些方法有许多约…

【java9】java9新特性之Optional类改进

其实Optional类在Java8中就引入了&#xff0c;用于避免null检查和NullPointerException指针问题。 在Java9中&#xff0c;Optional类得到了进一步的改进&#xff0c;增加了一些新的方法&#xff0c;使其更加灵活和易用。 以下是一些Java9中对Optional类的改进&#xff1a; s…

ssm106学生公寓管理系统的设计与实现+jsp

学生公寓管理系统设计与实现 摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本学生公寓管理系统就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短…

python数据分析——数据分析的统计推断

数据分析的统计推断 前言一、提出问题二、统计归纳方法三、统计推断四、统计推断步骤4.1.点估计4.2.区间估计4.2.1. 总体方差已知4.2.2总体方差未知 4.3. 假设检验4.4. 假设检验的假设4.5.显著性水平 五、检验统计量六、检验方法七、拒绝域八、假设检验步骤九、重要假设检验方法…

CGAL 网格简化

文章目录 一、简介二、实现代码三、实现效果参考资料一、简介 为了提高网格处理的效率,通常需要将过于冗长的3D数据集简化为更简洁而又真实的表示。尽管从几何压缩到逆向工程有许多应用,但简洁地捕捉表面的几何形状仍然是一项乏味的任务。CGAL中则为我们提供了一种通过变分几…

SpringBoot的ProblemDetails

1.RFC 7807 之前的项目如果出现异常&#xff0c;默认跳转到error页面。或者是抛出500 异常。 但是对于前后端分离的项目&#xff0c;Java程序员不负责页面跳转&#xff0c;只需要 把错误信息交给前端程序员处理即可。而RFC 7807规范就是将异常 信息转为JSON格式的数据。这个…

Golang | Leetcode Golang题解之第70题爬楼梯

题目&#xff1a; 题解&#xff1a; func climbStairs(n int) int {sqrt5 : math.Sqrt(5)pow1 : math.Pow((1sqrt5)/2, float64(n1))pow2 : math.Pow((1-sqrt5)/2, float64(n1))return int(math.Round((pow1 - pow2) / sqrt5)) }

5.Spring Security-web权限方案

设置登录的用户名和密码 1.通过配置文件设置用户名密码 spring:security:user:name: xiankejinpassword: 123456 如果没有以上配置&#xff0c;那么就会在后台生成一个随机密码&#xff0c;用户名固定位user。 2.通过配置类设置用户名密码 Configuration public class Sec…

[C++核心编程-02]----C++引用详解和使用方法分析

前言 在C中&#xff0c;引用是一个别名&#xff0c;它允许将一个已存在的变量或对象用不同的名称来访问。引用在定义时必须初始化&#xff0c;并且一旦初始化就不能再绑定其他对象&#xff0c;因此引用在声明时被初始化后就不能再改变引用对象。引用使用&符号进行声明。 引…

打印菱形

使用拆分法&#xff1a;空格和*分开打印 #include <stdio.h> int main() { int n 0; //行数 scanf("%d", &n); int i 0; //打印上半行 for (i 0; i < n; i) { int j 0; for (j 0; j < n - i - 1;…

玩comfyui踩过的坑之使用ComfyUI_Custom_NODES_ALEKPET翻译组件问题

环境&#xff1a; 秋叶安装包&#xff0c;安装ComfyUI_Custom_NODES_ALEKPET组件或者直接下载网盘中的包&#xff0c;直接解压包到comfyui根目录/custom_nodes/&#xff0c;重启后&#xff0c;按指导文件操作。 注意&#xff1a;网盘指导包中有配置好的流程json文件&#xff0…

【011】网上鲜花商店(SSM+JSP)

【011】网上鲜花商店(SSMJSP&#xff09; 一、系统情况介绍 网上鲜花商店分为前台端和后台端&#xff0c;是致力于可以便捷购花而开发的一套系统&#xff0c;可以按照不同种类进行分类管理&#xff0c;清晰客观的展示鲜花的详情信息以及价格等等&#xff0c;适合新手学习开发…

C++多态特性详解

目录 概念&#xff1a; 定义及实现&#xff1a; 虚函数重写的两个例外&#xff1a; 1.协变&#xff1a; 2.析构函数的重写&#xff1a; final关键字&#xff1a; override关键字&#xff1a; 多态是如何实现的&#xff08;底层&#xff09;&#xff1a; 面试题&#xff1…

代码审计之浅谈RASP技术

前言&#xff1a; 想摆会烂&#xff0c;所以就落个笔吧。 其实本来是想写关于iast技术的&#xff0c;但是认真思考了下&#xff0c;感觉笔者自己本身也不太能讲清楚iast技术&#xff0c;怕误人子弟。 所以最后还是基于笔者的理解以及实际应用写一篇关于RASP技术的文章&#xf…

酷我音乐无广VIP破姐版,支持蝰蛇音效,PC端 v9.2.0.0

01 软件介绍 酷我音乐是一款优质在线音乐播放服务软件&#xff0c;拥有全面的音乐版权库存&#xff0c;中国好声音、蒙面歌王、燃烧吧少年等热门综艺的版权&#xff0c;包括无损音质选项&#xff0c;并涵盖广泛多样的音乐类型&#xff0c;如华语、英语、粤语音乐&#xff0c;以…