1、简介
INA219 是一款由 Texas Instruments(TI) 生产的 高精度电流/电压/功率监测芯片,采用 I²C 接口 通信,广泛应用于电池管理、电源监控、太阳能系统、电机控制等领域。
1. 主要特性测量范围:电压测量(总线电压):0V ~ 26V(可配置)电流测量(分流电阻电压):±40mV(可调增益)功率计算(基于电压和电流)高精度:16位 ADC(模数转换器)可配置增益(PGA 放大倍数)通信接口:I²C 接口(标准模式 100kHz,快速模式 400kHz)可编程地址(支持 16 个 I²C 地址)低功耗:工作电流低至 1mA支持低功耗模式封装:SOT23-8(小型贴片封装)
2. 工作原理
INA219 通过 分流电阻(Shunt Resistor) 测量电流,并同时监测总线电压,计算功率:电流测量校准值电压测量总线电压(Vbus)功率计算
INA219 提供多个寄存器,用于配置和读取数据:
0x00 | Configuration | 配置 ADC 模式、增益、采样率等 |
0x01 | Shunt Voltage | 读取分流电压(Vshunt) |
0x02 | Bus Voltage | 读取总线电压(Vbus) |
0x03 | Power | 读取计算得到的功率 |
0x04 | Current | 读取计算得到的电流 |
0x05 | Calibration | 设置校准值(影响电流计算精度) |
3.cubemx配置
INA219的通信接口为IIC,可以使用STM32内置硬件I2C外设与INA219模块实现数据通信
3、程序设计
ina219.h
#ifndef __INA219_H #define __INA219_H #include "main.h" extern I2C_HandleTypeDef *hina219_i2c; #define INA219_ADDRESS (0x40 << 1) // 默认地址 左移1位 // 寄存器地址 #define INA219_REG_CONFIG 0x00 #define INA219_REG_SHUNTVOLTAGE 0x01 #define INA219_REG_BUSVOLTAGE 0x02 #define INA219_REG_POWER 0x03 #define INA219_REG_CURRENT 0x04 #define INA219_REG_CALIBRATION 0x05 // 配置参数 #define INA219_CONFIG_RESET 0x8000 #define INA219_CONFIG_BVOLTAGERANGE_32V 0x2000 #define INA219_CONFIG_GAIN_8_320MV 0x1800 #define INA219_CONFIG_BADCRES_12BIT 0x0180 #define INA219_CONFIG_SADCRES_12BIT_1S_532US 0x0018 #define INA219_CONFIG_MODE_SANDBVOLT_CONTINUOUS 0x0007 void INA219_Init(I2C_HandleTypeDef *hi2c); float INA219_GetShuntVoltage_mV(void); float INA219_GetBusVoltage_V(void); float INA219_GetCurrent_mA(void); float INA219_GetPower_mW(void); uint16_t INA219_ReadReg(uint8_t reg); void INA219_WriteReg(uint8_t reg, uint16_t value); #endif
INA219的IIC地址为0x40,因此需要将模块的A0、A1拨码开关调至GND
ina219.c
#include "ina219.h" #include <math.h> I2C_HandleTypeDef *hina219_i2c; float currentLSB = 0.0f; float powerLSB = 0.0f; void INA219_Init(I2C_HandleTypeDef *hi2c) { hina219_i2c = hi2c; // 计算LSB // 假设使用0.1欧姆分流电阻,最大预期电流为3.2A float maxExpectedCurrent = 3.2f; currentLSB = maxExpectedCurrent / 32768.0f; powerLSB = 20.0f * currentLSB; // 写入校准寄存器 uint16_t calibrationValue = (uint16_t)(0.04096f / (currentLSB * 0.1f)); INA219_WriteReg(INA219_REG_CALIBRATION, calibrationValue); // 配置寄存器 uint16_t config = INA219_CONFIG_BVOLTAGERANGE_32V | INA219_CONFIG_GAIN_8_320MV | INA219_CONFIG_BADCRES_12BIT | INA219_CONFIG_SADCRES_12BIT_1S_532US | INA219_CONFIG_MODE_SANDBVOLT_CONTINUOUS; INA219_WriteReg(INA219_REG_CONFIG, config); } uint16_t INA219_ReadReg(uint8_t reg) { uint8_t data[2]; HAL_I2C_Mem_Read(hina219_i2c, INA219_ADDRESS, reg, 1, data, 2, HAL_MAX_DELAY); return (data[0] << 8) | data[1]; } void INA219_WriteReg(uint8_t reg, uint16_t value) { uint8_t data[2] = {value >> 8, value & 0xFF}; HAL_I2C_Mem_Write(hina219_i2c, INA219_ADDRESS, reg, 1, data, 2, HAL_MAX_DELAY); } float INA219_GetShuntVoltage_mV(void) { int16_t value = (int16_t)INA219_ReadReg(INA219_REG_SHUNTVOLTAGE); return value * 0.01f; // LSB = 10uV } float INA219_GetBusVoltage_V(void) { uint16_t value = INA219_ReadReg(INA219_REG_BUSVOLTAGE); return (value >> 3) * 0.004f; // LSB = 4mV } float INA219_GetCurrent_mA(void) { int16_t value = (int16_t)INA219_ReadReg(INA219_REG_CURRENT); return value * currentLSB * 10000.0f; } float INA219_GetPower_mW(void) { int16_t value = (int16_t)INA219_ReadReg(INA219_REG_POWER); return value * powerLSB * 1000.0f; }
引脚连接顺序如下:
INA219模块+端连接+5V
INA219模块-端连接GND
INA219模块C端连接SCL
INA219模块D端连接SDA
INA219模块IN+端连接+5V或+12V电源
INA219模块GND端连接电源GND端
INA219模块IN-端连接电机负载+端
电机负载-端连接电源GND端
4、功率监测效果
由于手头上没有电源模块,以下是INA219空载的检测结果
5、OLED显示功率信息
定义字符数组变量,用于存储格式化字符串
/* USER CODE BEGIN PV */ char StrBuff[12]; /* USER CODE END PV */
OLED信息显示
void SimpleInfoShow(){ ssd1306_Fill(Black); OLED_ShowChinese(0,0,0,16); OLED_ShowChinese(15,0,1,16); OLED_ShowChinese(30,0,2,16); OLED_ShowChinese(45,0,3,16); OLED_ShowChinese(60,0,4,16); OLED_ShowChinese(75,0,5,16); OLED_ShowChinese(90,0,6,16); OLED_ShowChinese(0,16,7,16); // 电 OLED_ShowChinese(15,16,8,16); // 流 OLED_ShowChar(30,16,':',16); OLED_ShowString(90,16,(uint8_t*)"mA",16); OLED_ShowChinese(0,16*2,9,16); // 电 OLED_ShowChinese(15,16*2,10,16); // 压 OLED_ShowChar(30,16*2,':',16); OLED_ShowString(90,16*2,(uint8_t*)"mV",16); OLED_ShowChinese(0,16*3,0,16); // 功 OLED_ShowChinese(15,16*3,1,16); // 率 OLED_ShowChar(30,16*3,':',16); OLED_ShowString(90,16*3,(uint8_t*)"mW",16); }
INA219、OLED屏幕初始化
/* USER CODE BEGIN 2 */ INA219_Init(&hi2c1); ssd1306_Init(); ssd1306_Fill(Black); SimpleInfoShow(); /* USER CODE END 2 */
执行功率数据监测,并实时更新至OLED屏幕显示
while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ HAL_Delay(1000); float busVoltage = INA219_GetBusVoltage_V(); float shuntVoltage = INA219_GetShuntVoltage_mV(); float current = INA219_GetCurrent_mA(); float power = INA219_GetPower_mW(); printf("INA219 Detect: vbus:%f V; current:%f mA,vshunt:%f v,power:%fw\r\n", busVoltage, current,shuntVoltage,power); sprintf(StrBuff,"%03.0f mA",current); OLED_ShowString(40,16,(uint8_t*)StrBuff,16); sprintf(StrBuff,"%03.0f mV",busVoltage/1000); OLED_ShowString(40,16*2,(uint8_t*)StrBuff,16); sprintf(StrBuff,"%03.0f mW",power); OLED_ShowString(40,16*3,(uint8_t*)StrBuff,16); } /* USER CODE END 3 */ }
6、运行效果