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

2024-05-05 22:12

本文主要是介绍ROS专栏—基于STM32F103的INA219电源数据采集,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、专栏介绍

这篇博客为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 0void 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);elseINA_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 valuesina219_current_LSB_uA = 100;     // Current LSB = 500uA per bitina219_power_LSB_mW = 2;        // Power LSB = 10mW per bit = 20 * Current LSB// Set Calibration register to 'Cal' calculated aboveina219_Write_Register(INA219_REG_CALIBRATION, ina219_calValue);// Set Config register to take into account the settings aboveconfigValue = ( 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 OVFreturn (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 stepina219_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 OVFval *= 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 stepina219_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 stepina219_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 Flagtypedef 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

这篇关于ROS专栏—基于STM32F103的INA219电源数据采集的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/962803

相关文章

大模型研发全揭秘:客服工单数据标注的完整攻略

在人工智能(AI)领域,数据标注是模型训练过程中至关重要的一步。无论你是新手还是有经验的从业者,掌握数据标注的技术细节和常见问题的解决方案都能为你的AI项目增添不少价值。在电信运营商的客服系统中,工单数据是客户问题和解决方案的重要记录。通过对这些工单数据进行有效标注,不仅能够帮助提升客服自动化系统的智能化水平,还能优化客户服务流程,提高客户满意度。本文将详细介绍如何在电信运营商客服工单的背景下进行

基于MySQL Binlog的Elasticsearch数据同步实践

一、为什么要做 随着马蜂窝的逐渐发展,我们的业务数据越来越多,单纯使用 MySQL 已经不能满足我们的数据查询需求,例如对于商品、订单等数据的多维度检索。 使用 Elasticsearch 存储业务数据可以很好的解决我们业务中的搜索需求。而数据进行异构存储后,随之而来的就是数据同步的问题。 二、现有方法及问题 对于数据同步,我们目前的解决方案是建立数据中间表。把需要检索的业务数据,统一放到一张M

关于数据埋点,你需要了解这些基本知识

产品汪每天都在和数据打交道,你知道数据来自哪里吗? 移动app端内的用户行为数据大多来自埋点,了解一些埋点知识,能和数据分析师、技术侃大山,参与到前期的数据采集,更重要是让最终的埋点数据能为我所用,否则可怜巴巴等上几个月是常有的事。   埋点类型 根据埋点方式,可以区分为: 手动埋点半自动埋点全自动埋点 秉承“任何事物都有两面性”的道理:自动程度高的,能解决通用统计,便于统一化管理,但个性化定

使用SecondaryNameNode恢复NameNode的数据

1)需求: NameNode进程挂了并且存储的数据也丢失了,如何恢复NameNode 此种方式恢复的数据可能存在小部分数据的丢失。 2)故障模拟 (1)kill -9 NameNode进程 [lytfly@hadoop102 current]$ kill -9 19886 (2)删除NameNode存储的数据(/opt/module/hadoop-3.1.4/data/tmp/dfs/na

异构存储(冷热数据分离)

异构存储主要解决不同的数据,存储在不同类型的硬盘中,达到最佳性能的问题。 异构存储Shell操作 (1)查看当前有哪些存储策略可以用 [lytfly@hadoop102 hadoop-3.1.4]$ hdfs storagepolicies -listPolicies (2)为指定路径(数据存储目录)设置指定的存储策略 hdfs storagepolicies -setStoragePo

Hadoop集群数据均衡之磁盘间数据均衡

生产环境,由于硬盘空间不足,往往需要增加一块硬盘。刚加载的硬盘没有数据时,可以执行磁盘数据均衡命令。(Hadoop3.x新特性) plan后面带的节点的名字必须是已经存在的,并且是需要均衡的节点。 如果节点不存在,会报如下错误: 如果节点只有一个硬盘的话,不会创建均衡计划: (1)生成均衡计划 hdfs diskbalancer -plan hadoop102 (2)执行均衡计划 hd

【Prometheus】PromQL向量匹配实现不同标签的向量数据进行运算

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全栈,前后端开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi

烟火目标检测数据集 7800张 烟火检测 带标注 voc yolo

一个包含7800张带标注图像的数据集,专门用于烟火目标检测,是一个非常有价值的资源,尤其对于那些致力于公共安全、事件管理和烟花表演监控等领域的人士而言。下面是对此数据集的一个详细介绍: 数据集名称:烟火目标检测数据集 数据集规模: 图片数量:7800张类别:主要包含烟火类目标,可能还包括其他相关类别,如烟火发射装置、背景等。格式:图像文件通常为JPEG或PNG格式;标注文件可能为X

pandas数据过滤

Pandas 数据过滤方法 Pandas 提供了多种方法来过滤数据,可以根据不同的条件进行筛选。以下是一些常见的 Pandas 数据过滤方法,结合实例进行讲解,希望能帮你快速理解。 1. 基于条件筛选行 可以使用布尔索引来根据条件过滤行。 import pandas as pd# 创建示例数据data = {'Name': ['Alice', 'Bob', 'Charlie', 'Dav

SWAP作物生长模型安装教程、数据制备、敏感性分析、气候变化影响、R模型敏感性分析与贝叶斯优化、Fortran源代码分析、气候数据降尺度与变化影响分析

查看原文>>>全流程SWAP农业模型数据制备、敏感性分析及气候变化影响实践技术应用 SWAP模型是由荷兰瓦赫宁根大学开发的先进农作物模型,它综合考虑了土壤-水分-大气以及植被间的相互作用;是一种描述作物生长过程的一种机理性作物生长模型。它不但运用Richard方程,使其能够精确的模拟土壤中水分的运动,而且耦合了WOFOST作物模型使作物的生长描述更为科学。 本文让更多的科研人员和农业工作者