Eeprom что это за программа

Введение

При программировании микроконтроллеров AVR иногда возникает потребность сохранять данные, которые бы после выключения питания или сброса контроллера не изменяли свое значение. Для этих целей в составе AVR есть энергонезависимая память данных EEPROM (Electrically Erasable Programmable Read-Only Memory — электрически стираемое перепрограммируемое ПЗУ).
EEPROM имеет адресное пространство отличное от адресных пространств ОЗУ и flash памяти, в котором можно читать и записывать одиночные байты. В зависимости от модели микроконтроллера EEPROM может иметь объем от 512 байт (как, например, в микроконтроллере atmega16) до нескольких килобайт. Гарантированное количество циклов перезаписи этой памяти составляет не меньше 100000.
В этой статье на примере atmega16 мы разберемся, как работать с этим типом памяти, какие возможные проблемы при этом могут возникать и как с ними бороться.

Объявление переменных в EEPROM

Использование EEPROM начинается с объявления переменных, хранящиеся в этой памяти. Синтаксис объявления таких переменных отличается от объявлений обычных переменных (хранящихся в ОЗУ) только наличием ключевого слова. В зависимости от компилятора данное ключевое слово может разным.

Понятие SRAM, DRAM, ROM, PROM, EPROM, EEPROM, …

Объявление переменной в EEPROM для IAR AVR и CodeVision AVR:

//8-ми разрядная переменная
__eeprom uint8_t setting_2

//объявление массива 16-ти разрядных переменных
__eeprom uint16_t set[8];

//объявление массива и его инициализация
__eeprom uint8_t data[3] = ;

//указатель на 8-ми разрядную переменную в EEPROM, который сам хранится в RAM
uint8_t __eeprom * pSetting;

//указатель на 8-ми разрядную переменную в EEPROM, который сам храниться в EEPROM
__eeprom uint8_t __eeprom*pSetting;

Объявление переменной в EEPROM для AtmelStudio 6:


#include

//8-ми разрядная переменная в EEPROM
uint8_t setting EEMEM;

//объявление массива в EEPROM
uint16_t set[8] EEMEM;

//указатель на 8-ми разрядную переменную в EEPROM, который сам хранится в RAM
uint8_t *pSetting;

//указатель на 8-ми разрядную переменную в EEPROM, который сам храниться в EEPROM
uint8_t *pSetting EEMEM;

Инициализация переменных в EEPROM

При объявлении переменных в EEPROM их можно инициализировать, то есть присвоить начальные значения.


//для IAR AVR, CodeVision AVR
__eeprom uint8_t counter = 100;
__eeprom uint16_t data[3] = ;

//для AtmelStudio 6
uint8_t counter EEMEM = 23;
uint8_t data[3] EEMEM = ;

Инициализацию переменных хранящихся в ОЗУ компилятор «запихивает» в начало программы микроконтроллера — перед вызовом функции main. И она выполняется каждый раз, когда на микроконтроллер подается питание или происходит его сброс.
С EEPROM переменными ситуация немного другая, их должен инициализировать сам пользователь путем программирования EEPROM специальным файлом (с расширением .eep).

What Is EEPROM?


Как сгенерировать файл для EEPROM? Если в коде есть инициализация EEPROM переменных, то AtmelStudio 6 и CodeVision AVR создадут этот файл автоматически. А вот в IAR`e для этого нужно прописывать линкеру команды. Делается это так.
Меню Project > Options. >Linker вкладка Output. Устанавливаем значения по умолчанию — галочка Override default снята, формат — Debug information for C-SPY. На вкладке Extra Options ставим галочку Use Command Options и в окошке ниже прописываем такие строчки:

После компиляции и сборки проекта IAR создаст файл прошивки — .hex и файл для EEPROM`a — .eep

Полученный eep файл записывается с помощью программатора в микроконтроллер.

Чтение и запись EEPROM

В IAR`e и CodeVision AVR использование EEPROM переменных по сути ничем не отличается от использования обычных переменных (хранящихся в ОЗУ и регистрах). Вся работа по организации чтения и записи в эти EEPROM переменные выполняется компилятором.


//для IAR AVR, CodeVision AVR
__eeprom uint8_t data;
.
//читаем из EEPROM
uint8_t tmp = data;

//записываем в EEPROM
data = 129;

В AtmelStudio для чтения/записи EEPROM переменных используются специальные макросы. Они определены в файле eeprom.h. Вот некоторые из них:

uint8_t eeprom_read_byte (const uint8_t *__p) — прочитать байт
uint16_t eeprom_read_word (const uint16_t *__p) — прочитать слово (2 байта)
uint32_t eeprom_read_dword (const uint32_t *__p) — прочитать двойное слово (4 байта)

void eeprom_write_byte (uint8_t *__p, uint8_t __value) — запись байта
void eeprom_write_word (uint16_t *__p, uint16_t __value) — запись слова (2 байта)
void eeprom_write_dword (uint32_t *__p, uint32_t __value) — запись дв. слова (4 байта)

Макросы принимают в качестве параметра адрес переменной размещенной в EEPROM. Для взятия адреса переменной используется оператор «>#include

//объявляем переменные
uint8_t data EEMEM;
uint16_t pin_code EEMEM;
.
//читаем байт из eeprom
uint8_t tmp = eeprom_read_byte(

//записываем слово в eeprom
eeprom_write_word (https://chipenable.ru/index.php/programming-avr/item/158″ target=»_blank»]chipenable.ru[/mask_link]

ПРОГРАММИРОВАНИЕ МИКРОКОНТРОЛЛЕРОВ: ЕЕПРОМ

Забросил я уроки для начинающих, сегодня поговорим о EEPROM — энергонезависимой памяти.

Эта память одно из главных составляющих в функционале поделок на микроконтроллерах, любой начинающий микроконтроллерщик подходит к этапу освоения этой энергонезависимой памяти. Оно и ежу понятно, что сохранять настройки очень часто надо, нужно и без этого нельзя.

Читайте также:
Вотс апп что за программа

В даташитах все рассусолено сухим техническим языком про особенности работы еепром, я же остановлюсь на основополагающих правилах использования этой памяти, правильную на мой взгляд.

Объявляется еепром так же как и переменная, работают с еепром так же как с переменной, кроме некоторых но. Пример (Code Vision AVR):

unsigned char a; // объявляем беззнаковую переменную размером 8 бит
unsigned char eeprom eea; // объявляем «переменную» в еепром такого же типа, этого достаточно, всю остальную работу делает компилятор.

Переменную я обозвал в кавычках, ибо с ней можно обращаться как с обычной переменной, а в остальном она ведет себя по другому:

1. — значение хранимое в ЕЕПРОМ по умолчанию равно максимально возможному числу, в нашем случае после объявления в eea лежит число 255 или оно же 0xFF или оно же 0b11111111.
2- количество циклов стирания-записи у памяти ЕЕПРОМ относительно мало, поэтому нужно максимально ограничивать число записей в алгоритме программы.

Вот поучительная история про то, как фирма BLAUPUNKT лоханулась и проигнорировала второй пункт: www.audi.org.ua/materials/2954.html

3. Память ЕЕПРОМ самый тормозной тип данных, это нужно учитывать. Особенно при записи в ЕЕПРОМ. Можно получить каку, например, запихнув обработку еепром в прерываниях. В особо ответственных моментах можно использовать флаги состояния памяти ЕЕПРОМ, бывает очень полезно.

После обявления еепром и переменной я делаю команду присвоения числа из еепром в переменную, до начала основного цикла и как правило до начала работы прерываний:

После этого я верчу как хочу эту переменную, пишу в нее, читаю, используя ее в алгоритме и в нужный момент, когда нужно сохранить делаю так, чтоб данные закатились из этой переменной обратно в ЕЕПРОМ единожды:

Вот пример куска кода записи в ЕЕПРОМ:

unsigned char a; // объявляем беззнаковую переменную размером 8 бит
unsigned char eeprom eea; // объявляем еепром такого же типа,
unsigned char trig; // объявляем переменную, которая будет помнить, что кнопка нажата.

Далее идет основанная часть программы void main(void), в ней :

a=eea; // загоняем данные в с еепром в переменную

Далее идет главный цикл while(1) и в теле цикла:

if(key==1) // если кнопка настройки нажата, то:

trig=1; // включаем триггер, который запоминает, что кнопка нажата
a*b+b^2 ; //тут что то делаем нужное, когда кнопка нажата
>
else // если кнопка отжата

LED=1 ; //тут что то делаем нужное, когда кнопка отжата
if(trig) //если кнопка отжата и триггер включен, то:

eea=a; // пишем переменную а в еепром
trig=0; // сбрасываем триггер
>
>

Запись в ЕЕПРОМ срабатывает по отжатию кнопки единожды, когда триггер равен единице.

Источник: www.drive2.ru

Ардуино: память EEPROM

Как известно, сердцем Ардуино Уно является микроконтроллер фирмы Atmel — Atmega328. И как и любой микроконтроллер, Atmega328 имеет в своем составе несколько видов памяти. Каждый тип имеет свои особенности и свое предназначение.

Flash — энергонезависимая память, предназначенная для хранения программы. Эта память больше подходит для чтения данных, чем для их записи. Флэш-память в Atmega328 имеет 10 тысяч циклов перезаписи. Предполагается, что запись в эту память ведется редко, только во время создания устройства или при обновлении прошивки.

SRAM — оперативная энергозависимая память, которая нужна для хранения переменных во время работы устройства. Она очень быстрая, но полностью стирается при выключении питания.

EEPROM — энергонезависимая память, предназначенная для журналирования и хранения разного рода настроек. В отличие от Флэш памяти, она имеет 100 тысяч циклов перезаписи.

В микроконтроллере также есть регистры — это тоже память, сверхбыстрая энергозависимая, которая используется при выполнении арифметических операций, при работе с портами ввода/вывода и прочее.

Сколько памяти у Ардуино?

Размер памяти у микроконтроллера Atmega328:

  • Flash: 32 кб;
  • SRAM: 2 кб;
  • EEPROM: 1 кб;
  • регистры: в сумме 256 байт.

Для сравнения, у Ардуино Мега памяти гораздо больше:

  • Flash: 256 кб;
  • SRAM: 8 кб;
  • EEPROM: 4 кб.

Как видим, EEPROM в Arduino Уно всего 1 килобайт. Что можно хранить в таком объеме? Предположим, мы собираемся хранить значение ручек регулировки, подключенных к аналоговым входам Ардуино. Каждая такая ручка дает число от 0 до 1024 и требует 2 байта для хранения (по факту 1 байт и 2 бита, но для простоты используем 2б ), получается в EEPROM мы можем хранить значения 512 ручек настройки!

В общем, для большинства DIY проектов 1 кб EEPROM более чем достаточно. На этом уроке мы научимся записывать данные в EEPROM и считывать их оттуда.

Программа

Напишем программу, которая будет хранить значение счетчика нажатий кнопки. То есть каждый раз, когда мы нажимаем кнопку, переменная счетчика увеличивается на единицу и сохраняет свое значение в EEPROM. Чтобы проверить программу нам понадобится собрать стенд из урока про кнопки.

Для работы с EEPROM используется стандартная библиотека EEPROM.h. Запись и чтения в эту память ведется побайтово. Это значит, что за раз мы можем записать и считать число от 0 до 255. Запись одного байта осуществляется с помощью функции write:

EEPROM.write( адрес, значение );

Здесь адрес — индекс ячейки памяти, который может принимать значение от 0 до 1023. Максимальный адрес можно легко вычислить зная размер EEPROM у конкретного микроконтроллера: 1кб = 1024 байта, значит максимальный адрес 1024 — 1. Либо можно использовать функцию length — размер памяти, тогда максимальный адрес будет EEPROM.length() — 1.

Читайте также:
Google play services for instant что это за программа

Второй аргумент значение — это число, которое мы хотим сохранить в ячейке с индексом «адрес«.

Чтение байта осуществляется с помощью функции read:

EEPROM.read( адрес );

Итак, пишем программу.

#include // обязательно подключаем библиотеку const byte btnPin = 2; // это контакт, к которому подключена кнопка byte counter = 0; // переменная счетчика int addr = 0; // адрес ячейки для записи void setup() < Serial.begin(9600); // включаем порт для отладки pinMode(btnPin, INPUT); // активируем контакт за ввод // сразу после запуска программы считываем // число из EEPROM и выводим его в COM-порт byte v = EEPROM.read(addr); // считываем число из памяти Serial.print(«saved counter = «); Serial.println(v); // выводим считанное в COM-порт >void loop() < // если кнопка нажата, выполняем if( digitalRead(btnPin) == HIGH )< counter++; // увеличиваем счетчик на единицу EEPROM.write(addr, counter); // записываем счетчик Serial.print(«counter wp-block-image size-large»>Работа с EEPROM на Ардуино

Теперь отключим плату Ардуино от питания, затем снова включим и откроем монитор.

Работа с EEPROM на Ардуино

Участок кода в конце функции setup считал байт из нулевой ячейки EEPROM памяти и вывел его в порт. Работает!

Запись и чтение int и float

Что делать, если нам нужно сохранить переменную типа integer, long или float? Для этих целей в библиотеке EEPROM есть две специальные функции: put и get. Первая позволяет записать в память переменную любого типа, вторая — считать из памяти.

В отличие от однобайтовых функций write и read, в случае использования put и get легко запутаться в адресации. Так, при записи целого типа (int) с помощью put мы займем два байта памяти. И чтобы по-очереди записать два числа нужно будет прибавить к адресу двойку:

int addr = 0; // начальный адрес int v = 16555; // какое-то большое число EEPROM.put(addr, v); // записываем в ячейки 0 и 1 addr = addr + 2; EEPROM.put(addr, v);// записываем в ячейки 2 и 3

Если решим сохранить переменную типа long, то уже потребуется 4 байта. В общем, нужно всегда знать размер переменной, которую хотим разместить в EEPROM, или уметь его вычислять функцией sizeof.

Хорошим примером работы функций put и get послужит сохранение в EEPROM показаний поворотного потенциометра, подключенного к аналоговому входу Ардуино. Предположим, у нас есть прибор с одним потенциометром, с помощью которого настраиваются три коэффициента какого-нибудь PID-регулятора. Как нам уже известно, плата Ардуино Уно имеет 10-разрядный АЦП. Для чтения АЦП мы используем функцию analogWrite, которая вернет целый тип int — а это два байта.

Данная программа постоянно считывает значение с контакта A0 и при нажатии кнопки сохраняет его в EEPROM. После первого нажатия, значение сохраняется в ячейки с адресами 0,1. После второго — 2,3. После третьего — 4,5.

Работа с EEPROM на Ардуино

#include const byte btnPin = 2; const byte potPin = A0; // к этому контакту подключен потенциометр byte potIdx = 0; void setup() < Serial.begin(9600); pinMode(btnPin, INPUT); pinMode(potPin, INPUT); // считываем значения из EEPROM в цикле // сначала по адресу 0, потом 2, потом 4 // i — итератор, он же номер потенциометра Serial.println(«Read data from EEPROM»); for( byte i=0; idelay(3000); // пауза 3 секунды > void loop() < int v = analogRead(potPin); Serial.print(«v = «); Serial.println(v); if( digitalRead(btnPin) == HIGH )< EEPROM.put(potIdx*2, v); Serial.println(«Write data to EEPROM»); Serial.print(«value of pot #»); Serial.print(potIdx+1); Serial.print(» wp-block-image size-large»>

Настроив таким образом все три числа, отключим Ардуино от компьютера, а затем снова включим и откроем монитор последовательного порта.

Работа с EEPROM на Ардуино

Готово! Теперь можно не настраивать устройства каждый раз после подачи питания, а использовать EEPROM.

Надо заметить, что put и get умеют работать не только с естественными типами int, float, long, char, byte, но и со структурами. Для оценки их размера лучше использовать упомянутую функцию sizeof.

Дальше вы уже сами. Успехов!

Источник: robotclass.ru

Arduino EEPROM работа с памятью

Работа с EEPROM Arduino

EEPROM память Arduino позволяет сохранять важные данные во время работы программы, например настройки работы системы, даже при отключении питания или при перезагрузке микроконтроллера, так как она является энергонезависимой. Рассмотрим, как работать с EEPROM памятью Ардуино с примерами записи и чтения различных типов данных с помощью команд стандартной библиотеки EEPROM.h.

Arduino EEPROM энергонезависимая память

Энергонезависимая память EEPROM Arduino (Electrically Erasable Programmable Read-Only Memory) — это постоянное запоминающее устройство, которое может хранить записанные в нее данные десятки лет после отключения питания. Количество циклов перезаписи EEPROM памяти несколько сотен тысяч раз при температуре не ниже 24°С, а чтение данных не ограничено. Объем EEPROM памяти Arduino следующий:

  • ATmega168 (плата Arduino Nano) — 512 байт;
  • ATmega328 (плата Arduino Uno, Arduino Nano) — 1 Кбайт;
  • ATmega1280, ATmega2560 (плата Arduino Mega) — 4 Кбайт.

На операцию записи одного байта в EEPROM уходит около 3,3 мкс, а на чтение одного байта уходит около 0,4 мкс (микросекунд). Каждый байт (ячейка) EEPROM в Ардуино по умолчанию (т.е. ни разу не записанная ячейка) имеет значение 255. Обратите внимание, что если данные занимают место больше 1 байта (например, число больше 255), то они разбиваются на несколько ячеек. Это важно учитывать при записи в EEPROM.

Команды библиотеки EEPROM.h Arduino

Функция

Краткое описание

read()
write()
update()
get()
put()
EEPROM[]

Arduino EEPROM запись, чтение данных

Для этого занятия потребуется:

  • Arduino Uno / Arduino Nano / Arduino Mega
Читайте также:
Для чего эта программа high definition audio

Скетч. Чтение Arduino EEPROM (read)

#include EEPROM.h> // импортируем библиотеку int address; // переменная для хранения адреса byte value; // переменная для хранения значения void setup() < Serial.begin(9600); // запускаем монитор порта Serial.

println(EEPROM.length()); // выводим общее количество ячеек в памяти delay(3000); // перебираем в цикле все адреса в EEPROM памяти, пока все не переберем while (address < EEPROM.length()) < value = EEPROM.

read(address); // считываем значение байта Serial.print(«Address: «); // выводим полученные данные на монитор порта Serial.print(String(address)); Serial.print(«, value: «); Serial.println(String(value)); address++; // наращиваем адрес и повторяем операции delay(100); > > void loop()

Пояснения к коду:

  1. функция EEPROM.length() позволяет узнать общее число ячеек в памяти. Если вы работаете с Nano ATmega168, то цикл закончится на 512 ячейке;
  2. если память не использовалась, то все значения в ячейках будут равны 255.

Скетч. Запись Arduino EEPROM (write)

#include EEPROM.h> // импортируем библиотеку int address; // переменная для хранения адреса byte value; // переменная для хранения значения void setup() < Serial.begin(9600); // запускаем монитор порта Serial.

println(EEPROM.length()); // выводим общее количество ячеек в памяти EEPROM.

write(0,100); // записываем значение 100 в ячейку с адресом 0 delay(3000); // перебираем в цикле все адреса в EEPROM памяти, пока все не переберем while (address < EEPROM.length()) < value = EEPROM.

read(address); // считываем значение байта Serial.print(«Address: «); // выводим полученные данные на монитор порта Serial.print(String(address)); Serial.print(«, value: «); Serial.println(String(value)); address++; // наращиваем адрес и повторяем операции delay(100); > > void loop()

Пояснения к коду:

Пример работы предыдущей программы с EEPROM Arduino

  1. функция EEPROM.write() каждый раз перезаписывает данные в ячейке с адресом 0, что снижает жизненный цикл памяти, лучше использовать EEPROM.update() ;
  2. в следующих примерах не будем перебирать все ячейки в памяти, а запишем и прочитаем только несколько байт в энергонезависимой памяти Ардуино.

Скетч. Перезапись в Arduino EEPROM (update)

#include EEPROM.h> // импортируем библиотеку void setup() < Serial.begin(9600); // запускаем монитор порта EEPROM.

update(0,100); // записываем значение 100 в ячейку с адресом 0 delay(2000); Serial.println(EEPROM.read(0)); // выведет на монитор порта 100 Serial.println(EEPROM[0]); // выведет на монитор порта 100 > > void loop()

Пояснения к коду:

  1. вывод данных из ячейки с адресом 0 выполняется с помощью разных функций;
  2. функции write/read/update позволяют работать только с типами данных byte и использовать эти функции для данных типа float или int уже нельзя. Для этого следует использовать put/get, которые мы рассмотрим далее.

Arduino EEPROM примеры использования

Для начала рассмотрим запись в EEPROM Arduino числа больше, чем 255, например число 999. При записи в EEPROM число 999 будет разбиваться на множитель (старший байт) и недостающее число (младший байт), занимая при этом уже две ячейки в энергонезависимой памяти (т.е. 999 = 3×256 + 231). Чтобы вывести сохраненное число на монитор порта, его нужно будет «собрать» с помощью функции word() .

Скетч. Запись в память EEPROM int, float

#include EEPROM.h> // импортируем библиотеку int num = 999; // разбиваем число на 2 байта byte hi = highByte(num); // старший байт byte low = lowByte(num); // младший байт void setup() < Serial.begin(9600); // запускаем монитор порта EEPROM.

update(1, hi); // записываем старший байт в ячейку 1 EEPROM.update(2, low); // записываем младший байт в ячейку 2 delay(1000); byte val1 = EEPROM.

read(1); // считываем 1 байт по адресу ячейки byte val2 = EEPROM.read(2); // считываем 1 байт по адресу ячейки Serial.println(«highByte — «+String(val1)); // выводим старший байт на монитор Serial.println(«lowByte — «+String(val2)); // выводим младший байт на монитор int NUM = word(hi, low); // «собираем» число из байтов Serial.println(«int num — «+String(NUM)); // выводим полученное число > void loop()

Пояснения к коду:

  1. для записи данных в ячейку в программе использована функция EEPROM.update() , которая перезаписывает ячейку только в случае различия сохраняемых данных с данными в ячейке EEPROM Arduino Uno;
  2. основная проблема с сохранением больших чисел (int, float) в память EEPROM заключается в том, чтобы случайно не перезаписать нужную ячейку новой информацией. Для этого нужно учитывать размер сохраняемых данных в ПЗУ, используя функции EEPROM.put() и EEPROM.get() .

Скетч. Запись строк в EEPROM (String)

Пояснения к коду:

  1. перед сохранением новых данных в памяти, следует узнать размер данных, которые были сохранены, чтобы начать запись в новой ячейке;
  2. удалив из кода строчки для записи данных, вы можете каждый раз при запуске программы считывать все сохраненные данные из ПЗУ Ардуино.

Скетч. Очистка EEPROM Arduino

Чтобы стереть энергонезависимую память ЕЕПРОМ Ардуино и вернуть ее к заводским настройкам следует перезаписать все ячейки в памяти с числом 255. Для этого можно использовать цикл for или while. Простой пример с программой очистки EEPROM Ардуино приведен ниже. Если у вас остались вопросы по работе с EEPROM памятью на Ардуино, то оставляйте их в комментариях к этой записи.

#include EEPROM.h> // импортируем библиотеку int address; // переменная для хранения адреса void setup() < // перезаписываем в цикле все адреса в ЕЕПРОМ памяти while (address < EEPROM.length()) < EEPROM.update(address, 255); address++; > > void loop()

Пояснения к коду:

  1. все ячейки, если они отличаются от 255, автоматически перезапишутся;
  2. функция EEPROM.put() , как и EEPROM.update() перезаписывает ячейку лишь когда данные отличаются, экономя ресурс памяти еепром Ардуино.

Источник: xn--18-6kcdusowgbt1a4b.xn--p1ai

Рейтинг
( Пока оценок нет )
Загрузка ...
EFT-Soft.ru