11. Энергонезависимая память EEPROM
EEPROM — (Electrically Erasable Programmable Read-Only Memory) электрически стираемое перепрограммируемое ПЗУ, ЭСППЗУ). Память такого типа может стираться и заполняться данными несколько десятков тысяч раз. Используется в твердотельных накопителях. Одной из разновидностей EEPROM является флеш-память (Flash Memory).
Микроконтроллеры Atmega8 и Atmega168, работающие в Arduino имеют на борту 512 байт EEPROM – энергонезависимой памяти, в которой можно сохранять какие-либо данные, которые будут доступны после отключения питания.
Это может пригодиться для хранения каких-нибудь данных или значений.
Для работы с данной памятью в составе Arduino IDE уже есть удобная библиотека EEPROM (\hardware\libraries\EEPROM\).
Библиотека содержит всего две функции – чтения и записи данных 🙂
class EEPROMClass { public: uint8_t read(int); void write(int, uint8_t); }; extern EEPROMClass EEPROM;
byte EEPROM.read(address)
Описание:
Считывает байт из энергонезависимой памяти EEPROM. Если байт до этого никогда не перезаписывался – вернёт значение 255.
Параметры:
address: порядковый номер ячейки памяти для чтения — от 0 до 511 (int)
Возвращаемое значение:
Байт, хранимый в ячейке памяти.
Пример (File-Examples-EEPROM-eeprom_read):
/* * Чтение EEPROM * * Считывает значения всех байтов энергонезависимой памяти * EEPROM и выводит их в COM-порт */ #include <EEPROM.h> // начальный адрес памяти EEPROM int address = 0; byte value; void setup() { Serial.begin(9600); } void loop() { // считываем значение по текущему адресу EEPROM value = EEPROM.read(address); Serial.print(address); Serial.print("\t"); Serial.print(value, DEC); Serial.println(); // устанавливаем следующую ячейку памяти address = address + 1; // EEPROM содержит всего 512 байт: от 0 до 511, поэтому // если адрес достиг 512, то снова переходим на 0 if (address == 512) address = 0; delay(500); }
void EEPROM.write(address, value)
Описание:
Записывает байт в энергонезависимую память
Параметры:
address: порядковый номер ячейки памяти для записи — от 0 до 511 (int)
value: байт для записи – от 0 до 255 (byte)
Возвращаемое значение:
ничего
Примечание:
Документация (datasheet) на микроконтроллеры Atmega8/168 говорит, что возможное количество циклов перезаписи данных в памяти ограничено 100000 раз (Write/Erase Cycles). Это следует учитывать при использовании данной памяти.
Так же документация указывает, что время, требуемое для завершения цикла записи составляет 3.3 ms. Если в это время попытаться что-либо считать/записать в EEPROM, то такая попытка окончится неудачей 🙁
Однако, данная задержка уже учитывается библиотекой EEPROM, поэтому в дополнительном вызове delay() нет необходимости.
Пример (File-Examples-EEPROM-eeprom_write):
/* * EEPROM Write * * Сохраняет в энергонезависимой памяти EEPROM значения, * считанные с аналогового входа analog input 0. * Данные значения останутся в памяти и после отключения питания * от платы и в будущем могут быть доступны для * другого скетча. */ #include <EEPROM.h> // текущее значение адреса EEPROM int addr = 0; void setup() { } void loop() { // деление на 4 необходимо, чтобы перевести значение от // 0-1023 к одному байту, т.к. EEPROM может хранить только // значения от 0 до 255. int val = analogRead(0) / 4; // записываем значение в энергонезависимую память EEPROM.write(addr, val); // устанавливаем следующую ячейку памяти. // т.к. EEPROM содержит всего 512 ячеек – при достижении // конца памяти – возвращаемся на начало :) addr = addr + 1; if (addr == 512) addr = 0; delay(100); }
В примере eeprom_clear (File-Examples-EEPROM-eeprom_clear)
показано, как произвести очистку памяти – просто заполнить её нулями:
// записываем 0 во все 512 байт памяти EEPROM for (int i = 0; i < 512; i++) EEPROM.write(i, 0);
Пример. EEPROM - чтение/запись int
#include <EEPROM.h> //Needed to access the eeprom read write functions //This function will write a 2 byte integer to the eeprom at the specified address and address + 1 void EEPROMWriteInt(int p_address, int p_value) { byte lowByte = ((p_value >> 0) & 0xFF); byte highByte = ((p_value >> 8) & 0xFF); EEPROM.write(p_address, lowByte); EEPROM.write(p_address + 1, highByte); } //This function will read a 2 byte integer from the eeprom at the specified address and address + 1 unsigned int EEPROMReadInt(int p_address) { byte lowByte = EEPROM.read(p_address); byte highByte = EEPROM.read(p_address + 1); return ((lowByte << 0) & 0xFF) + ((highByte << 8) & 0xFF00); } void setup() { Serial.begin(9600); EEPROMWriteInt(0, 0xABCD); Serial.print("Read the following int at the eeprom address 0: "); Serial.println(EEPROMReadInt(0), HEX); } void loop() { }
читать далее: 12. Создание своей библиотеки
Ссылки
http://www.arduino.cc/en/Reference/EEPROM
http://ru.wikipedia.org/wiki/EEPROM
Implementation of an eeprom integer read / write
5 комментариев на «“Программирование Arduino — EEPROM”»
А сюда бы ещё хорошо пример как записывать и считывать int
Это понятно. Просто этот пример хорошо бы сразу в статью )
Типы данных в Arduino: https://learn.sparkfun.com/tutorials/data-types-in-arduino
Должно вот так работать:
return (highByte << 8) | lowByte;
есть ли способ записи, чтобы уменьшить износ ячеек памяти?
программа пишет нужное значение в ПЗУ в ячейку 0, потом оттуда при необходимости считывает остальная пзу свободна. можно сделать так: ищем ячейку где не нулевое значение, считываем. когда нужно записать число, то в предыдущую пишем 0, адрес для чтения сдвигаем на 1.
Объясните пожалуйста, зачем в данном случае
нужны битовые маски 0xFF и 0xFF00? разве без них не получится то же самое?