这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » DIY与开源设计 » 电子DIY » 【Let'sdo第1期-DIY功率检测与控制系统】INA219功率监测+OLED

共4条 1/1 1 跳转至

【Let'sdo第1期-DIY功率检测与控制系统】INA219功率监测+OLED显示

工程师
2025-05-26 22:07:34     打赏

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)功率计算

27e5167ad1e1043d2d560d12b8a2a9a.jpg

INA219 提供多个寄存器,用于配置和读取数据:

寄存器地址名称功能
0x00Configuration配置 ADC 模式、增益、采样率等
0x01Shunt Voltage读取分流电压(Vshunt)
0x02Bus Voltage读取总线电压(Vbus)
0x03Power读取计算得到的功率
0x04Current读取计算得到的电流
0x05Calibration设置校准值(影响电流计算精度)

3.cubemx配置

INA219的通信接口为IIC,可以使用STM32内置硬件I2C外设与INA219模块实现数据通信

1748267410876.png

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空载的检测结果

4f97f449301a704492384e34a2c4727.png

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、运行效果

afd2b4deb6d36e2f5eabe58c085d66b.jpg





关键词: 功率监测     INA219    

专家
2025-05-26 22:35:02     打赏
2楼

感谢分享


专家
2025-05-26 22:36:13     打赏
3楼

感谢分享


专家
2025-05-26 22:37:55     打赏
4楼

感谢分享


共4条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]