本文基于NUCLEO-F411RE开发板,通过与INA219 功率传感器连接,实现对功率数据采集,并通过OLED屏幕实现实时显示功率数据。
该DIY通过以下步骤实现:
一、使用STM32CubeMX新建工程
二、添加OLED屏幕和INA219功率传感器的驱动代码
三、通过串口发送获取的功率信息
四、在OLED屏幕显示电压、电流、功率的实时信息
硬件连接:
PB9 ---- SDA (INA219)
PB10 ---- SCL (INA219)
PB7 ---- SDA (OLED)
PB6 ---- SCL (OLED)
使用STM32CubeMX新建工程:
INA219模块是通过I2C的方式进行数据传输,因此需要使用到板子的I2C引脚
在cubemx中,将所使用的I2C引脚进行相应设置,这里使用的I2C1是给OLED使用的,I2C2是给INA219使用的
添加OLED屏幕和INA219功率传感器的驱动代码:
OLED屏幕的驱动代码有点长,这里就不贴了,是很经典的SSD1306的OLED屏幕
由于官方给的INA219的驱动代码是软件I2C方式的,但是无垠的广袤这位大佬写的帖子中提供了硬件I2C的驱动代码,在这里感谢大佬,我就偷个小懒了~
#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 * 1000.0f; } float INA219_GetPower_mW(void) { int16_t value = (int16_t)INA219_ReadReg(INA219_REG_POWER); return value * powerLSB * 1000.0f; }
通过串口发送获取的功率信息:
使用串口的方式很简单,只需要重写fputc函数对printf进行重定向就可以了
在hal库中,有现成的串口发送函数,直接在fputc函数中进行调用即可,这里使用的是UART2,也就是板卡自带的usb口提供的串口
int fputc(int ch, FILE *f) { uint8_t temp = ch; HAL_UART_Transmit(&huart2, &temp, 1, 1000); return temp; }
通过串口发送获取的功率信息
INA219_Init(&hi2c2); while (1) { current = INA219_GetCurrent_mA(); voltage = INA219_GetBusVoltage_V(); power = INA219_GetPower_mW(); printf("Voltage: %.2f V, Current: %.2f mA, Power: %.2f mWrn", voltage, current, power); HAL_Delay(500); }
通过串口助手可以查看相应的信息
在OLED屏幕显示电压、电流、功率的实时信息
由于开关电源本人缺少相应的电线,因此使用了很经典的面包板电源,但其实本质上是一样的
这里是OLED显示的代码
OLED_Printf(0, 16, OLED_8X16, "电流: %.2fmA", current); OLED_Printf(0, 32, OLED_8X16, "电压: %.2fV", voltage); OLED_Printf(0, 48, OLED_8X16, "功率: %.2fW", power); OLED_Update();
这是待机情况下的功率信息
这是负载情况下的功率信息