IIC 控制INA226 实现电压电流功率的监测

本文有前置代码,需要先参考 SPI 0.96LCD 7735s.先编写好相关的屏幕驱动代码,再添加相关IIC 驱动INA226 的代码

INA226的大概示意图 
下面是INA226的寄存器
INA226初始化需要两步
- 初始化ADC参数(0x00),采样时间,采样次数等
- 初始化校准电阻(0x05)。芯片需要配置一个电流校准寄存器,匹配芯片内部的电阻和外部采样电阻。计算公式如下图。

例1:
需求:6A的测量范围,采样电阻10mR
current_lsb = (6)/32768 =0.0001831
CAL = 0.00512/( 0.0001831 * 0.01) = 2,796.286
2,796.286 约等于 2796
2796 转换成hex 0xAEC,此时 地址为0x05 的Calibration Register寄存器写入值 0xAEC即可。
例2:
需求:每个lsb 为0.2mA,采样电阻 10mR
cal = 0.00512/( 0.0002 * 0.01) = 2560
2560 转换成hex 0xA00,此时 地址为0x05 的Calibration Register寄存器写入值 0xA00即可。
1. 硬件连接
INA226 只需外部接一个电阻到测量线路上就好,IIC接口去通信。

2. CubeMX生成代码
代码复用之前7735s的代码。初始化一下IIC, 
3. 编写代码 INA226
INA226 读写代码
读取和写INA226的代码,就是将库中的IIC函数重新封装一下。
static int32_t INA226_RD_Reg(I2C_HandleTypeDef *hi2c,uint8_t deviceAddress,uint8_t addr)
{
uint8_t temp[2];
HAL_I2C_Mem_Read(hi2c, deviceAddress, addr, I2C_MEMADD_SIZE_8BIT, temp, 2, 0xFF);
return temp[1] + temp[0] * 256;
}
static void INA226_WR_Reg(I2C_HandleTypeDef *hi2c,uint8_t deviceAddress,uint8_t addr, uint16_t value )
{
uint8_t temp[2];
temp[0] = value >> 8;
temp[1] = value & 0xFF;
HAL_I2C_Mem_Write(hi2c, deviceAddress, addr, I2C_MEMADD_SIZE_8BIT, temp, 2, 0x100);
}INA226 初始化寄存器代码
初始化INA226 ,主要就是初始化地址为0x01地址的参数,和0x05地址的校准寄存器
需要注意228和226的寄存器地址不同,所以需要控制不同的寄存器
void INA226_init()
{
//0100_010_100_100_111 //16次平均,1.1ms,1.1ms,连续测量分流电压和总线电压
INA226_WR_Reg(&hi2c1,0x80,0x00,0x4527); //ADC_CONFIG 寄存器初始化
INA226_WR_Reg(&hi2c1,0x80,0x05,0xA00);//SHUNT_CAL 寄存器,初始化电流的分流电阻
}main.c函数中的while函数
需要注意228和226的寄存器地址不同,所以需要控制不同的寄存器
INA226_init();
float t=0;
int32_t input = 0;
while (1)
{
//总线电压测量
input = (int)INA226_RD_Reg(&hi2c1,0x80 ,0x02);
t = input * 1.25 /1000;//V
LCD_ShowChinese(0,40,"电压",RED,WHITE,32,0);
LCD_ShowFloatNum1(70,45,t,5,RED,WHITE,24);
LCD_ShowString(143,45,"V",RED,WHITE,24,0);
//电流结果
input = (int)INA226_RD_Reg(&hi2c1,0x80 ,0x04);
t = input * 0.0002;//A
LCD_ShowChinese(0,0,"电流",RED,WHITE,32,0);
LCD_ShowFloatNum1(70,5,t,5,RED,WHITE,24);
LCD_ShowString(143,5,"A",RED,WHITE,24,0);
HAL_Delay(1000);
}4 编写代码INA228
INA228 是20 位ADC,所以在通信的时候会有一些位数上的差异
读取和写INA228的代码,就是将库中的IIC函数重新封装一下。
static int32_t INA228_RD_Reg(I2C_HandleTypeDef *hi2c,uint8_t deviceAddress,uint8_t addr)
{
uint8_t temp[3];
HAL_I2C_Mem_Read(hi2c, deviceAddress, addr, I2C_MEMADD_SIZE_8BIT, temp, 3, 0xFF);
return temp[2]+temp[1]*256 + temp[0] * 65536;
}
static void INA228_WR_Reg(I2C_HandleTypeDef *hi2c,uint8_t deviceAddress,uint8_t addr, uint16_t value )
{
uint8_t temp[2];
temp[0] = value >> 8;
temp[1] = value & 0xFF;
HAL_I2C_Mem_Write(hi2c, deviceAddress, addr, I2C_MEMADD_SIZE_8BIT, temp, 2, 0x100);
}INA228 初始化寄存器代码
初始化INA228 ,主要就是初始化地址为0x01地址的参数,和0x05地址的校准寄存器
需要注意228和226的寄存器地址不同,所以需要控制不同的寄存器
void INA228_init()
{
INA228_WR_Reg(&hi2c1,0x80,0x01,0xFB6F); //ADC_CONFIG 寄存器初始化
INA228_WR_Reg(&hi2c1,0x80,0x02,0xFA0);//SHUNT_CAL 寄存器,初始化电流的分流电阻
}main.c函数中的while函数
需要注意228和226的寄存器地址不同,所以需要控制不同的寄存器
INA228_init();
float t=0;
int32_t input = 0;
while (1)
{
//总线电压测量
input = (int)INA228_RD_Reg(&hi2c1,0x80 ,0x05);
t = input * 1.25 /1000;//V
LCD_ShowChinese(0,40,"电压",RED,WHITE,32,0);
LCD_ShowFloatNum1(70,45,t,5,RED,WHITE,24);
LCD_ShowString(143,45,"V",RED,WHITE,24,0);
//电流结果
input = (int)INA228_RD_Reg(&hi2c1,0x80 ,0x07);
t = input * 0.5057 -5;//uA
LCD_ShowChinese(0,0,"电流",RED,WHITE,32,0);
LCD_ShowFloatNum1(70,5,t,5,RED,WHITE,24);
LCD_ShowString(143,5,"A",RED,WHITE,24,0);
HAL_Delay(1000);
}总结
代码参考:https://blog.csdn.net/weixin_56719449/article/details/149055858