ESP32 EEPROM 开发

最近更新于 2024-05-05 12:31

1 前言

在有些开发情景下需要使用 EEPROM,比如用于保存 WiFi 的 SSID 和 密码,且要求可以在程序运行中设置修改。
ESP32 并没有 EEPROM 硬件上的支持,但是提供了 API,可以在 FLASH 上模拟 EEPROM,默认大小为 4096 byte。

2 环境

2.1 硬件

ESP32-WROOM-32

2.2 软件

Arduino IDE 2.2.1
esp32 2.0.14(开发板)

3 探索

3.1 读写随机数

通电首先读取一遍 EEPROM,并显示出来,然后再取随机数写入 EEPROM,写完最后再读取此次写入的数据。可以断电再通电,验证开始读取到的数据和上次写入的数据是一致的。

#include <EEPROM.h>

void setup()
{
    int addr = 0;
    const int eeprom_size = 64; // 初始化的 EEPROM 大小,必须大于实际操作的大小,一般可以直接申请 4096

    Serial.begin(115200);
    Serial.println("启动......");
    delay(5000);

    if (!EEPROM.begin(eeprom_size))
    {
        Serial.println("初始化 EEPROM 失败!");
        while (1)
        {
            delay(1000);
        }
    }

    Serial.println("从 EEPROM 中读取数据:");
    for (int i = 0; i < eeprom_size; ++i)
    {
        Serial.print(byte(EEPROM.read(i)));
        Serial.print(" ");
    }
    Serial.println();

    Serial.println("正在向 EEPROM 中写入随机数据......");
    for (int i = 0; i < eeprom_size; ++i)
    {
        int val = byte(random(10020));
        EEPROM.write(addr++, val);
        Serial.print(val);
        Serial.print(" ");
    }
    EEPROM.commit(); // 写入生效

    Serial.println();
    addr = 0;

    Serial.println("读取此次写入的数据:");
    for (int i  = 0; i < eeprom_size; ++i)
    {
        Serial.print(byte(EEPROM.read(i)));
        Serial.print(" ");
    }
    Serial.println("----------------------------------");

    EEPROM.end(); // 相当于 commit 后,再加释放 EEPROM 对象
}

void loop()
{
    delay(1000);
}

file

3.2 读写各种数据类型

#include <EEPROM.h>

void setup()
{
    const int eeprom_size = 1000;

    Serial.begin(115200);
    if (!EEPROM.begin(eeprom_size))
    {
        Serial.println("初始化 EEPROM 失败!");
        while (1)
        {
            delay(1000);
        }
    }

    int address = 0;

    EEPROM.writeByte(address, -128);
    address += sizeof(byte);

    EEPROM.writeChar(address, 'A');
    address += sizeof(char);

    EEPROM.writeUChar(address, 255);
    address += sizeof(unsigned char);

    EEPROM.writeShort(address, -32768);
    address += sizeof(short);

    EEPROM.writeUShort(address, 65535);
    address += sizeof(unsigned short);

    EEPROM.writeInt(address, -2147483648);
    address += sizeof(int);

    EEPROM.writeUInt(address, 4294967295);
    address += sizeof(unsigned int);

    EEPROM.writeLong(address, -2147483648);
    address += sizeof(long);

    EEPROM.writeULong(address, 4294967295);
    address += sizeof(unsigned long);

    int64_t value = -1223372036854775808LL;
    EEPROM.writeLong64(address, value);
    address += sizeof(int64_t);

    uint64_t  Value = 18446744073709551615ULL;
    EEPROM.writeULong64(address, Value);
    address += sizeof(uint64_t);

    EEPROM.writeFloat(address, 1234.1234);
    address += sizeof(float);

    EEPROM.writeDouble(address, 123456789.123456789);
    address += sizeof(double);

    EEPROM.writeBool(address, true);
    address += sizeof(bool);

    String sentence = "我爱 ESP32。";
    EEPROM.writeString(address, sentence);
    address += sentence.length() + 1;

    char gratitude[] = "感谢乐鑫!";
    EEPROM.writeString(address, gratitude);
    address += 21;

    EEPROM.commit();
    address = 0;

    Serial.println(EEPROM.readByte(address));
    address += sizeof(byte);

    Serial.println((char)EEPROM.readChar(address));
    address += sizeof(char);

    Serial.println(EEPROM.readUChar(address));
    address += sizeof(unsigned char);

    Serial.println(EEPROM.readShort(address));
    address += sizeof(short);

    Serial.println(EEPROM.readUShort(address));
    address += sizeof(unsigned short);

    Serial.println(EEPROM.readInt(address));
    address += sizeof(int);

    Serial.println(EEPROM.readUInt(address));
    address += sizeof(unsigned int);

    Serial.println(EEPROM.readLong(address));
    address += sizeof(long);

    Serial.println(EEPROM.readULong(address));
    address += sizeof(unsigned long);

    value = 0;
    value = EEPROM.readLong64(value);
    Serial.printf("0x%08X", (uint32_t)(value >> 32));
    Serial.printf("%08X\n", (uint32_t)value);
    address += sizeof(int64_t);

    Value = 0;
    Value = EEPROM.readULong64(Value);
    Serial.printf("0x%08X", (uint32_t)(Value >> 32));
    Serial.printf("%08X\n", (uint32_t)Value);
    address += sizeof(uint64_t);

    Serial.println(EEPROM.readFloat(address), 4);
    address += sizeof(float);

    Serial.println(EEPROM.readDouble(address), 8);
    address += sizeof(double);

    Serial.println(EEPROM.readBool(address));
    address += sizeof(bool);

    Serial.println(EEPROM.readString(address));
    address += sentence.length() + 1;

    Serial.println(EEPROM.readString(address));

    EEPROM.end();
}

void loop()
{
    delay(1000);
}

file

3.3 EEPROM 对象

#include <EEPROM.h>

EEPROMClass  ec_names("eeprom0"); // 实例对象 ec_names,并命名为 eeprom0
EEPROMClass  ec_height("eeprom1");
EEPROMClass  ec_age("eeprom2");

void setup()
{
    Serial.begin(115200);

    if (!ec_names.begin(0x500)) // 初始化并设置起始地址为 0x500
    {
        Serial.println("初始化 names 失败!");
        while (1)
        {
            delay(1000);
        }
    }

    if (!ec_height.begin(0x200))
    {
        Serial.println("初始化 height 失败!");
        while (1)
        {
            delay(1000);
        }
    }

    if (!ec_age.begin(0x100))
    {
        Serial.println("初始化 age 失败!");
        while (1)
        {
            delay(1000);
        }
    }

    const char * name = "陈强";
    char rname[32];
    double height = 1.78;
    uint32_t age = 69;

    // 分别写入到三个 EEPROM 对象的 0 地址位上
    ec_names.writeString(0, name);
    ec_height.put(0, height); // put 支持泛型
    ec_age.put(0, age);
    Serial.print("name: ");
    Serial.println(name);
    Serial.print("height: ");
    Serial.println(height);
    Serial.print("age: ");
    Serial.println(age);
    Serial.println("------------------------------------\n");

    // 清空变量
    rname[0] = '\0';
    height = 0;
    age = 0;
    Serial.print("name: ");
    Serial.println(rname);
    Serial.print("height: ");
    Serial.println(height);
    Serial.print("age: ");
    Serial.println(age);
    Serial.println("------------------------------------\n");

    // 从三个 EEPROM 对象各自的零位读取
    ec_names.get(0, rname); // get 支持泛型
    ec_height.get(0, height);
    ec_age.get(0, age);
    Serial.print("name: ");
    Serial.println(rname);
    Serial.print("height: ");
    Serial.println(height);
    Serial.print("age: ");
    Serial.println(age);

    ec_names.end();
    ec_height.end();
    ec_age.end();
    Serial.println("完成!");
}

void loop()
{
    delay(0xFFFFFFFF);
}

file

ESP32 EEPROM 开发
Scroll to top