#include "INA226.h"
#include "stm32f10x.h"
#include "iic2.h"
#include "delay.h"
#include "math.h"
#include "usart1.h"
#include "control.h"
float currentLSB, powerLSB;
float vShuntMax, vBusMax, rShunt;
//config默认0x4127
void Init_INA226(void)
{
INA226_configure(INA226_ADDRESS1, INA226_AVERAGES_1, INA226_BUS_CONV_TIME_1100US, INA226_SHUNT_CONV_TIME_1100US, INA226_MODE_SHUNT_BUS_CONT);
INA226_calibrate(INA226_ADDRESS1, INA226_Rshunt,10); //校准电流
INA226_setMaskEnable_h(INA226_ADDRESS1); //上限
INA226_setBusVoltageLimit(INA226_ADDRESS1,Save_OverV_H_P1_VBUS);
INA226_configure(INA226_ADDRESS2, INA226_AVERAGES_1, INA226_BUS_CONV_TIME_1100US, INA226_SHUNT_CONV_TIME_1100US, INA226_MODE_SHUNT_BUS_CONT);
INA226_calibrate(INA226_ADDRESS2, INA226_Rshunt,10);
INA226_setMaskEnable_h(INA226_ADDRESS2);
INA226_setBusVoltageLimit(INA226_ADDRESS2,Save_OverV_H_P1_VBAT);
}
//============================================================================================================
void INA226_VBUSLowLimit(void)
{
INA226_configure(INA226_ADDRESS1, INA226_AVERAGES_1, INA226_BUS_CONV_TIME_1100US, INA226_SHUNT_CONV_TIME_1100US, INA226_MODE_SHUNT_BUS_CONT);
INA226_calibrate(INA226_ADDRESS1, INA226_Rshunt,10);
INA226_setMaskEnable_l(INA226_ADDRESS1); //下限
INA226_setBusVoltageLimit(INA226_ADDRESS1,Save_OverV_L_P1_VBUS);
}
void INA226_VBUSHighLimit(void)
{
INA226_configure(INA226_ADDRESS1, INA226_AVERAGES_1, INA226_BUS_CONV_TIME_1100US, INA226_SHUNT_CONV_TIME_1100US, INA226_MODE_SHUNT_BUS_CONT);
INA226_calibrate(INA226_ADDRESS1, INA226_Rshunt,10);
INA226_setMaskEnable_h(INA226_ADDRESS1); //上限
INA226_setBusVoltageLimit(INA226_ADDRESS1,Save_OverV_H_P1_VBUS);
}
void INA226_VBATLowLimit(void)
{
INA226_configure(INA226_ADDRESS2, INA226_AVERAGES_1, INA226_BUS_CONV_TIME_1100US, INA226_SHUNT_CONV_TIME_1100US, INA226_MODE_SHUNT_BUS_CONT);
INA226_calibrate(INA226_ADDRESS2, INA226_Rshunt,10);
INA226_setMaskEnable_l(INA226_ADDRESS2); //下限
INA226_setBusVoltageLimit(INA226_ADDRESS2,Save_OverV_L_P1_VBAT);
}
void INA226_VBATHighLimit(void)
{
INA226_configure(INA226_ADDRESS2, INA226_AVERAGES_1, INA226_BUS_CONV_TIME_1100US, INA226_SHUNT_CONV_TIME_1100US, INA226_MODE_SHUNT_BUS_CONT);
INA226_calibrate(INA226_ADDRESS2, INA226_Rshunt,10);
INA226_setMaskEnable_h(INA226_ADDRESS2); //上限
INA226_setBusVoltageLimit(INA226_ADDRESS2,Save_OverV_H_P1_VBAT);
}
//============================================================================================================
uint8_t INA226_configure(u8 addr, ina226_averages_t avg, ina226_busConvTime_t busConvTime, ina226_shuntConvTime_t shuntConvTime, ina226_mode_t mode)
{
uint16_t config = 0x8000; //先复位
config |= (avg << 9 | busConvTime << 6 | shuntConvTime << 3 | mode);
// vBusMax = 36;
// vShuntMax = 0.08192f;
INA226_WriteTwoByte(addr,INA226_REG_CONFIG, config);
return 0;
}
//============================================
uint8_t INA226_setMaskEnable_h(u8 addr)
{
uint16_t mask = 0;
mask |= (INA226_BIT_BUL | INA226_BIT_APOL ); //配置 Alert 测 under Vbus;
//Alert pin polarity,active-high open collector
//警报标志位自动清除
INA226_WriteTwoByte(addr, INA226_REG_MASKENABLE, mask);
return 0;
}
uint8_t INA226_setMaskEnable_l(u8 addr)
{
uint16_t mask = 0;
mask |= (INA226_BIT_BOL | INA226_BIT_APOL ); //配置 Alert 测 over Vbus;
//Alert pin polarity,active-high open collector
//警报标志位自动清除
INA226_WriteTwoByte(addr, INA226_REG_MASKENABLE, mask);
return 0;
}
uint8_t INA226_calibrate(u8 addr, float rShuntValue, float iMaxExpected)
{
uint16_t calibrationValue;
float minimumLSB;
// float iMaxPossible;
// iMaxPossible = vShuntMax / rShunt;
rShunt = rShuntValue;
minimumLSB = iMaxExpected / 32767; //Current_LSB = Maximum Expected Current / 2^15
currentLSB = (uint16_t)(minimumLSB * 100000000);
currentLSB /= 100000000;
currentLSB /= 0.0001;
currentLSB = ceil(currentLSB);
currentLSB *= 0.0001;
powerLSB = currentLSB * 25;
calibrationValue = (uint16_t)((0.00512) / (currentLSB * rShunt));//CAL = 0.00512/(currentLSB * Rshunt)
if(debug ==1) USART1_Printf("calibrationValue %d\r\n",calibrationValue);
INA226_WriteTwoByte(addr, INA226_REG_CALIBRATION, calibrationValue);
return 0;
}
//================读数据===================================================================================================================================
float INA226_readBusPower(u8 addr)
{
return (INA226_ReadTwoByte(addr, INA226_REG_POWER) * powerLSB);
}
//mA级别
float INA226_readShuntCurrent(u8 addr)
{
u16 value=0;
float Current =0;
//=========================校准电流============================================================================
// float x1=286;
// float y1=289;
//
// float x2=5050;
// float y2=5100;
// float k= (y2-y1)/(x2-x1);//1.0099
// float b= y1-k*x1;//0.1784
// USART1_Printf("k= %.4f\r\nb= %.4f ",k,b);
// USART1_Printf("INA226_REG_SHUNTVOLTAGE %.4d\r\n",INA226_ReadTwoByte(addr, INA226_REG_SHUNTVOLTAGE));
//=====================================================================================================
value = INA226_ReadTwoByte(addr, INA226_REG_CURRENT);
if( (value > 65500) || (value <= 2) || (value <= -0.001)) value =0;
Current = value * currentLSB;
Current *=1000;
Current = Current / 1.0009 - 0.1784;
if( (Current > 65500) || (Current <= 2) || (Current <= -0.001)) Current =0;
return (Current);
}
//mV级别
float INA226_readShuntVoltage(u8 addr)
{
float voltage =0;
voltage = INA226_ReadTwoByte(addr, INA226_REG_SHUNTVOLTAGE) * 0.0000025; //2.5uV/bit
voltage *= 1000;
voltage = voltage / 1.2776 + 0.1609;
if(voltage <=0.17) voltage =0;
if(voltage > 80) voltage =0; //范围为+-80mv
//=========================校准电压============================================================================
// float x1=1.3;
// float y1=1.5;
// float x2=33;
// float y2=42;
// float k= (y2-y1)/(x2-x1);//1.2776
// float b= y1-k*x1;//-0.1609
// USART1_Printf("k= %.4f\r\nb= %.4f ",k,b);
// USART1_Printf("INA226_REG_SHUNTVOLTAGE %.4d\r\n",INA226_ReadTwoByte(addr, INA226_REG_SHUNTVOLTAGE));
//=====================================================================================================
return (voltage);
}
float INA226_readBusVoltage(u8 addr)
{
float voltage;
voltage = INA226_ReadTwoByte(addr, INA226_REG_BUSVOLTAGE);
voltage *= 1.25; //MV
// voltage *= 0.00125; //V
if(voltage <=10) voltage =0; //正误差
if(voltage > 80000) voltage =0; //负误差
// if (voltage <20) //误触发报警
// voltage = 205;
// if (voltage == 0)
// voltage = 205;
return (voltage);
}
//=====================================================================================================================================================
//================读配置寄存器配置==================================================
uint16_t INA226_getConfigure(u8 addr)
{
USART1_Printf("INA226_REG_Configure %d\r\n",INA226_ReadTwoByte(addr, INA226_REG_CONFIG));
return INA226_ReadTwoByte(addr, INA226_REG_CONFIG);
}
uint16_t INA226_getMaskEnable(u8 addr)
{
if(debug ==1) USART1_Printf("INA226_REG_MASKENABLE %d\r\n",INA226_ReadTwoByte(addr, INA226_REG_MASKENABLE));
return INA226_ReadTwoByte(addr, INA226_REG_MASKENABLE);
}
uint16_t INA226_getAlertLimit(u8 addr)
{
USART1_Printf("INA226_REG_ALERTLIMIT %d\r\n",INA226_ReadTwoByte(addr, INA226_REG_ALERTLIMIT));