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

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个回答
cm32 回答时间:5 小时前

学到了

所属标签

相似问题

官网相关资源

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