什么是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");
}
}