如何修改C语言I2C代码以读取红色区域对应寄存器数值?
I2C寄存器读取代码修改方案
问题分析
你的代码存在三个核心问题,直接导致读取失败:
- I2C设备地址格式错误
- 接收缓冲区长度与请求读取长度不匹配
- 未遵循「先指定寄存器地址,再读取数据」的I2C寄存器读取标准流程
具体修改步骤
修正I2C设备地址
HAL库的I2C通信函数中,设备地址需要是7位地址左移1位,并根据读写操作设置最低位:读操作最低位设为1,写操作设为0。你当前用0xFE作为读操作地址,这是设备的写地址,会直接导致通信握手失败。匹配缓冲区与读取长度
你定义的a[1]仅能容纳1个字节,但请求读取2个字节,会触发数组越界,引发内存异常。如果要读取红色方框对应的16位数值,需将缓冲区改为uint8_t a[2]。使用正确的寄存器读取流程
读取I2C设备寄存器时,必须先向设备写入目标寄存器地址,再启动读操作。HAL_I2C_Master_Receive无法完成这个两步流程,应改用HAL_I2C_Mem_Read函数,它会自动处理「写寄存器地址→读数据」的完整逻辑。
修改后的代码示例
假设你的设备7位地址为0x7F,目标寄存器地址为0xXX(替换为你实际要读取的寄存器地址):
I2C_HandleTypeDef hi2c1; // 设备7位地址左移1位,读操作最低位设为1 #define DEVICE_ADDR (0x7F << 1 | 1) // 目标寄存器地址 #define TARGET_REG (0xXX) // 缓冲区改为2字节,存储16位数值 uint8_t a[2]; uint16_t read_result; // 调用Mem_Read完成寄存器读取:参数依次为I2C句柄、设备地址、寄存器地址、地址长度、数据缓冲区、读取长度、超时时间 if(HAL_I2C_Mem_Read(&hi2c1, DEVICE_ADDR, TARGET_REG, I2C_MEMADD_SIZE_8BIT, a, 2, 50) == HAL_OK) { // 根据设备字节序拼接16位数值(若设备是小端序则交换a[0]和a[1]顺序) read_result = (a[0] << 8) | a[1]; printf("check1 : %04X\n\r", read_result); } else { printf("I2C read failed!\n\r"); }
额外排查点
- 确认硬件连接:SDA、SCL引脚焊接是否正确,是否接了合适的上拉电阻
- 确认I2C初始化配置:时钟频率是否与设备规格匹配(常见为100kHz或400kHz)
- 确认寄存器地址位数:若设备寄存器地址为16位,需将
I2C_MEMADD_SIZE_8BIT改为I2C_MEMADD_SIZE_16BIT
内容的提问来源于stack exchange,提问作者user15504267
相关产品推荐
相关产品推荐

