CraftDuino v2.0
  • - это CraftDuino - наш вариант полностью Arduino-совместимой платы.
  • CraftDuino - настоящий конструктор, для очень быстрого прототипирования и реализации идей.
  • Любая возможность автоматизировать что-то с лёгкостью реализуется с CraftDuino!
Просто добавьте CraftDuino!

Программирование Arduino - EEPROM

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
  • +1
  • 31 августа 2009, 13:42
  • admin

Комментарии (6)

RSS свернуть / развернуть
+
0
А сюда бы ещё хорошо пример как записывать и считывать int
avatar

savarez

  • 12 августа 2010, 17:35
+
0
Это понятно. Просто этот пример хорошо бы сразу в статью )
avatar

savarez

  • 10 сентября 2011, 12:22
+
0
Объясните пожалуйста, зачем в данном случае
return ((lowByte << 0) & 0xFF) + ((highByte << 8) & 0xFF00);
нужны битовые маски 0xFF и 0xFF00? разве без них не получится то же самое?
avatar

nes

  • 3 октября 2012, 18:40
+
0
Типы данных в Arduino: https://learn.sparkfun.com/tutorials/data-types-in-arduino

Должно вот так работать:
return (highByte << 8) | lowByte;
avatar

dontsov

  • 23 февраля 2015, 20:58
+
0
есть ли способ записи, чтобы уменьшить износ ячеек памяти?
программа пишет нужное значение в ПЗУ в ячейку 0, потом оттуда при необходимости считывает остальная пзу свободна. можно сделать так: ищем ячейку где не нулевое значение, считываем. когда нужно записать число, то в предыдущую пишем 0, адрес для чтения сдвигаем на 1.
avatar

Begemot911

  • 23 июля 2015, 10:18

Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.