news 2026/5/16 15:22:46

实现STM32读取INA226电流值并通过串口发送给HMI串口屏显示

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
实现STM32读取INA226电流值并通过串口发送给HMI串口屏显示

系统连接与工作原理

整个系统的数据流动如下:

硬件连接

1. INA226 与 STM32 连接 (I2C接口)

INA226 引脚STM32 引脚说明
VCC3.3V电源正极
GNDGND电源地
SCLPB6 (或其它I2C SCL引脚)I2C时钟线
SDAPB7 (或其它I2C SDA引脚)I2C数据线
A0GND或VCC地址选择引脚0
A1GND或VCC地址选择引脚1

INA226的I2C地址由A0和A1引脚决定:

  • 两个都接地(GND):0x40 (7位地址)
  • 在代码中,HAL库通常需要将7位地址左移1位(0x40 << 1 = 0x80)

2. HMI串口屏与STM32连接 (UART接口)

HMI串口屏引脚STM32 引脚说明
RXPA2 (USART2_TX)串口接收数据
TXPA3 (USART2_RX)串口发送数据(可选)
GNDGND共同地线
VCC5V或3.3V电源(根据屏规格)

3. INA226 与被测电路连接

INA226 引脚被测电路连接说明
V+电源正极测量总线电压
V-负载输入正极
S+电源正极电流检测正
S-负载输入正极电流检测负

注意:需要在S+和S-之间连接一个分流电阻(Shunt Resistor),例如0.1Ω/1W的精密电阻。电流通过测量该电阻两端的压降计算得出。

STM32代码实现 (HAL库)

1. INA226驱动代码 (ina226.c / ina226.h)

首先,我们需要编写INA226的驱动程序。

ina226.h
#ifndefINA226_H#defineINA226_H#include"stm32f1xx_hal.h"// 根据你的STM32系列调整// INA226寄存器地址#defineINA226_CONFIG_REG0x00#defineINA226_SHUNT_VOLTAGE_REG0x01#defineINA226_BUS_VOLTAGE_REG0x02#defineINA226_POWER_REG0x03#defineINA226_CURRENT_REG0x04#defineINA226_CALIBRATION_REG0x05#defineINA226_MASK_ENABLE_REG0x06#defineINA226_ALERT_LIMIT_REG0x07#defineINA226_MANUFACTURER_ID_REG0xFE#defineINA226_DIE_ID_REG0xFF// INA226默认I2C地址(A0和A1接地)#defineINA226_ADDRESS0x80// (0x40 << 1)// 配置寄存器设置(根据你的需求调整)#defineINA226_CONFIG_DEFAULT0x4727// 0100 0111 0010 0111// 函数声明voidINA226_Init(I2C_HandleTypeDef*hi2c);floatINA226_ReadBusVoltage(void);floatINA226_ReadShuntVoltage(void);floatINA226_ReadCurrent(void);floatINA226_ReadPower(void);uint16_tINA226_ReadManufacturerID(void);uint16_tINA226_ReadDieID(void);externI2C_HandleTypeDef hi2c1;// 你的I2C句柄#endif
ina226.c
#include"ina226.h"#include<math.h>// I2C句柄I2C_HandleTypeDef*ina226_i2c;// 校准值(需要根据你的分流电阻计算)staticuint16_tcalibrationValue=0;// 将在Init中计算voidINA226_Init(I2C_HandleTypeDef*hi2c){ina226_i2c=hi2c;// 验证器件IDuint16_tmanufID=INA226_ReadManufacturerID();uint16_tdieID=INA226_ReadDieID();// 预期值:制造商ID应为0x5449,芯片ID应为0x2260if(manufID!=0x5449||dieID!=0x2260){// 器件识别失败,处理错误Error_Handler();}// 计算校准值(示例:分流电阻0.1Ω,最大预期电流2A)// 公式:Cal = 0.00512 / (Current_LSB * Rshunt)// Current_LSB = 最大预期电流 / 2^15floatmaxExpectedCurrent=2.0;// 2AfloatrShunt=0.1;// 0.1ΩfloatcurrentLSB=maxExpectedCurrent/32768.0;calibrationValue=(uint16_t)(0.00512/(currentLSB*rShunt));// 写入校准寄存器uint8_tcalibData[3]={INA226_CALIBRATION_REG,(uint8_t)(calibrationValue>>8),(uint8_t)(calibrationValue&0xFF)};HAL_I2C_Master_Transmit(ina226_i2c,INA226_ADDRESS,calibData,3,HAL_MAX_DELAY);// 写入配置寄存器uint8_tconfigData[3]={INA226_CONFIG_REG,(uint8_t)(INA226_CONFIG_DEFAULT>>8),(uint8_t)(INA226_CONFIG_DEFAULT&0xFF)};HAL_I2C_Master_Transmit(ina226_i2c,INA226_ADDRESS,configData,3,HAL_MAX_DELAY);}// 读取总线电压(单位:伏特)floatINA226_ReadBusVoltage(){uint8_treg=INA226_BUS_VOLTAGE_REG;uint8_tdata[2];HAL_I2C_Master_Transmit(ina226_i2c,INA226_ADDRESS,&reg,1,HAL_MAX_DELAY);HAL_I2C_Master_Receive(ina226_i2c,INA226_ADDRESS,data,2,HAL_MAX_DELAY);uint16_tvoltageRaw=(data[0]<<8)|data[1];returnvoltageRaw*0.00125;// 1.25mV/LSB}// 读取电流值(单位:安培)floatINA226_ReadCurrent(){uint8_treg=INA226_CURRENT_REG;uint8_tdata[2];HAL_I2C_Master_Transmit(ina226_i2c,INA226_ADDRESS,&reg,1,HAL_MAX_DELAY);HAL_I2C_Master_Receive(ina226_i2c,INA226_ADDRESS,data,2,HAL_MAX_DELAY);int16_tcurrentRaw=(data[0]<<8)|data[1];// 计算Current_LSBfloatmaxExpectedCurrent=2.0;// 与初始化时一致floatcurrentLSB=maxExpectedCurrent/32768.0;returncurrentRaw*currentLSB;}// 读取其他数据的函数类似实现...uint16_tINA226_ReadManufacturerID(){uint8_treg=INA226_MANUFACTURER_ID_REG;uint8_tdata[2];HAL_I2C_Master_Transmit(ina226_i2c,INA226_ADDRESS,&reg,1,HAL_MAX_DELAY);HAL_I2C_Master_Receive(ina226_i2c,INA226_ADDRESS,data,2,HAL_MAX_DELAY);return(data[0]<<8)|data[1];}uint16_tINA226_ReadDieID(){uint8_treg=INA226_DIE_ID_REG;uint8_tdata[2];HAL_I2C_Master_Transmit(ina226_i2c,INA226_ADDRESS,&reg,1,HAL_MAX_DELAY);HAL_I2C_Master_Receive(ina226_i2c,INA226_ADDRESS,data,2,HAL_MAX_DELAY);return(data[0]<<8)|data[1];}

2. 主程序代码 (main.c)

#include"main.h"#include"stm32f1xx_hal.h"#include"ina226.h"#include<stdio.h>#include<string.h>// 全局变量I2C_HandleTypeDef hi2c1;UART_HandleTypeDef huart2;// 函数声明voidSystemClock_Config(void);staticvoidMX_GPIO_Init(void);staticvoidMX_I2C1_Init(void);staticvoidMX_USART2_UART_Init(void);voidSendToHMI(constchar*variable,floatvalue);intmain(void){HAL_Init();SystemClock_Config();MX_GPIO_Init();MX_I2C1_Init();MX_USART2_UART_Init();// 初始化INA226INA226_Init(&hi2c1);// 给INA226和HMI屏一点启动时间HAL_Delay(100);charmsg[50];sprintf(msg,"System Started\r\n");HAL_UART_Transmit(&huart2,(uint8_t*)msg,strlen(msg),HAL_MAX_DELAY);while(1){// 读取电流值floatcurrent=INA226_ReadCurrent();// 发送到HMI串口屏SendToHMI("current",current);// 可选:读取并发送其他值floatvoltage=INA226_ReadBusVoltage();SendToHMI("voltage",voltage);// 每秒更新一次(可根据需要调整)HAL_Delay(1000);}}// 发送数据到HMI串口屏的函数voidSendToHMI(constchar*variable,floatvalue){charbuffer[50];if(strcmp(variable,"current")==0){// 发送电流值到HMI的n0组件(数值显示)sprintf(buffer,"n0.val=%d\xFF\xFF\xFF",(int)(value*1000));// 转换为毫安HAL_UART_Transmit(&huart2,(uint8_t*)buffer,strlen(buffer),HAL_MAX_DELAY);// 可选:同时发送到文本组件显示更详细的信息sprintf(buffer,"t0.txt=\"%.2fA\"\xFF\xFF\xFF",value);HAL_UART_Transmit(&huart2,(uint8_t*)buffer,strlen(buffer),HAL_MAX_DELAY);}elseif(strcmp(variable,"voltage")==0){// 发送电压值到HMI的n1组件sprintf(buffer,"n1.val=%d\xFF\xFF\xFF",(int)(value*1000));// 转换为毫伏HAL_UART_Transmit(&huart2,(uint8_t*)buffer,strlen(buffer),HAL_MAX_DELAY);sprintf(buffer,"t1.txt=\"%.2fV\"\xFF\xFF\xFF",value);HAL_UART_Transmit(&huart2,(uint8_t*)buffer,strlen(buffer),HAL_MAX_DELAY);}}// 系统时钟配置voidSystemClock_Config(void){// 根据你的STM32型号配置}// I2C初始化staticvoidMX_I2C1_Init(void){hi2c1.Instance=I2C1;hi2c1.Init.ClockSpeed=400000;// 400kHzhi2c1.Init.DutyCycle=I2C_DUTYCYCLE_2;hi2c1.Init.OwnAddress1=0;hi2c1.Init.AddressingMode=I2C_ADDRESSINGMODE_7BIT;hi2c1.Init.DualAddressMode=I2C_DUALADDRESS_DISABLE;hi2c1.Init.OwnAddress2=0;hi2c1.Init.GeneralCallMode=I2C_GENERALCALL_DISABLE;hi2c1.Init.NoStretchMode=I2C_NOSTRETCH_DISABLE;HAL_I2C_Init(&hi2c1);}// USART2初始化(用于HMI串口屏)staticvoidMX_USART2_UART_Init(void){huart2.Instance=USART2;huart2.Init.BaudRate=9600;// 或115200,根据你的HMI屏设置huart2.Init.WordLength=UART_WORDLENGTH_8B;huart2.Init.StopBits=UART_STOPBITS_1;huart2.Init.Parity=UART_PARITY_NONE;huart2.Init.Mode=UART_MODE_TX_RX;huart2.Init.HwFlowCtl=UART_HWCONTROL_NONE;huart2.Init.OverSampling=UART_OVERSAMPLING_16;HAL_UART_Init(&huart2);}// GPIO初始化staticvoidMX_GPIO_Init(void){// GPIO初始化代码}

HMI串口屏配置

HMI串口屏通常使用USART HMI或类似的软件进行配置。

1. 在HMI屏上创建显示元件

  • 添加一个数值显示元件(如n0)用于显示电流值
  • 添加一个文本显示元件(如t0)用于显示带单位的电流值

2. HMI屏指令格式

STM32需要按照HMI屏的协议格式发送数据:

指令格式:组件ID.属性=值[0xFF 0xFF 0xFF] 示例:n0.val=1000\xFF\xFF\xFF(设置n0组件的值为1000)

参考代码 STM32读取INA226的电流值 并用串口发送给HMI串口屏显示www.3dddown.com/csa/56677.html

调试与优化建议

  1. I2C通信调试

    • 如果读取不到INA226的数据,先用逻辑分析仪或示波器检查I2C信号。
    • 确认INA226的地址是否正确(A0和A1引脚电平决定地址)。
    • 检查I2C线路上是否有适当的上拉电阻(通常4.7kΩ)。
  2. 电流测量校准

    • INA226的测量精度高度依赖校准寄存器的设置。校准公式为:
      CAL = 0.00512 / (Current_LSB × Rshunt)
      其中Current_LSB = 最大预期电流 / 32768
    • 可以用万用表测量实际电流,与INA226读数对比,微调校准值。
  3. 串口通信调试

    • 确保STM32与HMI屏的波特率、数据位、停止位和校验位设置一致。
    • HMI指令必须以0xFF 0xFF 0xFF结尾。
  4. 抗干扰处理

    • 电流检测路径(特别是分流电阻连接)应尽量短而直接,减少噪声干扰。
    • 在INA226的电源引脚附近添加去耦电容(100nF)。
  5. 功能扩展

    • 可以增加功率计算电能累计功能。
    • 添加阈值报警功能,当电流超过设定值时,在HMI屏上显示警告。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/15 17:26:57

青龙面板滑稽脚本库:自动化任务配置全攻略

青龙面板滑稽脚本库&#xff1a;自动化任务配置全攻略 【免费下载链接】huajiScript 滑稽の青龙脚本库 项目地址: https://gitcode.com/gh_mirrors/hu/huajiScript 青龙面板搭配滑稽脚本库&#xff0c;为技术爱好者提供了一套完整的自动化任务解决方案。通过本文的详细指…

作者头像 李华
网站建设 2026/5/15 17:27:00

10分钟搭建ORA-12154错误诊断原型工具

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 在快马平台上快速生成一个ORA-12154诊断工具原型&#xff0c;功能包括&#xff1a;1) 上传错误日志文件自动解析&#xff1b;2) 显示可能的错误原因&#xff08;如‘TNS无法解析服务…

作者头像 李华
网站建设 2026/5/15 18:26:12

终极指南:如何快速上手SpaceCadetPinball经典弹球游戏

终极指南&#xff1a;如何快速上手SpaceCadetPinball经典弹球游戏 【免费下载链接】SpaceCadetPinball Decompilation of 3D Pinball for Windows – Space Cadet 项目地址: https://gitcode.com/gh_mirrors/sp/SpaceCadetPinball SpaceCadetPinball是一个开源项目&…

作者头像 李华
网站建设 2026/5/15 18:26:33

map遍历零基础入门指南

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 开发一个map遍历学习应用&#xff0c;提供交互式教程和新手友好的界面。点击项目生成按钮&#xff0c;等待项目生成完整后预览效果 作为一个刚开始学习编程的新手&#xff0c;你可能…

作者头像 李华
网站建设 2026/5/15 18:27:27

Zustand入门指南:5分钟学会基础用法

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 创建一个最简单的Zustand示例项目&#xff0c;适合React初学者学习。要求&#xff1a;1) 创建一个基础store&#xff1b;2) 实现一个计数器功能&#xff1b;3) 在组件中显示和使用状…

作者头像 李华
网站建设 2026/5/15 18:27:27

JavaScript新手必看:理解并解决‘Uncaught (in promise)‘

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 创建一个交互式学习应用&#xff0c;通过简单示例和可视化演示帮助新手理解Promise概念。应用应包含&#xff1a;1) Promise生命周期图示 2) 错误处理示例 3) 互动练习区&#xff0…

作者头像 李华