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

Забросил я уроки для начинающих, сегодня поговорим о 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; // сбрасываем триггер
>
>
Запись в ЕЕПРОМ срабатывает по отжатию кнопки единожды, когда триггер равен единице.
Объясните, что такое инициализация?
Не во всяком аппарате организован такой алгоритм.
Зачастую чистую память нужно инициализировать ручками, записывая в нее нужный код.
Вообще, само понятие «инициализации» — это создание таких условий, после которых аппарат оживает и его можно настраивать дальше, его штатными средствами.
Пример из компьютеров: если стирается флеш-БИОС, машина умирает.
Чтобы такого не происходило (а особенно это неприятно, если микросхема на пайке, а не на кровати), сейчас делают нестираемую часть прошивки, в которой записана процедура восстановления БИОС с внешнего носителя (например, у Асусов сделано так).
| Caша писал: |
| И еще – что такое флэш-память?Я знаю такие: EEPROM – 24C04,93C46 и т.п. EPROM(ПЗУ) – 27C512,27C040 и т.п. Что из этого флэш?Что такое ROM и RAM?В общем я запутался в трех соснах. |
RAM — Random Access Memory, память с произвольной выборкой, ОЗУ (оперативное запоминающее устройство). Можно писать, можно читать.
Но обесточил — и она все забыла.
ROM — Read Only Memory, память только для чтения, ПЗУ (постоянное запоминающее устройство).
ПЗУ бывают масочные (т.е., нужный код зашивается в процессе изготовления кристалла), с прожигаемыми перемычками (программируются один раз), электрически программируемые с ультрафиолетовым стиранием (программируются несколько раз, EPROM), электрически перепрограммируемые (можно перепрограммировать, не вынимая из аппаратуры, EEPROM).
Масочные — например, контроллер клавиатуры компьютера.
Там стоит однокристальный универсальный контроллер, в который зашита прямо при изготовлении микросхемы программа, обеспечивающая функцию клавиатуры.
Память с прожигаемыми перемычками существует в основном в виде программируемых логических матриц (ПЛМ), сложных дешифраторов.
Память с УФ стиранием программируется нулями, а единицы записываются сразу во все ячейки, при освещении УФ лампой.
Введение
При программировании микроконтроллеров AVR иногда возникает потребность сохранять данные, которые бы после выключения питания или сброса контроллера не изменяли свое значение. Для этих целей в составе AVR есть энергонезависимая память данных EEPROM (Electrically Erasable Programmable Read-Only Memory — электрически стираемое перепрограммируемое ПЗУ).
EEPROM имеет адресное пространство отличное от адресных пространств ОЗУ и flash памяти, в котором можно читать и записывать одиночные байты. В зависимости от модели микроконтроллера EEPROM может иметь объем от 512 байт (как, например, в микроконтроллере atmega16) до нескольких килобайт. Гарантированное количество циклов перезаписи этой памяти составляет не меньше 100000.
В этой статье на примере atmega16 мы разберемся, как работать с этим типом памяти, какие возможные проблемы при этом могут возникать и как с ними бороться.
Объявление переменных в EEPROM
Использование EEPROM начинается с объявления переменных, хранящиеся в этой памяти. Синтаксис объявления таких переменных отличается от объявлений обычных переменных (хранящихся в ОЗУ) только наличием ключевого слова. В зависимости от компилятора данное ключевое слово может разным.
Объявление переменной в EEPROM для IAR AVR и CodeVision AVR:
Объявление переменной в EEPROM для AtmelStudio 6:
Инициализация переменных в EEPROM
При объявлении переменных в EEPROM их можно инициализировать, то есть присвоить начальные значения.
Инициализацию переменных хранящихся в ОЗУ компилятор «запихивает» в начало программы микроконтроллера — перед вызовом функции main. И она выполняется каждый раз, когда на микроконтроллер подается питание или происходит его сброс.
С EEPROM переменными ситуация немного другая, их должен инициализировать сам пользователь путем программирования EEPROM специальным файлом (с расширением .eep).
Как сгенерировать файл для 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 переменные выполняется компилятором.
В AtmelStudio для чтения/записи EEPROM переменных используются специальные макросы. Они определены в файле eeprom.h. Вот некоторые из них:
Макросы принимают в качестве параметра адрес переменной размещенной в EEPROM. Для взятия адреса переменной используется оператор &. Примеры ниже поясняют использование этих макросов.
Заключение
Из этой статьи вы узнали:
— как объявить переменную в EEPROM памяти,
— как создать файл для инициализации EEPROM,
— как прочитать и записать данные в EEPROM.
В следующей статье будут разобраны регистры, используемые для чтения и записи в EEPROM, а также низкоуровневая работа с этим типом памяти.