esp32-c3 使用microPython实现at24c02的单字节写、单字节读、连续写(跨页)、连续读(跨页)
from machine import Pin, I2C
import timeclass AT24C02:def __init__(self, scl=3, sda=10, dev_addr=0xA0): # 默认I2C引脚self.i2c = I2C(0, scl=Pin(scl), sda=Pin(sda), freq=400_000)self.dev_addr = dev_addrself.page_size = 8 # 页大小定义self.max_addr = 0xFF # 最大地址255def write_byte(self, addr, data):"""单字节写入(带地址校验)"""if addr > self.max_addr:raise ValueError("Address overflow")buf = bytearray([addr & 0xFF, data])try:self.i2c.writeto(self.dev_addr, buf)time.sleep_ms(5) # 写入周期等待return Trueexcept OSError:return Falsedef read_byte(self, addr):"""单字节读取(带异常处理)"""if addr > self.max_addr:raise ValueError("Address overflow")try:self.i2c.writeto(self.dev_addr, bytes([addr]))return self.i2c.readfrom(self.dev_addr, 1)[0]except OSError:return None# 写入时,由于内部页缓冲区的限制,连续写入超过页边界会导致数据回卷,因此必须分页处理def write_page(self, addr, data):"""分页写入实现"""if addr + len(data) > self.max_addr:raise ValueError("Address overflow")while len(data) > 0:# 计算当前页剩余空间chunk = min(self.page_size - (addr % self.page_size), len(data))# 构建包含地址的写入数据包buf = bytearray([addr]) + data[:chunk]for _ in range(3): # 最多重试3次数try:self.i2c.writeto(self.dev_addr, buf)breakexcept OSError:time.sleep_ms(1)else:return Falseaddr += chunkdata = data[chunk:]time.sleep_ms(5) # 页写入延迟return True# 读取操作没有限制,可以连续读取任意长度的数据,无需担心页边界def read_page(self, addr, length):"""连续读取优化"""if addr + length > self.max_addr:raise ValueError("Address overflow")data = bytearray()while length > 0:chunk = min(16, length) # 单次最大读取长度try:self.i2c.writeto(self.dev_addr, bytes([addr]))data += self.i2c.readfrom(self.dev_addr, chunk)addr += chunklength -= chunkexcept OSError:return Nonereturn dataif __name__ == "__main__":# 初始化EEPROM对象eeprom = AT24C02()# 测试用例1:单字节读写test_addr = 0x10eeprom.write_byte(test_addr, 0xAA)read_val = eeprom.read_byte(test_addr)print(f"Single byte test: {'PASS' if read_val == 0xAA else 'FAIL'} ({read_val})")# 测试用例2:跨页写入(32字节)write_data = bytes([i % 256 for i in range(32)])success = eeprom.write_page(0x20, write_data)print(f"Page write: {'SUCCESS' if success else 'FAIL'}")# 测试用例3:连续读取验证read_data = eeprom.read_page(0x20, 32)if read_data:match = read_data == write_dataprint(f"Data verification: {'MATCH' if match else 'MISMATCH'}")print("Original:", write_data.hex())print("Readback:", read_data.hex())else:print("Read operation failed")