INA226使用之程序与模块测试

笔者最近有个项目需要测量电流参数,于是买来INA226模块测试一下。

文章目录

  • 应用电路
  • 程序设计
  • 模块测试
  • 总结

应用电路

首先测试使用的INA226模块如下图所示。

INA226模块原理图如下图所示。

官方手册的参考电路如下图所示。
结合上述图片以及数据手册,可知使用INA226模块时,与单片机的接线方式如下。

INA226模块 单片机
VCC 3.3V或5V
GND GND
SCL PB6
SDA PB7
VBS 电路总线电压
INA+ 电流流入端
INA- 电流流出端
ALE 报警引脚(未使用报警功能可不接)

程序设计

INA226.h文件如下。

#ifndef __INA226_H
#define __INA226_H
#include "sys.h"

#define READ_ADDR                  0x81	 //A1=GND,A2=GND // R=1, W=0
#define WRITE_ADDR                 0x80

#define Config_Reg                 0x00
#define Shunt_V_Reg                0x01
#define Bus_V_Reg                  0x02
#define Power_Reg                  0x03
#define Current_Reg                0x04
#define Calib_Reg                  0x05
#define Mask_En_Reg                0x06
#define Alert_Reg                  0x07
#define Man_ID_Reg                 0xFE  //0x5449
#define ID_Reg                     0xFF  //0x2260

u16 INA226_Read2Byte(u8 reg_addr);
u8 INA226_Write2Byte(u8 reg_addr,u16 reg_data);
void INA226_Init(void);

#endif

INA226.c文件如下。

#include "INA226.h"
#include "myiic.h"
#include "delay.h"

u16 INA226_Read2Byte(u8 reg_addr)
{
     
	u16 reg_data=0;
	u16 temp=0;
	IIC_Start();
	IIC_Send_Byte(WRITE_ADDR);
	if(IIC_Wait_Ack())return 0;
	IIC_Send_Byte(reg_addr);   
	if(IIC_Wait_Ack())return 0;
	IIC_Start();
	IIC_Send_Byte(READ_ADDR);
	if(IIC_Wait_Ack())return 0;
	reg_data= IIC_Read_Byte(1);
	reg_data=(reg_data<<8)&0xFF00;
	temp=IIC_Read_Byte(0);
	IIC_Stop();
	reg_data|=temp;
	return reg_data;
}

u8 INA226_Write2Byte(u8 reg_addr,u16 reg_data)
{
             
	u8 data_high=(u8)((reg_data&0xFF00)>>8);
	u8 data_low=(u8)reg_data&0x00FF;
	IIC_Start();
	IIC_Send_Byte(WRITE_ADDR);   
	if(IIC_Wait_Ack())return 0;
	IIC_Send_Byte(reg_addr );    
	if(IIC_Wait_Ack())return 0;        
	IIC_Send_Byte(data_high);
	if(IIC_Wait_Ack())return 0;        
	IIC_Send_Byte(data_low);
	if(IIC_Wait_Ack())return 0;                 
	IIC_Stop();
	delay_ms(2);
	return 1;
}

void INA226_Init(void)
{
     
	INA226_Write2Byte(Config_Reg, 0x4527);//0100_010_100_100_111 //16次平均,1.1ms,1.1ms,连续测量分流电压和总线电压
	INA226_Write2Byte(Calib_Reg, 0x0A00);
}

其中myiic.h、delay.h均使用的是正点原子F3系列开发板的程序。

通信部分直接参考数据手册中的时序图即可,主要是在INA226_Init()函数中,写入Configuration Register的数据为0x4527,该值所代表的参数已经在注释中给出,读者想修改的话参考数据手册寄存器定义表格即可。而写入Calibration Register的数据需要根据实际电路中的采样电阻阻值以及电流分辨率来设置。
比如,在此次测试的INA226模块中使用的贴片采样电阻为R100,即0.1欧。
根据数据手册中的公式1和公式2。
INA226使用之程序与模块测试_第1张图片
因为Shunt Voltage Register的值最大为0x7FFF,LSB=2.5uV, FSR = 81.92mV。
又因为分流电阻阻值为0.1欧,所以最大电流为819.2mA。(注意这个问题,避免在实际使用中出现的超量程情况,以至得出错误测量数据)

所以Maximum Expected Current的值不能超过819.2mA。

假设Current_LSB = 0.02mA,则Maximum Expected Current = 655.36mA,满足上述条件。
则CAL = 0.00512/(0.02*0.1)*1000 = 2560= 0x0A00。
所以最后写入Calibration Register中的数据为0x0A00。

最后就可以直接使用了。
在源文件中,笔者没有对各种获取测量参数的函数进行封装,而是在主程序中直接读取数据后转换成对应测量数据。具体程序如下。

printf("data=%-5d, Bus_V  =%f mV\r\n", INA226_Read2Byte(Bus_V_Reg),INA226_Read2Byte(Bus_V_Reg)*1.25);
printf("data=%-5d, Shunt_V=%f mV\r\n", INA226_Read2Byte(Shunt_V_Reg),INA226_Read2Byte(Shunt_V_Reg)*2.5*0.001);
printf("data=%-5d, Curent =%f mA\r\n", INA226_Read2Byte(Current_Reg),INA226_Read2Byte(Current_Reg)*0.02);
printf("data=%-5d, Power  =%f mW\r\n", INA226_Read2Byte(Power_Reg),INA226_Read2Byte(Power_Reg)*0.02*25);

关于数据转换中所用到的参数,在INA226的数据手册中可以找到。
Bus Voltage Register的 LSB = 1.25mV,FSR = 0x7FFF。
Shunt Voltage Register 的 LSB = 2.5uV,FSR = 0x7FFF。
Current Register 的 LSB = 0.02mA,FSR = 0x7FFF。
Power Register 的 LSB = Current_LSB * 25,FSR = 0xFFFF。

模块测试

按照上面的接线方式表格接好INA226模块的连线。
最后实物接线图如下。
INA226使用之程序与模块测试_第2张图片

使用学生稳压电源对测量回路供电,使用4位半万用表测量回路电流以及总线电压。
INA226使用之程序与模块测试_第3张图片


使用串口助手接收并显示测量数据。

因为手上只有一个万用表,所以无法在测量电流时,同时测量总线电压。下面就单独测量一次总线电压,测量结果如下。
INA226使用之程序与模块测试_第4张图片

总结

多次测量发现,若以万用表所测电流数据为真实值,那么INA226模块所测电流值接近真实值,在随着电流数据增大时,误差可能会增大。在实际使用中,可以改变采样电阻的阻值大小,进而改变电流的量程,从而改变其分辨率。如觉得本次测量中的模块电流量程太小需要扩大量程,可以减小采样电阻的阻值,但是这样会导致电流分辨率的下降。

在本次测试中,还存在总线电压测不准以及数据不稳定的情况,导致功率测量值不准,不知道是不是测试方法错误,还是什么问题,欢迎大家与笔者交流讨论。

INA226完整驱动程序上面已经给出,可以直接进行移植,若嫌麻烦可以下载工程文件。
INA226完整工程文件

你可能感兴趣的:(笔记,单片机,c语言,硬件,传感器)