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

共2条 1/1 1 跳转至

【Let’sdo第1期—功率检测与控制系统DIY】-成果贴

菜鸟
2026-07-13 15:02:58     打赏

上篇介绍了这次活动的一个任务-点亮OLED,这次着重介绍最复杂、最难的一个环节-INA219读取功率信息

首先对硬件部分进行介绍。
# 硬件连接
开发板上的I2C3的SCL为PA8,SDA为PC9。

image.png

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

image.png

检测负载的效果如下

image.png

# INA219驱动移植

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

image.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);
}

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

image.png

image.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;
}

# 实际效果演示

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

image.png

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


专家
2026-07-14 06:04:27     打赏
2楼

谢谢分享


共2条 1/1 1 跳转至

回复

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