基于INA226模块的功率检测电路

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 模块电路

基于INA226模块的功率检测电路_第1张图片

 

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;
}
*/

 

你可能感兴趣的:(嵌入式设计,嵌入式,单片机)