Работа с EEPROM памятью. Eeprom что это такое

Советы и вопросы
Eeprom что это такое - Видео Анализ требований и дизайн EEPROM.h + avr/eeprom.h Скетч. Перезапись в Arduino EEPROM (update) О чипах – микросхемах хранения информации

Чтобы компенсировать этот недостаток, чипы подобные AT28C256, оснащаются функцией блочного программирования. При таком подходе к программированию, одновременно (блоком) загружаются 64, 128 или 256 байт. Блочный способ сокращает время программирования.

Как хранить данные в Arduino

У плат семейства плат Arduino есть несколько видов памяти. Во-первых, это статическое ОЗУ (оперативное запоминающее устройство), которая используется для хранения переменных в процессе выполнения программы. Во-вторых, это флеш-память, в которой хранятся написанные вами скетчи. И в-третьих, это EEPROM, которую можно использовать для постоянного хранения информации. Первый тип памяти – энергозависимый, он теряет всю информацию после перезагрузки Arduino. Вторые два типа памяти хранят информацию пока она не будет перезаписана новой, даже после отключения питания. Последний тип памяти – EEPROM – позволяет записывать данные, хранить их и считывать при необходимости. Эту память мы и рассмотрим сейчас.

Инструкция по использованию EEPROM в Arduino

EEPROM означает Electrically Erasable Programmable Read-Only Memory, т.е. электрически стираемое перепрограммируемое постоянное запоминающее устройство. Данные в этой памяти могут храниться десятки лет после отключения питания. Количество циклов перезаписи – порядка нескольких миллионов раз.

  • для плат, основанных на микроконтроллере ATmega328 (например, Arduino UNO и Nano), количество памяти составляет 1 кБ,
  • для плат на ATmega168 и ATmega8 – 512 байт,
  • на ATmega2560 и ATmega1280 – 4 кБ.

Тип памяти серии 27… 27C… сохраняет записанные программатором данные до следующего программирования с функцией стирания или без таковой. Допускается многократное программирование без стирания, при условии изменения битов только от состояния единицы до состояния нуля или имеющих состояние нуль.

Библиотека avr/eeprom.h

Описание к этой библиотеке я спрятал под спойлер, потому что она не очень актуальна и знать о ней необязательно. Также она не работает на esp8266/32 по понятным причинам.

Стандартная библиотека eeprom.h идёт в комплекте с компилятором avr-gcc, который компилирует наши скетчи из под Arduino IDE. Полную документацию можно почитать здесь. Для подключения библиотеки в скетч пишем #include Библиотека имеет набор функций для работы с целочисленными типами данных ( byte – 1 байт, word – 2 байта, dword – 4 байта), float , и block “блоков” – наборов данных любого формата (структуры, массивы, и т.д.). Под работой подразумевается запись, чтение и обновление. Обновление – крайне важный инструмент, позволяющий избежать лишних перезаписей ячеек памяти. Обновление делает запись, если записываемое значение отличается от текущего в этой ячейке. Чтение:

  • eeprom_read_byte(адрес) – вернёт значение
  • eeprom_read_word(адрес) – вернёт значение
  • eeprom_read_dword(адрес) – вернёт значение
  • eeprom_read_float(адрес) – вернёт значение
  • eeprom_read_block(адрес в SRAM, адрес в EEPROM, размер) – прочитает содержимое по адрес в EEPROM в адрес в SRAM
  • eeprom_write_byte(адрес, значение)
  • eeprom_write_word(адрес, значение)
  • eeprom_write_dword(адрес, значение)
  • eeprom_write_float(адрес, значение)
  • eeprom_write_block(адрес в SRAM, адрес в EEPROM, размер) – запишет содержимое по адрес в SRAM в адрес в EEPROM
  • eeprom_update_byte(адрес, значение)
  • eeprom_update_word(адрес, значение)
  • eeprom_update_dword(адрес, значение)
  • eeprom_update_float(адрес, значение)
  • eeprom_update_block(адрес в SRAM, адрес в EEPROM, размер) – обновит содержимое по адрес в SRAM в адрес в EEPROM
  • _EEPUT(addr, val) – записывает (write) байт val по адресу addr . Приведение типов не требуется (оно сделано в макросе)
  • _EEGET(val, addr) – читает байт по адресу addr и записывает его в переменную val . Приведение типов не требуется (оно сделано в макросе)

Рассмотрим простой пример, в котором происходит запись и чтение единичных типов данных в разные ячейки:

Хранить данные таким образом не очень удобно, потому что менеджмент адресов приходится проводить вручную, считать количество байт в каждом типе и “сдвигать” адрес на нужное количество. Гораздо удобнее хранить разношёрстные данные в структурах, про них мы подробнее говорили в уроке про типы данных. Мы должны передать функции адрес данных в памяти (оператор & ), по сути – указатель, а также преобразовать его к типу void* , потому что функция чтения/записи блока принимает именно такой тип. Подробнее про указатели мы говорили в отдельном уроке. Также функции чтения/записи блока нужно передать размер блока данных в количестве байт. Это можно сделать вручную (числом), но лучше использовать sizeof() , которая посчитает этот размер и передаст в функцию.

Точно так же можно хранить массивы:

В библиотеке avr/eeprom.h есть ещё один очень полезный инструмент – EEMEM, он позволяет сделать автоматическую адресацию данных путём создания указателей, значение которым присвоит компилятор. Рассмотрим пример, в котором запишем в EEPROM несколько переменных, структуру и массив, раздав им автоматически адреса. Важный момент! Адреса задаются снизу вверх по порядку объявления EEMEM, я подпишу их в примере:

Библиотека EEPROM.h

Библиотека EEPROM.h идёт в комплекте с ядром Arduino и является стандартной библиотекой. По сути EEPROM.h – это удобная оболочка для avr/eeprom.h, чуть расширяющая её возможности и упрощающая использование. Важный момент: подключая в скетч EEPROM.h мы автоматически подключаем avr/eeprom.h и можем пользоваться её фишками, такими как EEMEM. Рассмотрим инструменты, которые нам предлагает библиотека:

  • EEPROM.write(адрес, данные) – пишет данные ( только byte! ) по адресу
  • EEPROM.update(адрес, данные) – обновляет (та же запись, но лучше) байт данных, находящийся по адресу. Не реализована для esp8266/32!
  • EEPROM.read(адрес) – читает и возвращает байт данных, находящийся по адресу
  • EEPROM.put(адрес, данные) – записывает (по факту – обновляет , update) данные любого типа (типа переданной переменной) по адресу
  • EEPROM.get(адрес, данные) – читает данные по адресу и сам записывает их в данные – указанную переменную
  • EEPROM – библиотека позволяет работать с EEPROM памятью как с обычным массивом типа byte ( uint8_t )

В отличие от avr/eeprom.h у нас нет отдельных инструментов для работы с конкретными типами данных, отличными от byte, и сделать write/update/read для float/long/int мы не можем. Но зато у нас есть всеядный put/get, который очень удобно использовать! Рассмотрим пример с чтением/записью байтов:

Логика работы с адресами такая же, как в предыдущем пункте урока! Обратите внимание на работу с EEPROM как с массивом, можно читать, писать, сравнивать, и даже использовать составные операторы, например EEPROM0 += 10 , но это работает только для элементарных ячеек, байтов. Теперь посмотрим, как работает put/get:

Гораздо удобнее чем write_block и read_block, не правда ли? Put и get сами преобразовывают типы и сами считают размер блока данных, использовать их очень приятно. Они работают как с массивами, так и со структурами.

Для изменения значения придётся прочитать ячейку, выполнить нужные операции, и снова в неё записать. Ещё один удобный хак: можно ввести макросы на чтение и запись определённых значений, например:

А что такое EEPROM и где оно живет?

В последних версиях OpenComputers обрастает всякими загадочными вещами.

Игроки, которые только только освоились с предыдущей версией вдруг понимают, что надо изучать все заново.

«А пошло оно все!» — думают игроки, и уходят на версию 1.3.6, или переучиваются на ComputerCraft, который проще, и не требует непонятного.

А одна из самых загадочных — неведомый EEPROM.

Это такая мелкая хрень, без которой не работает ни один компьютер, или даже робот. Хорошо еще, что есть стандартный EEPROM который называется Lua BIOS. Он легко крафтится и заставляет работать компьютеры как и раньше.

Но найдем задачку посложнее, где Lua BIOS не поможет.

Попробуем собрать микроконтроллер, который будет управлять входными дверями.

Представим, как оно должно работать.

2014-12-25_20.17.07.png

Слева от двери (если входить) — микроконтроллер.

Ради понтов, возьмем Микроконтроллер 2-ого уровня и поставим в него беспроводную сетевую плату. Кроме того добавим красную плату, чтобы управлять дверью.

1. Если контроллер принимает сигнал «open» — он открывает дверь.

2. Если примет сигнал «close» — он закрывает дверь.

3. Если примет посторонний сигнал — взрывает динамит. Дабы сокровища не достались хакерам.

Для управления задействуем любой комп, у которого тоже будет беспроводная плата (или точка доступа).

2. Крафтим контроллер

С этим проблем не возникнет. Потому, что я играю в креативе 😛 .

Открываем NEI и берем нужные детали. В последний слот положим пока пустой EEPROM. Потом поставим на него прошивку, а пока — не важно.

2014-12-25_21.10.37.png

Нажимаем кнопку «Старт» и достаем готовый блок.

3. Готовим прошивку

Теперь, когда все готово, мы построили сокровищницу и скрафтили контроллер — осталось самое главное.

Программирование EEPROM’а отличается от программирования обычной программы.

Потому, что обычно, наши программы выполняются в OpenOS, которая заботливо загружает нужные библиотеки, предоставляет всякие удобные фичи и прочее.

Тем не менее писать мы будем именно в OpenOS. Запустим компьютер, напишем edit bios и введем следующие строки:

Дело в том, что большая часть библиотек, которые мы использовали — это библиотеки OpenOS. А значит мы не можем ими пользоваться в BIOS. Однако кое-что нам доступно.

Это библиотеки computer и component , и соответственно все установленные в целевом агрегате (микроконтроллер) компоненты.

Более чем достаточно для наших задач.

Вышеприведенный код делает следующее:

* ищет компонент с названием » redstone » и возвращает его прокси

* в вечном цикле посылает нулевой редстоун-импульс направо (side = 5), т.е. гасит сигнал

* ждет секунду (на самом деле — ожидает эвентов, то есть сигналов)

* посылает редстоун сигнал с силой 15 направо

Преследуем двоякую цель: во-первых проверить, что EEPROM вообще работает так про него написано на Вики. Кто его знает? А во-вторых: убедиться, что сторона 5 это именно та сторона, где дверь. А не какая-нибудь другая.

18 комментариев

Полезные ресурсы

Голосование

Информация

О нас

Проект ComputerCraft.ru основан в 2014 году. Особенностью наших игровых серверов является обязательное наличие компьютерных и технических модов и аддонов. Когда мод ComputerCraft устарел и больше не отвечал техническим требованиям, ему на замену пришел современный и высокотехнологичный мод OpenComputers. Черепашек заменили роботы из мода Opencomputers.

ComputerCraft.ru — это площадка для игры в Minecraft и общения на форуме, стабильные серверы и возможность в легкой и игровой форме обучиться программированию на языке Lua и реализовать все свои самые смелые инженерные идеи и решения и поделиться ими с другими игроками. За все время существования проекта сменилось 10 игровых серверов, которые посетили более 9000 игроков. На сайте собрано множество интересных программ и библиотек, статей, гайдов, веселых историй и горячих обсуждений, выдвинуто множество идей автоматизации и способов программирования.

У нас играют и пишут программы как новички так и опытные программисты. А самые продвинутые участники нашего коллектива даже разрабатывают собственные авторские моды и аддоны, ресурспаки, репозитории, мощнейшие библиотеки и операционные системы.

Регистрируйтесь прямо сейчас и присоединяйтесь к нашему дружному коллективу фанатов игры Minecraft , компьютерных и инженерных модов!

Типичный EEPROM протокол содержит 3 фазы: Код операции, фазы адреса и фазы данных. Код операции — обычно первые 8 бит, далее следует фаза адреса в 8-24 бита (зависит от устройства) и в конце запись или чтение информации.

Результат

Собственно все, теперь мы можем регистрировать в списке любые параметры:

Замечу, что пользователю параметров нужно только объявить параметр и список, а вся портянка с кодом, до этого, пишется один раз. Используются параметры точно также как и CachedNvData .

Что произойдет в этом примере, когда мы будем писать 10,11,12. 15 в наш параметр. Каждый раз при записи, адрес параметра будет смещаться на размер параметра + размер индекса + размер копии параметра и индекса. Как только количество записей превысит максимальное количество, параметр начнет писаться с начального адреса.

На картинке снизу как раз видно, что число 15 с индексом 5 записалось с начального адреса, а 10 теперь нет вообще.

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

Вот и все, надеюсь в этой статье цель получилось пояснить более детально, спасибо за то, что прочитали до конца.

Оцените статью