Linux下无法向24fc512 I2C存储芯片写入数据的求助
问题:无法向24FC512 I2C存储芯片写入数据
环境与检测情况
在Linux环境(树莓派4、BeagleBone Black)下,24FC512 I2C存储芯片的SCL和SDA引脚配有4.7KΩ上拉电阻,可被I2C总线检测到,地址为0x50;同类型0x52芯片也存在相同写入问题。BeagleBone Black上0x54、0x56地址被内核驱动占用(显示UU),但树莓派4可识别。
I2C检测输出:
ebian@BeagleBone:~$ i2cdetect -y 2 Warning: Can't use SMBus Quick Write command, will skip some addresses 0 1 2 3 4 5 6 7 8 9 a b c d e f 00: 10: 20: 30: -- -- -- -- -- -- -- -- 40: 50: 50 -- 52 -- UU -- UU -- -- -- -- -- -- -- -- -- 60: 70:
Python尝试过程
>>> from smbus2 import SMBus >>> bus = SMBus(2) >>> bus.read_byte_data(0x50,0) # 读取地址0的1字节数据 2 # 该数据是用Arduino写入的 >>> bus.read_byte_data(0x50,1) # 读取地址1的1字节数据 255 >>> bus.write_byte_data(0x50, 1, 0) # 尝试向地址1写入0 >>> bus.read_byte_data(0x50,1) 255 >>> # 写入无效果,read/write_block_data()也存在相同问题 >>> bus.close()
问题原因与解决方法
核心原因
24FC512是16位地址的I2C EEPROM(容量64KB,对应地址范围0x0000~0xFFFF),而你使用的write_byte_data()、read_byte_data()仅支持8位寄存器地址,无法正确传递芯片所需的16位内存地址,导致写入操作没有定位到目标地址,读取自然返回初始值255。
正确操作代码
写入单个字节
需要先传递16位地址的高字节、低字节,再发送数据,同时要预留EEPROM写入周期(最大5ms):
from smbus2 import SMBus import time bus = SMBus(2) # 向16位地址0x0001写入字节0x00 addr_high = 0x00 # 地址高8位 addr_low = 0x01 # 地址低8位 data = 0x00 bus.write_i2c_block_data(0x50, addr_high, [addr_low, data]) # 等待写入完成(必须预留足够时间) time.sleep(0.01) bus.close()
读取单个字节
需先发送完整的16位地址,再执行读取操作:
from smbus2 import SMBus import time bus = SMBus(2) # 读取16位地址0x0001的字节 addr_high = 0x00 addr_low = 0x01 # 先发送16位地址 bus.write_i2c_block_data(0x50, addr_high, [addr_low]) # 读取1个字节 read_data = bus.read_i2c_block_data(0x50, addr_high, 1)[0] print(f"读取到的数据:{read_data}") bus.close()
额外注意事项
- EEPROM写入需要时间,写入后必须等待至少几毫秒再读取,否则会读到旧数据或芯片忙状态。
- 确认I2C总线电压匹配:树莓派、BeagleBone均为3.3V,与24FC512兼容,4.7KΩ上拉电阻符合要求。
- BeagleBone Black上的
UU标记表示对应地址已被内核驱动占用,无法直接访问,此类情况换树莓派测试即可。
内容的提问来源于stack exchange,提问作者CostinC
相关产品推荐
相关产品推荐

