你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

HAL_I2C_Mem_Read_IT读取INA226多个寄存器只有第一个寄存器是对的,其他全为0XFF

[复制链接]
1564553256@qq.c 提问时间:2025-12-14 16:02 / 未解决

//IIC+中断 //记住不光要开IT中断,还要把I2C global中断打开

include "sht30.h"

// IT状态标志(仅用于批量读取) volatile uint8_t ina226_IT_rx_done = 0; // 接收完成标志 volatile uint8_t ina226_IT_rx_error = 0; // 接收错误标志 uint8_t ina226_IT_read_buf[4] = {0}; // 批量读取缓存(6字节:3个16位寄存器) float Power, Current, BusVoltage; uint16_t num_of_Current = 0; uint8_t sht30_rx_err = 0; HAL_StatusTypeDef INA226_Read_ALL_IT(uint8_t Dev_addr) { // 检查上一次IT是否还在进行 if (HAL_I2C_GetState(&INA226_IIC) == HAL_I2C_STATE_BUSY_RX) { return HAL_BUSY; } // 重置IT状态和缓存 ina226_IT_rx_done = 0; ina226_IT_rx_error = 0; for (uint8_t i = 0; i < 4; i++) { ina226_IT_read_buf[i] = 0; } // 启动IT批量读取:从0x02寄存器开始,连续读取6字节(0x02/0x03/0x04各2字节) // 核心:利用INA226寄存器地址自动递增特性,一次读取3个寄存器 HAL_StatusTypeDef ret = HAL_I2C_Mem_Read_IT( &INA226_IIC, Dev_addr<<1, // 设备地址(Mem_Read自动处理读位,无需|0x01) INA226_REG_POWER, // 起始寄存器地址(0x02) I2C_MEMADD_SIZE_8BIT, // 寄存器地址8位 ina226_IT_read_buf, // IT接收缓存(6字节) 4 // 读取长度:3个寄存器×2字节=6字节 );

if (ret != HAL_OK) { return ret; // IT启动失败 } return HAL_OK; }

/**

  • @brief I2C Mem_Read IT接收完成回调(仅处理INA226) / void HAL_I2C_MemRxCpltCallback(I2C_HandleTypeDef hi2c) { if (hi2c->Instance == INA226_IIC.Instance) { ina226_IT_rx_done = 1; // 标记接收完成 ina226_IT_rx_error = 0; // 无错误

    // 功率(0x03):第2-3字节,LSB=625μW uint16_t power_reg = (ina226_IT_read_buf[0] << 8) | ina226_IT_read_buf[1]; Power = (float)power_reg * POWER_LSB;

    // 电流(0x04):第4-5字节,LSB=25μA(有符号) int16_t current_reg = (int16_t)((ina226_IT_read_buf[2] << 8) | ina226_IT_read_buf[3]); Current = (float)current_reg * CURRENT_LSB; num_of_Current++; if(num_of_Current < 80) { INA226_Read_ALL_IT(addr_1); } else { num_of_Current = 0; SHT30_Read_ALL_IT(SHT30_ADDR_1); // INA226_Read_ALL_IT(addr_1); } } }

/** @brief I2C IT错误回调(仅处理INA226) / void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *hi2c) { if (hi2c->Instance == INA226_IIC.Instance) { if(num_of_Current != 0) { ina226_IT_rx_done = 1; // 标记传输结束 ina226_IT_rx_error = 1; // 标记错误 INA226_Read_ALL_IT(addr_1); } else { sht30_rx_err = 1; SHT30_Read_ALL_IT(SHT30_ADDR_1); } } }

  • image.png可以看到power是正常的,但是current就不正常,这是从power寄存器(0x03)开始读,如果我从总线电压寄存器(0x02)开始读六个字节,就会是下面这样: image.png

  • 可以看到只有第一个寄存器读出来的才能正确转换

    另外我想说,如果用阻塞式单个读取,是完全没问题的,也就是配置没问题

    /**

    • @brief 从INA226读取16位寄存器数据
    • @param Dev_addr: 从机地址
    • @param reg_addr:寄存器地址
    • @param data:读取到的数据(16位,输出参数)
    • @retval HAL_StatusTypeDef:操作状态 / HAL_StatusTypeDef INA226_ReadReg(uint8_t Dev_addr, uint8_t reg_addr, uint16_t data) { uint8_t rx_buf[2]; // 先发送要读取的寄存器地址 if (HAL_I2C_Master_Transmit(&INA226_IIC, (Dev_addr << 1) | 0x00, &reg_addr, 1, 50) != HAL_OK) { return HAL_ERROR; } // 读取该寄存器的16位数据 if (HAL_I2C_Master_Receive(&INA226_IIC, (Dev_addr << 1) | 0x01, rx_buf, 2, 50) != HAL_OK) { return HAL_ERROR; } *data = (rx_buf[0] << 8) | rx_buf[1]; // 组合高8位和低8位 return HAL_OK; }

    /**

    • @brief 读取INA226的电流(需先初始化校准)
    • @param Dev_addr: 从机地址
    • @retval float:电流(单位:A) / float INA226_ReadCurrent(uint8_t Dev_addr) { uint16_t reg_data; int16_t signed_data; if (INA226_ReadReg(Dev_addr, INA226_REG_CURRENT, &reg_data) != HAL_OK) { return -1.0f; } // 电流值为16位有符号数,LSB由校准值决定(此处为25μA/bit) signed_data = (int16_t)reg_data; return signed_data CURRENT_LSB; }
收藏 评论1 发布时间:2025-12-14 16:02

举报

1个回答
CM_STM32 回答时间:2025-12-14 17:33:34

学到了

所属标签

相似问题

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版