创客出手

目录

在ESP32使用EEPROM断电保存数据

ESP32_EEPROM

什么是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具有以下特点:

  1. 容量:ESP32的EEPROM容量为512bytes,也就是4kb,虽然不大,但足够存储程序的配置数据。这意味着你可以在512个地址上储存一个0-255的数值。

  2. 可编程性:ESP32的EEPROM可以通过简单几段代码实现运行时进行读写操作,非常方便。

  3. 寿命:ESP32的EEPROM寿命很长,经过1万次擦写后,依然可以保持良好的性能。

  4. 安全性:ESP32的EEPROM支持加密和校验功能,可以确保数据的安全性和完整性。

ESP32 EEPROM的使用方法

  1. 我们使用Arduino的EEPROM库来访问ESP的内部EEPROM储存空间。方法非常简单,只要先引入头文件。该库已经被假如到esp32点Arduino框架,因此不用安装额外的库就能直接使用。
    #include <EEPROM.h>
  2. 初始化EEPROM需要先定义EEPROM容量大小。如果要增加EEPROM的纪录内容,千万不要忘记修改大小,因为即使你的使用地址超出了容量,也没有报错提示。
    #define EEPROM_SIZE 10
    ...
    void setup() {
    EEPROM.begin(EEPROM_SIZE);
    ...
    }
  3. 写数据到EEPROM,具体格式为:EEPROM.write(<地址>, <数值>), 其中地址是你定义的大小范围内的地址,从零开始,数值是0-255的数值,例如:
    EEPROM.write(0, 132);
  4. 从EEPROM读取数据,具体格式为:EEPROM.read(<地址>), 其中地址是你之前写入数据的地址,返回一个0-255的无符号整数,uint8_t. 如果在读取前没有被写入数值,默认值为255。
    uint8_t value = EEPROM.read(0);
  5. 除了无符号整数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");
  }
}
更多关于 的文章
关注创客出手公众号

关注创客出手