1 模块简介
INA226是一款分流/功率监视器,具有I2C™或SMBUS兼容接口。 该器件监视分流压降和总线电源电压。 可编程校准值、转换时间和取平均值功能与内部乘法器相结合,可实现电流值(单位为安培)和功率值(单位为瓦)的直接读取。最高失调电压为10μV,最大增益误差为0.1%。该器件是一款完整的16位单芯片解决方案,能够为数字I2C接口的电流、电压及电源提供全面可编程测量。
NA226可在0V至36V的共模总线电压范围内感测电流,与电源电压无关。该器件由一个2.7V至5.5V的单电源供电,电源电流典型值为330µA。该器件的额 定工作温度范围为–40°C至125°C,I2C 兼容接口上具有多达16个可编程地址。
主要特性与优势
• 具有 I2C 接口的单芯片解决方案支持电流、电压以及电源测量,无需外部多路复用器或 ADC 即可简化电路板设计,应对布局局限性;
• 业界最高精度,具有 10 uV 最大失调电压与 0.1% 最大增益误差,不但可在低电流下实现更高精度,而且还可使用更小的分流电阻器,从而可降低 I*R 损耗;
• 独立可编程转换时间与采样平均技术不但可简化每个系统的速度需求定制,而且还可降低对软件及存储器的需求;
• 420 uA 最大静态电流与 2 uA 最大关断电流支持高效工作,即便 INA226 集成 ADC 与电源多路复用器,功耗也比同类竞争产品的分立式解决方案低 3.5%;
• 140 dB 共模抑制比 (CMRR) 与 36 V 共模电压 (CMV) 可在整个工作范围内确保变化极小或根本无变化的失调电压,从而可简化误差分析
2 模块电路
3 驱动程序
IIC的驱动直接取之于stm32F4。
bsp_ina226.h
#ifndef __INA226_H
#define __INA226_H
#include "sys.h"
#include "bsp_iic.h"
#define CFG_REG 0x00 //
#define SV_REG 0x01 //分流电压
#define BV_REG 0x02 //总线电压
#define PWR_REG 0x03 //电源功率
#define CUR_REG 0x04 //电流
#define CAL_REG 0x05 //校准,设定满量程范围以及电流和功率测数的
#define ONFF_REG 0x06 //屏蔽 使能 警报配置和转换准备就绪
#define AL_REG 0x07 //包含与所选警报功能相比较的限定值
#define INA226_GET_ADDR 0XFF //包含唯一的芯片标识号
#define INA226_ADDR1 0x80
//#define INA226_GETALADDR 0x14
//定义配置数据
#define INA226_VAL_LSB 2.5f //分流电压 LSB 2.5uV
#define Voltage_LSB 1.25f //总线电压 LSB 1.25mV
#define CURRENT_LSB 1.0f //电流LSB 1mA
#define POWER_LSB 25*CURRENT_LSB
#define CAL 456 //0.00512/(Current_LSB*R_SHUNT) = 470 //电流偏大改小
typedef struct
{
float voltageVal; //mV
float Shunt_voltage; //uV
float Shunt_Current; //mA
float Power_Val; //功率
float Power; //功率mW
u32 ina226_id;
}INA226;
void INA226_SetRegPointer(u8 addr,u8 reg);
void INA226_SendData(u8 addr,u8 reg,u16 data);
u16 INA226_ReadData(u8 addr);
void INA226_Get_ID(u8 addr); //获取 id
u16 INA226_GetVoltage( u8 addr); //获取总线电压装载值
u16 INA226_GetShunt_Current(u8 addr); //获取分流电流装载值
u16 INA226_GetShuntVoltage(u8 addr); //分流电压装载值
//u16 INA226_Get_Power(u8 addr); //获取功率装载值,不使用
u16 INA226_GET_CAL_REG(u8 addr); //获取校准值
void mx_ina226_init(void);
void GetVoltage(float *Voltage);
void Get_Shunt_voltage(float *Current);
void Get_Shunt_Current(float *Current);
void get_power(void); 获取功率= 总线电压 * 电流
u8 INA226_AlertAddr(void);
void Get_Power(float *Power);
extern INA226 ina226_data;
#endif
bsp_ina226.c
#include "bsp_ina226.h"
#include "delay.h"
// 接线说明:
// 模拟IIC:
// SDA -- PF0 -- A型板 I2
// SCL -- PF1 -- A型板 I1
INA226 ina226_data;
//初始化INA226
void mx_ina226_init(void)
{
IIC_Init();
INA226_SendData(INA226_ADDR1,CFG_REG,0x8000); //重新启动
INA226_SendData(INA226_ADDR1,CFG_REG,0x484f); //设置转换时间204us,求平均值次数128,采样时间为204*128,设置模式为分流和总线连续模式
INA226_SendData(INA226_ADDR1,CAL_REG,CAL); //设置分辨率
INA226_Get_ID(INA226_ADDR1); //获取ina226的id
}
//设置寄存器指针
void INA226_SetRegPointer(u8 addr,u8 reg)
{
IIC_Start();
IIC_Send_Byte(addr);
IIC_Wait_Ack();
IIC_Send_Byte(reg);
IIC_Wait_Ack();
IIC_Stop();
}
//发送,写入数据
void INA226_SendData(u8 addr,u8 reg,u16 data)
{
u8 temp=0;
IIC_Start();
IIC_Send_Byte(addr);
IIC_Wait_Ack();
IIC_Send_Byte(reg);
IIC_Wait_Ack();
temp = (u8)(data>>8);
IIC_Send_Byte(temp);
IIC_Wait_Ack();
temp = (u8)(data&0x00FF);
IIC_Send_Byte(temp);
IIC_Wait_Ack();
IIC_Stop();
}
//读取数据
u16 INA226_ReadData(u8 addr)
{
u16 temp=0;
IIC_Start();
IIC_Send_Byte(addr+1);
IIC_Wait_Ack();
temp = IIC_Read_Byte(1);
temp<<=8;
temp |= IIC_Read_Byte(0);
IIC_Stop();
return temp;
}
//1mA/bit
u16 INA226_GetShunt_Current(u8 addr)
{
u16 temp=0;
INA226_SetRegPointer(addr,CUR_REG);
temp = INA226_ReadData(addr);
if(temp&0x8000) temp = ~(temp - 1);
return temp;
}
//获取id
void INA226_Get_ID(u8 addr)
{
u32 temp=0;
INA226_SetRegPointer(addr,INA226_GET_ADDR);
temp = INA226_ReadData(addr);
ina226_data.ina226_id = temp;
}
//获取校准值
u16 INA226_GET_CAL_REG(u8 addr)
{
u32 temp=0;
INA226_SetRegPointer(addr,CAL_REG);
temp = INA226_ReadData(addr);
return (u16)temp;
}
//1.25mV/bit
u16 INA226_GetVoltage(u8 addr)
{
u32 temp = 0;
INA226_SetRegPointer(addr,BV_REG);
temp = INA226_ReadData(addr);
return (u16)temp;
}
//2.5uV/bit
u16 INA226_GetShuntVoltage(u8 addr)
{
int16_t temp = 0;
INA226_SetRegPointer(addr,SV_REG);
temp = INA226_ReadData(addr);
if(temp&0x8000) temp = ~(temp - 1);
return (u16)temp;
}
//获取电压
void GetVoltage(float *Voltage)//mV
{
*Voltage = INA226_GetVoltage(INA226_ADDR1)*Voltage_LSB;
}
//获取分流电压
void Get_Shunt_voltage(float *Voltage)//uV
{
*Voltage = (INA226_GetShuntVoltage(INA226_ADDR1)*INA226_VAL_LSB);//如需矫正电流分流参数请将这里改为2.5
}
//获取电流
void Get_Shunt_Current(float *Current)//mA
{
*Current = (INA226_GetShunt_Current(INA226_ADDR1)* CURRENT_LSB);
}
//获取功率= 总线电压 * 电流
void get_power()//W
{
GetVoltage(&ina226_data.voltageVal); //mV
Get_Shunt_voltage(&ina226_data.Shunt_voltage); //uV
Get_Shunt_Current(&ina226_data.Shunt_Current); //mA
Get_Power(&ina226_data.Power);
ina226_data.Power_Val = ina226_data.voltageVal*0.001f * ina226_data.Shunt_Current*0.001f; //mV*mA
}
//获取功率装载值,ina226内部计算的的功率,由于未经校准,故不采用
u16 INA226_Get_Power(u8 addr)
{
int16_t temp=0;
INA226_SetRegPointer(addr,PWR_REG);
temp = INA226_ReadData(addr);
return (u16)temp;
}
//获取功率,ina226内部计算,不准确,不采用
void Get_Power(float *Power)//W
{
*Power = (INA226_Get_Power(INA226_ADDR1)*POWER_LSB);
}
//不设置报警,舍弃
/*
u8 INA226_AlertAddr()
{
u8 temp;
IIC_Start();
IIC_Send_Byte(INA226_GETALADDR);
IIC_Wait_Ack();
temp = IIC_Read_Byte(1);
IIC_Stop();
return temp;
}
*/