什么是EEPROM
EEPROM代表可擦除可编程只读存储器(Electrically Erasable Programmable Read-Only Memory,缩写为EEPROM),是一种电子存储器,可在不需要外部设备的情况下擦除和重写。 EEPROM是一个非易失性存储器(NVM),这意味着它可以保留存储的数据即使没有电源供应。 EEPROM广泛应用于各种电子设备中,如计算机、手机、数字相机等。
ESP32中EEPROM的特点
ESP32并不具有内置的EEPROM,ESP32是通过Flash内存来模拟EEPROM。而Flash内存和EEPROM非常类似,也是一种非易失性存储器,非常适合于存储需要长期保存的数据,支持100,000 到 1,000,000 次写入操作。
ESP32中的EEPROM具有以下特点:
- 
容量:ESP32的EEPROM容量为512bytes,也就是4kb,虽然不大,但足够存储程序的配置数据。这意味着你可以在512个地址上储存一个0-255的数值。 
- 
可编程性:ESP32的EEPROM可以通过简单几段代码实现运行时进行读写操作,非常方便。 
- 
寿命:ESP32的EEPROM寿命很长,经过1万次擦写后,依然可以保持良好的性能。 
- 
安全性:ESP32的EEPROM支持加密和校验功能,可以确保数据的安全性和完整性。 
ESP32 EEPROM的使用方法
- 我们使用Arduino的EEPROM库来访问ESP的内部EEPROM储存空间。方法非常简单,只要先引入头文件。该库已经被假如到esp32点Arduino框架,因此不用安装额外的库就能直接使用。
#include <EEPROM.h>
- 初始化EEPROM需要先定义EEPROM容量大小。如果要增加EEPROM的纪录内容,千万不要忘记修改大小,因为即使你的使用地址超出了容量,也没有报错提示。
#define EEPROM_SIZE 10 ... void setup() { EEPROM.begin(EEPROM_SIZE); ... }
- 写数据到EEPROM,具体格式为:EEPROM.write(<地址>, <数值>), 其中地址是你定义的大小范围内的地址,从零开始,数值是0-255的数值,例如:
EEPROM.write(0, 132);
- 从EEPROM读取数据,具体格式为:EEPROM.read(<地址>), 其中地址是你之前写入数据的地址,返回一个0-255的无符号整数,uint8_t. 如果在读取前没有被写入数值,默认值为255。
uint8_t value = EEPROM.read(0);
- 除了无符号整数ESP32的EEPROM库同样支持读写Byte、Char、Short、Long、Long64、Float、Double、Bool、String、Bytes等类型的读写,但相应的容量需要根据计算来定义好。
代码示例
以下的代码展示怎样保存LED灯在关机前的状态,使用了NodeMCU开发版,其中默认BUILDIN_LED是第二引脚。
// 引入头文件
#include <EEPROM.h>
// 定于EEPROM容量
#define EEPROM_SIZE 1
// 定义引脚, 我们使用开发板的IO0按钮,默认被拉高
#define BUTTON_PIN 0
// 使用板载LED灯
#define BUILDIN_LED 2
// LED状态
int ledState = HIGH;
// 按钮状态
int buttonState;
// 之前的按钮状态
int lastButtonState = HIGH;
// 上次被触发的时间
unsigned long lastDebounceTime = 0; 
// 防抖动计时器
unsigned long debounceDelay = 50; 
void setup() { 
  Serial.begin(115200);
  // 初始化EEPROM
  EEPROM.begin(EEPROM_SIZE);
 //使用GPIO0需要设置默认上拉
  pinMode(BUTTON_PIN, INPUT_PULLUP);
  pinMode(BUILDIN_LED, OUTPUT);
  // 读取LED在EEPROM的状态
  ledState = EEPROM.read(0);
  // 写入关机前的状态
  digitalWrite(BUILDIN_LED, ledState);
}
void loop() {
  // 读取按钮状态
  int reading = digitalRead(BUTTON_PIN);
  // 检查按钮状态是否改变
  if (reading != lastButtonState) {
    // 重制防抖计时器
    lastDebounceTime = millis();
  }
  if ((millis() - lastDebounceTime) > debounceDelay) {
   // 需要按下时间大于防抖时间,才会进入改变状态
    // 如果按钮状态改变
    if (reading != buttonState) {
      buttonState = reading;
      //只有等新的状态是LOW,才改变LED状态
      if (buttonState == LOW) {
        ledState = !ledState;
      }
    }
  }
  // 保存已经读取的状态
  lastButtonState = reading;
  // 如果LED状态盒当前状态不一样
  if (digitalRead(BUILDIN_LED)!= ledState) {
    Serial.println("State changed");
    // 改变LED状态
    digitalWrite(BUILDIN_LED, ledState);
    // 保存LED状态到EEPROM
    EEPROM.write(0, ledState);
    EEPROM.commit();
    Serial.println("State saved in flash memory");
  }
} 
								 
															



