最近更新于 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);
}
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);
}
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);
}
ESP32 EEPROM 开发