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

如何将基于I2C的EEPROM写入C宏改写为Python实现

C代码逻辑解析

你提供的C宏是一个通用的EEPROM写入工具,核心逻辑是绕过C的类型限制,把任意类型的变量按原始字节写入EEPROM,不需要针对不同类型单独写适配代码,具体执行步骤如下:

  • 先取变量p的内存首地址,强制转为字节指针pp,这样就可以按字节为单位读取变量的全部内存内容
  • 遍历变量p占用的所有内存字节,遍历次数等于sizeof(p),也就是该类型变量占用的内存字节数
  • 从传入的EEPROM起始地址address开始,依次将每个字节写入对应偏移的EEPROM地址,完成整块数据的写入

如果你的硬件是用外接I2C接口的EEPROM芯片(比如AT24C系列),确实是用machine模块的I2C对象实现;如果你的开发板(比如部分AVR、ESP系列)固件自带模拟EEPROM支持,可以直接调用封装好的EEPROM接口,不用手动操作I2C。

MicroPython 实现代码

Python是高级语言,不能直接读取变量的原始内存地址,所以需要先把目标数据转为字节序列,再执行写入,和C代码的最终效果完全一致。

情况1:使用固件自带的内置EEPROM接口

from machine import EEPROM
import struct

# 初始化EEPROM,size参数根据你的硬件可写空间调整,比如ESP32一般最大支持4096字节
eeprom = EEPROM(size=4096)

def eeprom_write(address, data):
    # 把输入数据转为字节序列
    if isinstance(data, int):
        # 假设对应C的4字节有符号int,小端序,可根据你的实际C环境调整长度和端序
        data_bytes = data.to_bytes(4, byteorder='little', signed=True)
    elif isinstance(data, float):
        # 对应C的4字节单精度浮点数,小端序
        data_bytes = struct.pack('<f', data)
    elif isinstance(data, (bytes, bytearray)):
        data_bytes = data
    else:
        raise TypeError("当前仅支持int、float、bytes类型数据写入")
    
    # 逐字节写入EEPROM,和C宏逻辑一致
    for offset in range(len(data_bytes)):
        eeprom.write(address + offset, data_bytes[offset])
    # 部分固件的模拟EEPROM需要调用commit才会把缓存写入存储,不支持该方法的固件可以删掉这行
    if hasattr(eeprom, 'commit'):
        eeprom.commit()

情况2:外接I2C接口EEPROM芯片

from machine import I2C, Pin
import struct
import time

# 初始化I2C,scl、sda引脚根据你的硬件接线调整
i2c = I2C(0, scl=Pin(22), sda=Pin(21), freq=400000)
# EEPROM的I2C设备地址,AT24C系列默认一般为0x50,可根据硬件ADDR引脚接线调整
EEPROM_DEV_ADDR = 0x50

def eeprom_write_i2c(address, data):
    # 把输入数据转为字节序列
    if isinstance(data, int):
        data_bytes = data.to_bytes(4, byteorder='little', signed=True)
    elif isinstance(data, float):
        data_bytes = struct.pack('<f', data)
    elif isinstance(data, (bytes, bytearray)):
        data_bytes = data
    else:
        raise TypeError("当前仅支持int、float、bytes类型数据写入")
    
    # 逐字节写入,兼容性最好,不需要处理页写入的跨页问题
    for offset in range(len(data_bytes)):
        write_addr = address + offset
        # 构造写入帧:2字节EEPROM地址 + 1字节数据(适配容量大于256字节的EEPROM)
        buf = bytearray([(write_addr >> 8) & 0xFF, write_addr & 0xFF, data_bytes[offset]])
        i2c.writeto(EEPROM_DEV_ADDR, buf)
        # 等待EEPROM写入完成,固定5ms兼容所有AT24C系列芯片
        time.sleep_ms(5)
注意事项
  • 如果需要写入结构体等价的数据,可以用struct.pack一次性把多个字段打包为字节序列,再传入写入函数即可
  • 字节序、数据长度要和你原来的C代码运行环境保持一致,不然会出现读写数据不匹配的问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 01:39:02