一、专栏介绍
这篇博客为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, ®);
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, ®);
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, ®);
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