Files
cls_master/lib/ina219/INA219.c

180 lines
4.8 KiB
C

/*
* INA219.c
*
* Created on: Dec 30, 2020
* Author: Piotr Smolen <komuch@gmail.com>
*/
#include "main.h"
#include "INA219.h"
uint16_t ina219_calibrationValue =0;
int16_t ina219_currentDivider_mA =0;
int16_t ina219_powerMultiplier_mW=0;
uint16_t Read16(INA219_t *ina219, uint8_t Register)
{
uint8_t Value[2] = {0};
HAL_I2C_Mem_Read(ina219->ina219_i2c, (ina219->Address<<1), Register, 1, Value, 2, 1000);
return ((Value[0] << 8) | Value[1]);
}
void Write16(INA219_t *ina219, uint8_t Register, uint16_t Value)
{
uint8_t addr[2];
addr[0] = (Value >> 8) & 0xff; // upper byte
addr[1] = (Value >> 0) & 0xff; // lower byte
HAL_I2C_Mem_Write(ina219->ina219_i2c, (ina219->Address<<1), Register, 1, (uint8_t*)addr, 2, 1000);
}
uint16_t INA219_ReadBusVoltage(INA219_t *ina219)
{
uint16_t result = Read16(ina219, INA219_REG_BUSVOLTAGE);
return ((result >> 3 ) * 4);
}
int16_t INA219_ReadCurrent_raw(INA219_t *ina219)
{
int16_t result = Read16(ina219, INA219_REG_CURRENT);
return (result );
}
int16_t INA219_ReadCurrent(INA219_t *ina219)
{
int16_t result = INA219_ReadCurrent_raw(ina219);
return (result / ina219_currentDivider_mA );
}
uint16_t INA219_ReadShuntVolage(INA219_t *ina219)
{
uint16_t result = Read16(ina219, INA219_REG_SHUNTVOLTAGE);
return (result * 0.01 );
}
void INA219_Reset(INA219_t *ina219)
{
Write16(ina219, INA219_REG_CONFIG, INA219_CONFIG_RESET);
HAL_Delay(1);
}
void INA219_setCalibration(INA219_t *ina219, uint16_t CalibrationData)
{
Write16(ina219, INA219_REG_CALIBRATION, CalibrationData);
}
uint16_t INA219_getConfig(INA219_t *ina219)
{
uint16_t result = Read16(ina219, INA219_REG_CONFIG);
return result;
}
void INA219_setConfig(INA219_t *ina219, uint16_t Config)
{
Write16(ina219, INA219_REG_CONFIG, Config);
}
void INA219_setCalibration_32V_2A(INA219_t *ina219)
{
uint16_t config = INA219_CONFIG_BVOLTAGERANGE_32V |
INA219_CONFIG_GAIN_8_320MV | INA219_CONFIG_BADCRES_12BIT |
INA219_CONFIG_SADCRES_12BIT_1S_532US |
INA219_CONFIG_MODE_SANDBVOLT_CONTINUOUS;
ina219_calibrationValue = 4096;
ina219_currentDivider_mA = 10; // Current LSB = 100uA per bit (1000/100 = 10)
ina219_powerMultiplier_mW = 2; // Power LSB = 1mW per bit (2/1)
INA219_setCalibration(ina219, ina219_calibrationValue);
INA219_setConfig(ina219, config);
}
void INA219_setCalibration_32V_1A(INA219_t *ina219)
{
uint16_t config = INA219_CONFIG_BVOLTAGERANGE_32V |
INA219_CONFIG_GAIN_8_320MV | INA219_CONFIG_BADCRES_12BIT |
INA219_CONFIG_SADCRES_12BIT_1S_532US |
INA219_CONFIG_MODE_SANDBVOLT_CONTINUOUS;
ina219_calibrationValue = 10240;
ina219_currentDivider_mA = 25; // Current LSB = 40uA per bit (1000/40 = 25)
ina219_powerMultiplier_mW = 0.8f; // Power LSB = 800uW per bit
INA219_setCalibration(ina219, ina219_calibrationValue);
INA219_setConfig(ina219, config);
}
void INA219_setCalibration_16V_400mA(INA219_t *ina219)
{
uint16_t config = INA219_CONFIG_BVOLTAGERANGE_16V |
INA219_CONFIG_GAIN_1_40MV | INA219_CONFIG_BADCRES_12BIT |
INA219_CONFIG_SADCRES_12BIT_1S_532US |
INA219_CONFIG_MODE_SANDBVOLT_CONTINUOUS;
ina219_calibrationValue = 8192;
ina219_currentDivider_mA = 20; // Current LSB = 50uA per bit (1000/50 = 20)
ina219_powerMultiplier_mW = 1.0f; // Power LSB = 1mW per bit
INA219_setCalibration(ina219, ina219_calibrationValue);
INA219_setConfig(ina219, config);
}
void INA219_setPowerMode(INA219_t *ina219, uint8_t Mode)
{
uint16_t config = INA219_getConfig(ina219);
switch (Mode) {
case INA219_CONFIG_MODE_POWERDOWN:
config = (config & ~INA219_CONFIG_MODE_MASK) | (INA219_CONFIG_MODE_POWERDOWN & INA219_CONFIG_MODE_MASK);
INA219_setConfig(ina219, config);
break;
case INA219_CONFIG_MODE_SANDBVOLT_TRIGGERED:
config = (config & ~INA219_CONFIG_MODE_MASK) | (INA219_CONFIG_MODE_SANDBVOLT_TRIGGERED & INA219_CONFIG_MODE_MASK);
INA219_setConfig(ina219, config);
break;
case INA219_CONFIG_MODE_SANDBVOLT_CONTINUOUS:
config = (config & ~INA219_CONFIG_MODE_MASK) | (INA219_CONFIG_MODE_SANDBVOLT_CONTINUOUS & INA219_CONFIG_MODE_MASK);
INA219_setConfig(ina219, config);
break;
case INA219_CONFIG_MODE_ADCOFF:
config = (config & ~INA219_CONFIG_MODE_MASK) | (INA219_CONFIG_MODE_ADCOFF & INA219_CONFIG_MODE_MASK);
INA219_setConfig(ina219, config);
break;
}
}
uint8_t INA219_Init(INA219_t *ina219, I2C_HandleTypeDef *i2c, uint8_t Address)
{
ina219->ina219_i2c = i2c;
ina219->Address = Address;
ina219_currentDivider_mA = 0;
ina219_powerMultiplier_mW = 0;
uint8_t ina219_isReady = HAL_I2C_IsDeviceReady(i2c, (Address << 1), 3, 2);
if(ina219_isReady == HAL_OK)
{
INA219_Reset(ina219);
INA219_setCalibration_32V_2A(ina219);
return 1;
}
else
{
return 0;
}
}