ESP32如何在EEPROM中存储用户名密码字符串对数组?
ESP32 EEPROM存储用户名密码字符串对数组的正确实现方式
ESP32没有物理EEPROM,它的EEPROM功能是通过模拟Flash分区实现的,操作逻辑和传统EEPROM类似,但要注意Flash的擦写寿命限制。下面是实现用户名密码字符串对数组存储的完整方案:
1. 规划存储结构
先定义固定格式的结构体存储单组用户名密码,同时记录字符串实际长度(避免读取时处理冗余空字符):
#include <EEPROM.h> // 定义单组凭证的结构体,可按需调整用户名/密码的最大长度 typedef struct { uint8_t username_len; // 用户名实际长度(1字节,支持最多255字符) char username[20]; // 用户名缓存,最大20字符 uint8_t password_len; // 密码实际长度 char password[20]; // 密码缓存,最大20字符 } UserCredential; // 定义要存储的凭证数量,计算所需EEPROM总大小 #define USER_COUNT 3 #define EEPROM_SIZE (USER_COUNT * sizeof(UserCredential))
2. 初始化EEPROM
在setup()中初始化EEPROM,指定总大小:
void setup() { Serial.begin(115200); // 初始化EEPROM,大小为所有凭证的总字节数 if (!EEPROM.begin(EEPROM_SIZE)) { Serial.println("EEPROM初始化失败"); while (1); } }
3. 写入凭证数组
编写函数批量写入多组用户名密码到EEPROM,用EEPROM.put()直接写入结构体(自动处理字节序列化):
void saveUserCredentials(UserCredential* credentials, int count) { if (count > USER_COUNT) { Serial.println("超出最大存储数量"); return; } for (int i = 0; i < count; i++) { // 计算当前凭证在EEPROM中的起始地址 int addr = i * sizeof(UserCredential); // 写入结构体到指定地址 EEPROM.put(addr, credentials[i]); } // 必须调用commit()才能将缓存写入Flash if (EEPROM.commit()) { Serial.println("凭证存储成功"); } else { Serial.println("凭证存储失败"); } }
4. 读取凭证数组
编写函数从EEPROM读取所有存储的凭证:
void loadUserCredentials(UserCredential* credentials, int count) { if (count > USER_COUNT) { Serial.println("超出最大存储数量"); return; } for (int i = 0; i < count; i++) { int addr = i * sizeof(UserCredential); // 从指定地址读取结构体 EEPROM.get(addr, credentials[i]); } Serial.println("凭证读取完成"); }
5. 使用示例
在主程序中调用函数进行存储和读取:
void loop() { // 示例:准备要存储的凭证数组 UserCredential users[USER_COUNT] = { {6, "admin", 8, "admin123"}, {5, "user1", 6, "123456"}, {5, "user2", 6, "654321"} }; // 存储凭证(仅首次运行或修改后调用,避免频繁写入Flash) saveUserCredentials(users, USER_COUNT); // 读取凭证 UserCredential loadedUsers[USER_COUNT]; loadUserCredentials(loadedUsers, USER_COUNT); // 打印读取结果 for (int i = 0; i < USER_COUNT; i++) { Serial.printf("用户%d: 用户名=%.*s, 密码=%.*s\n", i+1, loadedUsers[i].username_len, loadedUsers[i].username, loadedUsers[i].password_len, loadedUsers[i].password); } // 避免重复执行,进入死循环 while (1); }
关键注意事项
- Flash擦写寿命:ESP32的模拟EEPROM依赖Flash,擦写寿命约10万次,不要频繁调用
commit()(比如不要放在loop里循环执行)。 - 数据完整性:可以在结构体中添加CRC校验位,读取时验证数据是否损坏。
- 边界检查:写入字符串时要确保实际长度不超过定义的缓存大小,避免数组溢出。
- 首次初始化:首次运行时,EEPROM中的数据是随机的,可以在结构体中添加一个标记位(比如
uint8_t magic = 0xAA),读取时先检查标记位是否有效,无效则写入默认凭证。
内容的提问来源于stack exchange,提问作者Nico Hennrich
相关产品推荐
相关产品推荐

