Сохранение значения в EEPROM в Arduino Uno

Привет, я новичок в Arduino Uno. Я хотел сохранить значение 77880 в EEPROM и получить его позже. Я сделал код следующим образом, чтобы проверить свою логику (я использую Arduino Uno):

#include <EEPROM.h>
int addr = 0;
byte value;
void setup() {
  // put your setup code here, to run once:
  int val = 77880;
  EEPROM.write(addr, val);
  Serial.begin(57600);
}

void loop() {
  // put your main code here, to run repeatedly:
  value = EEPROM.read(addr);

  Serial.print(addr);
  Serial.print("\t");
  Serial.print(value);
  Serial.println();
  delay(1000);
}

но я не получаю значение 77880, когда читаю адрес EEPROM. вместо этого я получаю значение 56 в своем последовательном выводе. Может ли кто-нибудь объяснить, как мне реализовать то же самое?

, 👍1


2 ответа


Лучший ответ:

2

EEPROM может хранить значения 0–255 только по одному адресу. Это максимальный диапазон 8-битного значения и "ячеек" EEPROM. имеют 8-битный размер.

Вам придется разделить значение на несколько 8-битных фрагментов и сохранить каждый фрагмент по другому адресу, например, для 32-битных значений, которые вы можете использовать:

uint32_t val = 77880; // В шестнадцатеричном формате 0x13038
int addr = 0;
EEPROM.write(addr, val & 0xFF); // Сохраняет 0x38 по адресу 0
EEPROM.write(addr + 1, (val >> 8) & 0xFF); // Сохраняет 0x30 по адресу 1
EEPROM.write(addr + 2, (val >> 16) & 0xFF); // Сохраняет 0x01 по адресу 2
EEPROM.write(addr + 3, (val >> 24) & 0xFF); // Сохраняет 0x00 по адресу 3

Затем, чтобы прочитать, вы делаете обратное и сдвигаете значения и выполняете ИЛИ над ними:

uint32_t val = (uint32_t)EEPROM.read(addr) |
               ((uint32_t)EEPROM.read(addr + 1) << 8) |
               ((uint32_t)EEPROM.read(addr + 2) << 16) |
               ((uint32_t)EEPROM.read(addr + 3) << 24);

В качестве альтернативы в библиотеке EEPROM есть функция "хранить что угодно" помощник сделает это за вас:

EEPROM.put(addr, val); 

Таким образом, переменная val будет храниться в достаточном количестве ячеек для ее размещения (4 в случае 32-разрядной переменной), поэтому вы должны знать, что не следует выполнять запись в другие используемые ею ячейки ( 0, 1, 2 и 3 в данном случае), иначе вы испортите свои данные.

Вы вспоминаете это с помощью:

EEPROM.get(addr, val);
,

Спасибо за быстрый ответ, @Jaivishnu


0

См. ответ Маженко, почему у вас возникла проблема. Это альтернативное решение проблемы.

Использование библиотеки Arduino для EEPROM очень ограничено. Он может читать/записывать только один байт за раз. Ваша переменная val имеет тип int, который представляет собой 16-битное целое число в uno. Итак, два байта, которые также называются word.

Я использую AVR EEPROM "библиотеку" напрямую.

#include <avr/eeprom.h>

EEMEM int eepVariable; // использование EEMEM заставит компилятор обрабатывать расположение в EEPROM за вас
                           // компилятор следит за тем, чтобы никакие данные не перекрывались внутри EEPROM.

int value; // тоже должно быть `int`.
void setup() {
  // поместите сюда код установки для однократного запуска:
  int val = 77880;
  eeprom_write_word(&eepVariable, val);
  Serial.begin(57600);
}

void loop() {
  // поместите сюда ваш основной код для многократного запуска:
  value = eeprom_read_word(&eepVariable);

  Serial.print(value);
  Serial.println();
  delay(1000);
}
,

«Использование библиотеки Arduino для EEPROM очень ограничено». Вы можете не знать, но это не было правдой в течение многих лет. См. EEPROM.put(). Вы можете написать любой тип. Библиотека Arduino EEPROM также позволяет вам обращаться к EEPROM, как если бы это был массив, используя перегруженный operator[], что иногда очень удобно. Библиотека Arduino EEPROM также не будет вызывать излишнего износа. Он только обновляет значения. Он не будет перезаписывать байты, если они уже являются тем, что вы пишете. Именно по этим причинам я рекомендую использовать библиотеку Arduino EEPROM., @Gabriel Staples