You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

ESP32(Arduino框架)EEPROM读写异常原因咨询

ESP32 EEPROM 读写异常问题分析与解决

你的判断其实不完全准确,这个问题和串口波特率没有关系,核心原因是ESP32的EEPROM实现机制——它本身没有硬件EEPROM,是用Flash的一块区域模拟的,而模拟EEPROM的初始化加载是异步操作导致的。

问题根源详解

当你调用EEPROM.begin(128)时,ESP32会触发一个异步操作:把Flash中模拟EEPROM区域的数据加载到一块RAM缓存里。这个加载过程需要一点时间(虽然很短,但对于240MHz的ESP32来说,程序执行速度远快于Flash的读取速度)。

你在EEPROM.begin()之后立刻调用EEPROM.read(),这时候Flash的数据还没来得及加载到RAM缓存中,你读到的其实是缓存的初始值(刚好和你全局定义的configuration结构体内容一致,因为全局变量在RAM中初始化后,未被覆盖的缓存区域可能刚好复用了这块内存的内容),所以才会出现“首次就读到准备写入的数据”的情况。

添加延迟后,Flash的数据已经完成加载到缓存,这时候你读到的就是EEPROM中原本存储的数据了。

解决方案

不需要10秒这么长的延迟,只需要给Flash加载留一点时间就行,比如10ms就足够稳定:

void setup() {
  Serial.begin(115200);
  EEPROM.begin(128);
  delay(10); // 等待Flash数据加载到RAM缓存
  // 读取原有EEPROM数据
  for(int i = 0; i <= 50; i++) {
    Serial.print((char)EEPROM.read(i));
  }
  Serial.println("\n");
  saveconfig();
  // 读取写入后的数据
  for(int i = 0; i <= 50; i++) {
    Serial.print((char)EEPROM.read(i));
  }
  Serial.println("\n");
}

另外,更规范的做法是使用EEPROM.get()EEPROM.put()来直接读写结构体,避免逐个字节操作的繁琐:

// 读取结构体
configuration_type loaded_config;
EEPROM.get(0, loaded_config);
// 写入结构体
EEPROM.put(0, configuration);
EEPROM.commit();

补充说明

ESP32的串口波特率(这里是115200)只会影响串口输出的速度,和EEPROM缓存的加载完全无关,所以你的波特率猜想并不正确。这个问题的本质是Flash模拟EEPROM的异步加载特性,和MCU的时钟速度快确实有关,但不是因为波特率跟不上,而是Flash读取速度跟不上CPU的执行速度。

内容的提问来源于stack exchange,提问作者Praveen Kumar P S

火山引擎 最新活动