这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » DIY与开源设计 » 电子DIY » 【Let'sdo2025年第1期】功率监测与控制系统DIY活动基础任务——INA

共2条 1/1 1 跳转至

【Let'sdo2025年第1期】功率监测与控制系统DIY活动基础任务——INA219读取功率信息

高工
2025-06-14 09:12:49     打赏

活动任务三是使用INA219对测量5V,12V负载电压电流并显示在OLED。首先对硬件部分进行介绍。
# 硬件连接
开发板上的I2C3的SCL为PA8,SDA为PC9。

INA219_I2C3.png

INA219模块的接口是I2C,连接开发板I2C3和模块的对应管脚,实现开发板与模块之间的硬件连接。另外,连接开关电源、稳压模块、继电器、OLED屏幕和负载。
连接12V负载的连接图如下,


12V_Hardware.png


检测负载的效果如下

12V_Info.png# INA219驱动移植

INA219的驱动使用现有的libdriver中的INA219驱动。
https://gitee.com/libdriver/ina219
驱动库的代码分布如下,在移植时,复制驱动源码到工程中,参考驱动接口中的模板实现MCU平台上的通讯接口,参考示例程序使用驱动函数获取INA219的信息。

libdriver_ina219_code.png

使用上述驱动库,需要完成几个接口函数,针对开发板的实现如下

#include "driver_ina219_interface.h"
#include <stdarg.h>
#include <main.h>

/**
 * @brief  interface iic bus init
 * @return status code
 *         - 0 success
 *         - 1 iic init failed
 * @note   none
 */
uint8_t ina219_interface_iic_init(void)
{
    return 0;
}

/**
 * @brief  interface iic bus deinit
 * @return status code
 *         - 0 success
 *         - 1 iic deinit failed
 * @note   none
 */
uint8_t ina219_interface_iic_deinit(void)
{
    return 0;
}

/**
 * @brief      interface iic bus read
 * @param[in]  addr iic device write address
 * @param[in]  reg iic register address
 * @param[out] *buf pointer to a data buffer
 * @param[in]  len length of the data buffer
 * @return     status code
 *             - 0 success
 *             - 1 read failed
 * @note       none
 */
uint8_t ina219_interface_iic_read(uint8_t addr, uint8_t reg, uint8_t *buf, uint16_t len)
{
	HAL_StatusTypeDef ret;
	ret=HAL_I2C_Mem_Read(&hi2c3, addr, reg, 1, buf, len, HAL_MAX_DELAY);
	if(ret!=HAL_OK)
		return 1;
	return 0;
}

/**
 * @brief     interface iic bus write
 * @param[in] addr iic device write address
 * @param[in] reg iic register address
 * @param[in] *buf pointer to a data buffer
 * @param[in] len length of the data buffer
 * @return    status code
 *            - 0 success
 *            - 1 write failed
 * @note      none
 */
uint8_t ina219_interface_iic_write(uint8_t addr, uint8_t reg, uint8_t *buf, uint16_t len)
{
	HAL_StatusTypeDef ret;
	ret=HAL_I2C_Mem_Write(&hi2c3, addr, reg, 1, buf, len, HAL_MAX_DELAY);
	if(ret!=HAL_OK)
		return 1;
	return 0;
}

/**
 * @brief     interface delay ms
 * @param[in] ms time
 * @note      none
 */
void ina219_interface_delay_ms(uint32_t ms)
{
    HAL_Delay(ms);
}


在工程中添加驱动相关的代码文件,并且在工程的路径中添加存放代码的文件夹路径。
INA219_CubeIDE.png

Project_Path.png
这样,就可以在工程中调用驱动库中的函数来使用INA219检测设备的功率信息。
# INA219驱动使用

在工程中,封装INA219的初始化过程和功率信息的操作为以下两个函数:

uint8_t ina219_basic_init(ina219_address_t addr_pin, double r)
{
    uint8_t res;
    uint16_t calibration;

    /* link interface function */
    DRIVER_INA219_LINK_INIT(&gs_handle, ina219_handle_t);
    DRIVER_INA219_LINK_IIC_INIT(&gs_handle, ina219_interface_iic_init);
    DRIVER_INA219_LINK_IIC_DEINIT(&gs_handle, ina219_interface_iic_deinit);
    DRIVER_INA219_LINK_IIC_READ(&gs_handle, ina219_interface_iic_read);
    DRIVER_INA219_LINK_IIC_WRITE(&gs_handle, ina219_interface_iic_write);
    DRIVER_INA219_LINK_DELAY_MS(&gs_handle, ina219_interface_delay_ms);
    DRIVER_INA219_LINK_DEBUG_PRINT(&gs_handle, ina219_interface_debug_print);

    /* set addr pin */
    res = ina219_set_addr_pin(&gs_handle, addr_pin);
    if (res != 0)
    {
        return 1;
    }

    /* set the r */
    res = ina219_set_resistance(&gs_handle, r);
    if (res != 0)
    {
        return 1;
    }

    /* init */
    res = ina219_init(&gs_handle);
    if (res != 0)
    {
        return 1;
    }

    /* set bus voltage range */
    res = ina219_set_bus_voltage_range(&gs_handle, INA219_BASIC_DEFAULT_BUS_VOLTAGE_RANGE);
    if (res != 0)
    {
        (void)ina219_deinit(&gs_handle);

        return 1;
    }

    /* set bus voltage adc mode */
    res = ina219_set_bus_voltage_adc_mode(&gs_handle, INA219_BASIC_DEFAULT_BUS_VOLTAGE_ADC_MODE);
    if (res != 0)
    {
        (void)ina219_deinit(&gs_handle);

        return 1;
    }

    /* set shunt voltage adc mode */
    res = ina219_set_shunt_voltage_adc_mode(&gs_handle, INA219_BASIC_DEFAULT_SHUNT_VOLTAGE_ADC_MODE);
    if (res != 0)
    {
        (void)ina219_deinit(&gs_handle);

        return 1;
    }

    /* set shunt bus voltage continuous */
    res = ina219_set_mode(&gs_handle, INA219_MODE_SHUNT_BUS_VOLTAGE_CONTINUOUS);
    if (res != 0)
    {
        (void)ina219_deinit(&gs_handle);

        return 1;
    }

    /* set pga */
    res = ina219_set_pga(&gs_handle, INA219_BASIC_DEFAULT_PGA);
    if (res != 0)
    {
        (void)ina219_deinit(&gs_handle);

        return 1;
    }

    /* calculate calibration */
    res = ina219_calculate_calibration(&gs_handle, (uint16_t *)&calibration);
    if (res != 0)
    {
        (void)ina219_deinit(&gs_handle);

        return 1;
    }

    /* set calibration */
    res = ina219_set_calibration(&gs_handle, calibration);
    if (res != 0)
    {
        (void)ina219_deinit(&gs_handle);

        return 1;
    }

    return 0;
}

/**
 * @brief      basic example read
 * @param[out] *mV pointer to a mV buffer
 * @param[out] *mA pointer to a mA buffer
 * @param[out] *mW pointer to a mW buffer
 * @return     status code
 *             - 0 success
 *             - 1 read failed
 * @note       none
 */
uint8_t ina219_basic_read(float *mV, float *mA, float *mW)
{
    uint8_t res;
    int16_t s_raw;
    uint16_t u_raw;

    /* read bus voltage */
    res = ina219_read_bus_voltage(&gs_handle, (uint16_t *)&u_raw, mV);
    if (res != 0)
    {
        return 1;
    }

    /* read current */
    res = ina219_read_current(&gs_handle, (int16_t *)&s_raw, mA);
    if (res != 0)
    {
        return 1;
    }

    /* read power */
    res = ina219_read_power(&gs_handle, (uint16_t *)&u_raw, mW);
    if (res != 0)
    {
        return 1;
    }

    return 0;
}

在主函数中调用定义的INA219初始化函数以及功率信息读取函数来获取功率信息。

  ina219_basic_init(INA219_ADDRESS_0, 0.01);

  ina219_interface_delay_ms(1000);

  ina219_basic_read(&mV, &mA, &mW);

将获取到到的功率信息显示在OLED屏幕上

float mV;
float mA,mA_sum,mA_ave;
float mW;
static ina219_handle_t gs_handle;        /**< ina219 handle */
static char V_info[32];
static char I_info[32];
static char W_info[32];

  while (1)
  {


       u8g2_ClearDisplay(&myDisplay);

    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
	sprintf(V_info,"电压:%.2fmV",mV);
	sprintf(I_info,"电流:%.2fmA",mA_ave);
	sprintf(W_info,"功率:%.2fmW",mW);
	u8g2_DrawUTF8(&myDisplay,0,16,"功率检测和显示");
	u8g2_DrawUTF8(&myDisplay,0,32,V_info);
	u8g2_DrawUTF8(&myDisplay,0,48,I_info);
	u8g2_DrawUTF8(&myDisplay,0,64,W_info);

	u8g2_SendBuffer(&myDisplay);
  }

# 实际效果演示

选择一个路由器作为12负载,在连接后INA219采集到功率数据如下图所示。

12V_Info.png


配套的电机工作电压为3V,电机和其他部分连接如下。

3V_Hardware.png
读取到的功率信息如下所示。

3V_Info.png
# 总结

使用现有的libdriver驱动INA219,在使用时只需要实现不同MCU的通讯接口就可以使用函数库的功能,可以快速上手,对于初期开发是有参考价值的,后续可在此基础上进行驱动的优化。





专家
2025-06-14 20:06:42     打赏
2楼

感谢分享


共2条 1/1 1 跳转至

回复

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