You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

24LC512 I2C块读取异常:read_i2c_block_data从第2个存储地址起始读取

解决24LC512 I2C块读取从第2个地址开始的问题

这问题我之前帮朋友排查过,核心是24LC512的16位地址机制和Python I2C库默认函数的行为不匹配,咱们一步步理清楚:

问题根源

24LC512是64KB的EEPROM,需要16位存储地址才能覆盖所有单元,但很多基础I2C库(比如smbus)的read_i2c_block_data函数默认只发送8位的寄存器地址参数。当你调用bus.read_i2c_block_data(0x54, 0, length)时,实际只给芯片传了低8位地址0x00,高8位地址要么残留了之前的数值,要么被芯片默认解析成了非0值,导致地址指针没正确指向0x0000,最终块读取从0x0001开始。

而read_byte能正常工作,是因为你之前用write_byte_data(0x54, 0, 0)已经把地址指针设到了0x0000(这里虽然只传了8位地址,但24LC512会默认高8位为0),之后的read_byte是基于当前指针读,读完自动自增,所以行为符合预期。

解决方案

要正确读取24LC512的块数据,必须先完整发送16位地址,再执行块读取,这里给两种可行方法:

方法1:用i2c_rdwr发送完整I2C消息(推荐)

如果你的库支持i2c_rdwr(比如smbus2),可以构造包含地址写入和数据读取的完整传输:

from smbus2 import SMBus, i2c_msg

# 初始化总线,根据你的硬件调整总线号
bus = SMBus(1)
device_addr = 0x54
read_length = 10  # 按需修改要读取的字节数

# 构造写地址消息:设备写地址 + 16位地址(高8位在前,低8位在后)
write_addr_msg = i2c_msg.write(device_addr, [0x00, 0x00])
# 构造读数据消息
read_data_msg = i2c_msg.read(device_addr, read_length)

# 执行组合传输
bus.i2c_rdwr(write_addr_msg, read_data_msg)

# 解析结果
data = list(read_data_msg)
print(data)

方法2:先通过write_i2c_block_data设置完整地址

如果只能用基础smbus函数,可以先发送两个字节的地址定位到0x0000,再读块:

# 先写入16位地址(高8位0x00,低8位0x00)
bus.write_i2c_block_data(device_addr, 0x00, [0x00])
# 再执行块读取
data = bus.read_i2c_block_data(device_addr, 0x00, read_length)

这里的write_i2c_block_data相当于给芯片依次传了高8位和低8位地址,完成16位地址的定位。

额外验证点

  • 47C16是16Kbit的EERAM,只需要14位地址,8位地址参数足够覆盖,所以它不会出现这个问题;
  • 检查硬件:确认SDA/SCL的上拉电阻正常,避免信号干扰导致地址解析错误。

内容的提问来源于stack exchange,提问作者Kurt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 08:10:50