当前位置:   article > 正文

ESP32-EEPROM存储_esp32的eeprom存储

esp32的eeprom存储

EEPROM前言

  在EPS32中已经将EEPROM弃用。对于ESP32上的新应用程序,建议使用NVS为首选项。提供EEPROM是为了向后兼容现有的Arduino应用程序。EEPROM是使用NVS中的单个blob实现的,因此它是容器(Flash)中的容器(NVS)(弟中弟)。因此,它不会是一种高性能存储方法。首选项将直接使用nvs,并将每个条目存储为其中的单个对象。所以现在的EEPROM也仅是在函数功能上向后兼容,实际储存方式已经完全变了,这需要我们在实际应用中注意。NVS小知识链接

主要API介绍

  1. bool begin(size_t size); // 开启一块分区访问存储
  2. uint8_t read(int address); // 读取指定地址数据
  3. void write(int address, uint8_t val); // 在指定地址保存数据
  4. uint16_t length(); // 获取申请的分区大小
  5. bool commit(); // 将数据从缓存区存入flash中
  6. void end(); // 结束访问

  在实际应用中主要思路是,先申明begin(想要保存的数据大小),再利用write(地址偏移,单个字符数据0-255),当所有数据通过write写完后,一定要记得中commit()提交,使数据从暂存区保存到flash中,实现掉电保护。read的使用直接利用地址偏移可以直接读出数据。

例子1(随机数的保存)

  1. #include <Arduino.h>
  2. #include "EEPROM.h"
  3. // the current address in the EEPROM (i.e. which byte
  4. // we're going to write to next)
  5. int addr = 0;
  6. #define EEPROM_SIZE 64
  7. void setup()
  8. {
  9. Serial.begin(115200);
  10. Serial.println("start...");
  11. if (!EEPROM.begin(EEPROM_SIZE))
  12. {
  13. Serial.println("failed to initialise EEPROM"); delay(1000000);
  14. }
  15. Serial.println(" bytes read from Flash . Values are:");
  16. for (int i = 0; i < EEPROM_SIZE; i++)
  17. {
  18. Serial.print(byte(EEPROM.read(i))); Serial.print(" ");
  19. }
  20. Serial.println();
  21. Serial.println("writing random n. in memory");
  22. }
  23. void loop()
  24. {
  25. // need to divide by 4 because analog inputs range from
  26. // 0 to 1023 and each byte of the EEPROM can only hold a
  27. // value from 0 to 255.
  28. // int val = analogRead(10) / 4;
  29. int val = byte(random(10020));
  30. // write the value to the appropriate byte of the EEPROM.
  31. // these values will remain there when the board is
  32. // turned off.
  33. EEPROM.write(addr, val);
  34. Serial.print(val); Serial.print(" ");
  35. // advance to the next address. there are 512 bytes in
  36. // the EEPROM, so go back to 0 when we hit 512.
  37. // save all changes to the flash.
  38. addr = addr + 1;
  39. if (addr == EEPROM_SIZE)
  40. {
  41. Serial.println();
  42. addr = 0;
  43. EEPROM.commit();
  44. Serial.print(EEPROM_SIZE);
  45. Serial.println(" bytes written on Flash . Values are:");
  46. for (int i = 0; i < EEPROM_SIZE; i++)
  47. {
  48. Serial.print(byte(EEPROM.read(i))); Serial.print(" ");
  49. }
  50. Serial.println(); Serial.println("----------------------------------");
  51. }
  52. delay(100);
  53. }

特殊API直接调用

  前面的写入与读取只能是单字符的读取与写入,官方为了方便调用,还提供了对于各数据类型的支持:

  1. uint8_t readByte(int address);
  2. int8_t readChar(int address);
  3. uint8_t readUChar(int address);
  4. int16_t readShort(int address);
  5. uint16_t readUShort(int address);
  6. int32_t readInt(int address);
  7. uint32_t readUInt(int address);
  8. int32_t readLong(int address);
  9. uint32_t readULong(int address);
  10. int64_t readLong64(int address);
  11. uint64_t readULong64(int address);
  12. float_t readFloat(int address);
  13. double_t readDouble(int address);
  14. bool readBool(int address);
  15. size_t readString(int address, char* value, size_t maxLen);
  16. String readString(int address);
  17. size_t readBytes(int address, void * value, size_t maxLen);
  18. template <class T> T readAll (int address, T &);
  19. size_t writeByte(int address, uint8_t value);
  20. size_t writeChar(int address, int8_t value);
  21. size_t writeUChar(int address, uint8_t value);
  22. size_t writeShort(int address, int16_t value);
  23. size_t writeUShort(int address, uint16_t value);
  24. size_t writeInt(int address, int32_t value);
  25. size_t writeUInt(int address, uint32_t value);
  26. size_t writeLong(int address, int32_t value);
  27. size_t writeULong(int address, uint32_t value);
  28. size_t writeLong64(int address, int64_t value);
  29. size_t writeULong64(int address, uint64_t value);
  30. size_t writeFloat(int address, float_t value);
  31. size_t writeDouble(int address, double_t value);
  32. size_t writeBool(int address, bool value);
  33. size_t writeString(int address, const char* value);
  34. size_t writeString(int address, String value);
  35. size_t writeBytes(int address, const void* value, size_t len);
  36. template <class T> T writeAll (int address, const T &);

例子2(各数据类型)

  1. #include <Arduino.h>
  2. #include "EEPROM.h"
  3. void setup() {
  4. // put your setup code here, to run once:
  5. Serial.begin(115200);
  6. Serial.println("\nTesting EEPROM Library\n");
  7. if (!EEPROM.begin(1000)) {
  8. Serial.println("Failed to initialise EEPROM");
  9. Serial.println("Restarting...");
  10. delay(1000);
  11. ESP.restart();
  12. }
  13. int address = 0;
  14. EEPROM.writeByte(address, -128); // -2^7
  15. address += sizeof(byte);
  16. EEPROM.writeChar(address, 'A'); // Same as writyByte and readByte
  17. address += sizeof(char);
  18. EEPROM.writeUChar(address, 255); // 2^8 - 1
  19. address += sizeof(unsigned char);
  20. EEPROM.writeShort(address, -32768); // -2^15
  21. address += sizeof(short);
  22. EEPROM.writeUShort(address, 65535); // 2^16 - 1
  23. address += sizeof(unsigned short);
  24. EEPROM.writeInt(address, -2147483648); // -2^31
  25. address += sizeof(int);
  26. EEPROM.writeUInt(address, 4294967295); // 2^32 - 1
  27. address += sizeof(unsigned int);
  28. EEPROM.writeLong(address, -2147483648); // Same as writeInt and readInt
  29. address += sizeof(long);
  30. EEPROM.writeULong(address, 4294967295); // Same as writeUInt and readUInt
  31. address += sizeof(unsigned long);
  32. int64_t value = -1223372036854775808LL; // -2^63
  33. EEPROM.writeLong64(address, value);
  34. address += sizeof(int64_t);
  35. uint64_t Value = 18446744073709551615ULL; // 2^64 - 1
  36. EEPROM.writeULong64(address, Value);
  37. address += sizeof(uint64_t);
  38. EEPROM.writeFloat(address, 1234.1234);
  39. address += sizeof(float);
  40. EEPROM.writeDouble(address, 123456789.123456789);
  41. address += sizeof(double);
  42. EEPROM.writeBool(address, true);
  43. address += sizeof(bool);
  44. String sentence = "I love ESP32.";
  45. EEPROM.writeString(address, sentence);
  46. address += sentence.length() + 1;
  47. char gratitude[21] = "Thank You Espressif!";
  48. EEPROM.writeString(address, gratitude);
  49. address += 21;
  50. // See also the general purpose writeBytes() and readBytes() for BLOB in EEPROM library
  51. EEPROM.commit();
  52. address = 0;
  53. Serial.println(EEPROM.readByte(address));
  54. address += sizeof(byte);
  55. Serial.println((char)EEPROM.readChar(address));
  56. address += sizeof(char);
  57. Serial.println(EEPROM.readUChar(address));
  58. address += sizeof(unsigned char);
  59. Serial.println(EEPROM.readShort(address));
  60. address += sizeof(short);
  61. Serial.println(EEPROM.readUShort(address));
  62. address += sizeof(unsigned short);
  63. Serial.println(EEPROM.readInt(address));
  64. address += sizeof(int);
  65. Serial.println(EEPROM.readUInt(address));
  66. address += sizeof(unsigned int);
  67. Serial.println(EEPROM.readLong(address));
  68. address += sizeof(long);
  69. Serial.println(EEPROM.readULong(address));
  70. address += sizeof(unsigned long);
  71. value = 0;
  72. value = EEPROM.readLong64(value);
  73. Serial.printf("0x%08X", (uint32_t)(value >> 32)); // Print High 4 bytes in HEX
  74. Serial.printf("%08X\n", (uint32_t)value); // Print Low 4 bytes in HEX
  75. address += sizeof(int64_t);
  76. Value = 0; // Clear Value
  77. Value = EEPROM.readULong64(Value);
  78. Serial.printf("0x%08X", (uint32_t)(Value >> 32)); // Print High 4 bytes in HEX
  79. Serial.printf("%08X\n", (uint32_t)Value); // Print Low 4 bytes in HEX
  80. address += sizeof(uint64_t);
  81. Serial.println(EEPROM.readFloat(address), 4);
  82. address += sizeof(float);
  83. Serial.println(EEPROM.readDouble(address), 8);
  84. address += sizeof(double);
  85. Serial.println(EEPROM.readBool(address));
  86. address += sizeof(bool);
  87. Serial.println(EEPROM.readString(address));
  88. address += sentence.length() + 1;
  89. Serial.println(EEPROM.readString(address));
  90. address += 21;
  91. }
  92. void loop() {
  93. // put your main code here, to run repeatedly:
  94. }

初步展现底层:

  前面提到过,在目前的ESP32中并没有EEPROM,而是利用NVS模拟出来的,仅是了程序的向后兼容性,而前面的程序中的EEPROM储存空间也仅仅是NVS的单个blob实现的,也就是说我们可以创造多个EEPROM来存储数据。

  在EEPROMClass类中,有三个:

        EEPROMClass(uint32_t sector);
        EEPROMClass(const char* name, uint32_t user_defined_size);
        EEPROMClass(void);

  程序在默认状态下使用的是最后一个:extern EEPROMClass EEPROM;而从定义中,我们可知这个类是可以指定名称与大小的。

  且提供了函数get与put用于保存数据与读取:

  1. template<typename T>
  2. T &get(int address, T &t) {
  3. if (address < 0 || address + sizeof(T) > _size)
  4. return t;
  5. memcpy((uint8_t*) &t, _data + address, sizeof(T));
  6. return t;
  7. }
  8. template<typename T>
  9. const T &put(int address, const T &t) {
  10. if (address < 0 || address + sizeof(T) > _size)
  11. return t;
  12. memcpy(_data + address, (const uint8_t*) &t, sizeof(T));
  13. _dirty = true;
  14. return t;
  15. }

 

例子(对EEPROMClass的调用):

  1. #include <Arduino.h>
  2. #include "EEPROM.h"
  3. // Instantiate eeprom objects with parameter/argument names and sizes
  4. EEPROMClass NAMES("eeprom0", 0x500);
  5. EEPROMClass HEIGHT("eeprom1", 0x200);
  6. EEPROMClass AGE("eeprom2", 0x100);
  7. void setup() {
  8. Serial.begin(9600);
  9. Serial.println("Testing EEPROMClass\n");
  10. if (!NAMES.begin(NAMES.length())) {
  11. Serial.println("Failed to initialise NAMES");
  12. Serial.println("Restarting...");
  13. delay(1000);
  14. ESP.restart();
  15. }
  16. if (!HEIGHT.begin(HEIGHT.length())) {
  17. Serial.println("Failed to initialise HEIGHT");
  18. Serial.println("Restarting...");
  19. delay(1000);
  20. ESP.restart();
  21. }
  22. if (!AGE.begin(AGE.length())) {
  23. Serial.println("Failed to initialise AGE");
  24. Serial.println("Restarting...");
  25. delay(1000);
  26. ESP.restart();
  27. }
  28. const char* name = "Teo Swee Ann";
  29. char rname[32];
  30. double height = 5.8;
  31. uint32_t age = 47;
  32. // Write: Variables ---> EEPROM stores
  33. NAMES.put(0, name);
  34. HEIGHT.put(0, height);
  35. AGE.put(0, age);
  36. Serial.print("name: "); Serial.println(name);
  37. Serial.print("height: "); Serial.println(height);
  38. Serial.print("age: "); Serial.println(age);
  39. Serial.println("------------------------------------\n");
  40. // Clear variables
  41. name = '\0';
  42. height = 0;
  43. age = 0;
  44. Serial.print("name: "); Serial.println(name);
  45. Serial.print("height: "); Serial.println(height);
  46. Serial.print("age: "); Serial.println(age);
  47. Serial.println("------------------------------------\n");
  48. // Read: Variables <--- EEPROM stores
  49. NAMES.get(0, rname);
  50. HEIGHT.get(0, height);
  51. AGE.get(0, age);
  52. Serial.print("name: "); Serial.println(rname);
  53. Serial.print("height: "); Serial.println(height);
  54. Serial.print("age: "); Serial.println(age);
  55. Serial.println("Done!");
  56. }
  57. void loop() {
  58. delay(0xFFFFFFFF);
  59. }

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/461765
推荐阅读
  

闽ICP备14008679号