Что такое чип памяти и как программировать микросхемы. Основные особенности EEPROM памяти Почему AVR

Урок 15

Часть 1

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

Я думаю, может не все, но очень многие знают, что в контроллерах AVR помимо основной оперативной памяти, а также памяти для хранения прошивки существует ещё и энергонезависимая память типа EEPROM . Данная память сделана по технологии электрического стирания информации, что в отличие от её предшественника EPROM, в котором стирание производилось только при помощи ультрафиолетовых лучей, позволило использовать данный тип памяти практически повсеместно. Как мы знаем, ещё существует энергонезависимая память типа Flesh, которая стоит намного дешевле, но у которой также есть существенный минус. Там невозможно стереть отдельный байт, стирание производится только блоками, что не совсем удобно в некоторых случаях, особенно когда информации требуется хранить немного, и информация данная представляет собой небольшие настроечные параметры. Поэтому нам стоит также остановиться на данном типе памяти. И причем не только из-за того, что он присутствует в контроллере, а из-за того, что это очень удобно для хранения некоторых величин, которые нужны нам будут даже после того, как контроллер потерял питание.

Так как мы работаем с контроллером Atmega8A, техническую документацию данного МК мы и откроем и увидим там, что всего такой памяти у нас 512 байт. Это тем не менее не так мало. Если мы, например будем какой-нибудь будильник программировать, чтобы данные установки не потерялись после отключения питания, мы вполне можем с вами обратиться к данной памяти. Также в документации написано, что данная память гарантированно переживёт 100000 циклов записи/считывания.

Теперь напрашивается вопрос. Как же организован процесс работы с данной памятью в микроконтроллере AVR ? Как всегда, компания Atmel об этом позаботилась и организовала данный процесс на аппаратном уровне, что очень радует потому, что нам постоянно приходится беречь ресурсы контроллера. Для управления данным аппаратным уровнем существуют определенные регистры.

Один из них — регистровая пара EEAR . Почему пара, а потому что 512 адресов не влезут в 8 бит, требуется ещё один

Как именно мы будем адресоваться, мы увидим в процессе программирования EEPROM .

Следующий — регистр данных EADR

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

Ну и как водится, практически ни одна периферия и технология, организованная на аппаратном уровне, не обходится без управляющего регистра. У нас управляющим регистром является регистр EECR

Давайте сразу немного познакомимся с битами данного регистра.

Бит EERE — бит, заставляющий начать процесс чтения из памяти EEPROM. И, как только данные считались и записались в регистр данных, этот бит сбросится. Поэтому мы можем считать даннй бит не только управляющим, но и статусным или битом состояния.

Бит EEWE — бит, установка которого даёт команду контроллеру записать данные из регистра данных в определенный адрес EEPROM. После завершения процедуры записи, данный бит также сбрасывается самостоятельно.

Бит EEMWE — бит, разрешающий (не начинающий) процесс записи.

Бит EERIE — бит, разрешающий прерывания.

Ну, теперь перейдём к проекту. Проект был создан обычным стандартным образом и назван Test13 . Также был подключен файл main.h и созданы файлы eeprom.h и eeprom.c .

Вот исходный код созданных файлов

Test13.c:

#include "main.h"

int main ( void )

{

while (1)

{

}

}

#ifndef MAIN_H_

#define MAIN_H_

#define F_CPU 8000000UL

#include

#include

#include

#include

#include

#include "eeprom.h"

 

#endif /* MAIN_H_ */

eeprom.h

#ifndef EEPROM_H_

#define EEPROM_H_

#include "main.h"

void EEPROM_write ( unsigned int uiAddress , unsigned char ucData );

unsigned char EEPROM_read ( unsigned int uiAddress );

#endif /* EEPROM_H_ */

eeprom.c

#include "eeprom.h"

Сначала, соответственно, мы попробуем записать данные в память EEPROM. Ну, оно и логично, так как пока мы ничего не записали, нам читать также нечего.

Ну, давайте не будем забивать голову и вставим код функции записи, также и функции чтения из примера в технической документации в файл eeprom.c и уберем англоязычные комментарии, вставив туда русскоязычные. После всех исправлений файл станет вот таким

#include "eeprom.h"

void EEPROM_write ( unsigned int uiAddress , unsigned char ucData )

{

while ( EECR & (1<< EEWE ))

{}

EEAR = uiAddress ; //Устанавливаем адрес

EEDR = ucData ; //Пищем данные в регистр

EECR |= (1<< EEMWE ); //Разрешаем запись

EECR |= (1<< EEWE ); //Пишем байт в память

}

unsigned char EEPROM_read ( unsigned int uiAddress )

{

while ( EECR & (1<< EEWE ))

{} //ждем освобождения флага окончания последней операцией с памятью

EEAR = uiAddress ; //Устанавливаем адрес

EECR |= (1<< EERE ); //Запускаем операцию считывания из памяти в регистр данных

return EEDR ; //Возвращаем результат

}

Напишем прототипы на данные функции в файле eeprom.h

#include "main.h"

void EEPROM_write ( unsigned int uiAddress , unsigned char ucData );

unsigned char EEPROM_read ( unsigned int uiAddress );

Теперь вызовем функцию записи в функции main() и тем самым попробуем записать какую-нибудь 8-битную величину по адресу 1. Вообще, адресация в данной памяти начинается с 0

int main ( void )

EEPROM_write (1, 120);

While (1)

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

Соберём проект и перейдём в программу для прошивки Avrdude .

Выберем там наш файл прошивки, затем попытаемся считать контроллер, затем всё сотрем по кнопке "стереть все"

Также в программе avrdude есть ещё одна строка "Eeprom". Данную строку мы можем использовать, чтобы записать в данную память не программно, а из файла. Но мы будем писать из нашей программы, а данную строку будем использовать, чтобы читать в файл память EEPROM. Можно написать в эту строку путь от руки и файл создастся сам. Напишем, например "C:\1\11111" и нажмем "Чтение", и по данному пути запишется в указанный файл вся информация из памяти EEPROM

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

Найдём теперь на диске данный файл и откроем его в блокноте

Данный файл имеет приблизительно такой же формат как и файл прошивки. Сначала адрес, затем 32 байта информационных и затем контрольная сумма на эти 32 байта. Если мы не разу не записывали ничего в память EEPROM, то по всем адресам у нас будут FF, то есть во всех битах памяти у нас единички.

Закрываем файл, пытаемся прошить контроллер, затем опять читаем память EEPROM в файл и откроем файл

Мы видим, что в файл записалось число "78", что и означает 120 в десятичном формате.

Теперь попробуем нажать кнопку "Стереть всё", в этом случае память EEPROM стетеься не должна.

Читаем опять EEPROM в файл, открываем файл и видим, что память стёрлась, у нас опять везде "FF".

Почему так произошло? Потому что нужно настроить фьюзы. Читаем фьюзы

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

Прошиваем фьюзы, стираем контроллер, прошиваем контроллер, опять стираем, читаем память EEPROM в файл и открываем его. Теперь мы видим, что ничего у нас не стёрлось

Теперь попробуем отключить контроллер от питания и подать через некоторое время питание опять. Опять читаем EEPROM в файл, у нас всё цело. Отлично!

В следующей части урока мы попробуем программно прочитать данные из памяти EEPROM.

Смотреть ВИДЕОУРОК (нажмите на картинку)

Post Views: 7 259

  • Tutorial

Резюме: Если вы периодически обновляете некоторое значение в EEPROM каждые несколько минут (или несколько секунд), вы можете столкнуться с проблемой износа ячеек EEPROM. Чтобы избежать этого, требуется снижать частоту записей в ячейку. Для некоторых типов EEPROM даже частота записи чаще чем один раз в час может быть проблемой.

Когда вы записываете данные, время летит быстро

EEPROM повсеместно используется для сохранения параметров настройки и журнала работы во встраиваемых системах. К примеру, вы можете хотеть функцию «черного ящика», для записи последних данных на момент аварии или потери питания. Я видел спецификации с требованием записывать подобные данные каждые несколько секунд.

Но проблема в том, что EEPROM имеет ограниченный ресурс числа записей. После 100,000 или миллиона записей (зависит от конкретного чипа), некоторые из ваших систем начнут испытывать проблемы с отказом EEPROM. (Посмотрите в даташит, чтобы узнать конкретную цифру. Если вы хотите выпустить большое число устройств, «наихудший случай», вероятно, более важен чем «типичный»). Миллион записей кажется большой цифрой, но на самом деле он закончится очень быстро. Давайте посмотрим на примере, предположив, что нам нужно сохранять измеренное напряжение в одну ячейку каждые 15 секунд.

1,000,000 записей при одной записи в 15 секунд дают записи в минуту:
1,000,000 / (4 * 60 минут/час * 24 часа/день) = 173.6 дней.
Другими словами, ваша EEPROM исчерпает резерв в миллион записей менее чем через 6 месяцев.

Ниже приведен график, показывающая время до износа (в годах), основанный на периоде обновления конкретной ячейки EEPROM. Ограничительная линия для продукта с продолжительностью жизни 10 лет составляет одно обновление каждые 5 минут 15 секунд для микросхемы с ресурсом 1 миллион записей. Для EEPROM с ресурсом 100К можно обновлять конкретную ячейку не чаще одного раза в 52 минуты. Это означает, что не стоит и надеяться обновлять ячейку каждые несколько секунд, если вы хотите, чтобы ваш продукт работал годы, а не месяцы. Вышесказанное масштабируется линейно, правда, в настоящем приборе имеются еще и вторичные факторы, такие как температура и режим доступа.

Уменьшить частоту

Самый безболезненный способ решить проблему-это просто записывать данные реже. В некоторых случаях требования к системе это позволяют. Или можно записывать только при каких-либо больших изменениях. Однако, с записью, привязанной к событиям, помните о возможном сценарии, при котором значение будет постоянно колебаться, и вызовет поток событий, которые приведут к износу EEPROM.
(Будет неплохо, если вы сможете определить, сколько раз производилась запись в EEPROM. Но это потребует счётчика, который будет храниться в EEPROM… при этом проблема превращается проблему износа счётчика.)

Прерывание по снижению уровня питания

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

Кольцевой буфер

Классическое решение проблемы износа-использовать кольцевой буфер FIFO, содержащий N последних записей значения. Так-же понадобится сохранять указатель на конец буфера в EEPROM. Это уменьшает износ EEPROM на величину, пропорциональную числу копий в этом буфере. Например, если буфер проходит через 10 различных адресов для сохранения одного значения, каждая конкретная ячейка модифицируется в 10 раз реже, и ресурс записи возрастает в 10 раз. Вам также понадобится отдельный счётчик или отметка времени для каждой из 10 копий, чтобы можно было определить, которая из них последняя на момент выключения. Другими словами, понадобится два буфера, один для значения, и один для счетчика. (Если сохранять счетчик по одному и тому-же адресу, это приведёт к его износу, т.к. он должен увеличиваться при каждом цикле записи.) Недостаток этого метода в том, что нужно в 10 раз больше места чтобы получить в 10 раз большую продолжительность жизни. Можно проявить смекалку, и упаковать счетчик вместе с данными. Если вы записываете большое количество данных, добавление нескольких байт для счетчика - не такая уж большая проблема. Но в любом случае, понадобится много EEPROM.
Atmel приготовил аппноут, содержащий все кровавые подробности:
AVR-101: High Endurance EEPROM Storage: www.atmel.com/images/doc2526.pdf

Особый случай для счётчика числа записей

Иногда нужно сохранить счётчик, а не сами значения. К примеру, вы можете хотеть знать число включений прибора, или время работы вашего устройства. Самое плохое в счётчиках, это то, что у них постоянно меняется младший значащий бит, изнашивая младшие ячейки EEPROM быстрее. Но и тут возможно применить некоторые трюки. В аппноуте от Microchip есть несколько умных идей, таких как использование кода Грея, чтобы только один бит из многобайтового счётчика менялся при изменении значения счетчика. Также они рекомендуют использовать корректирующие коды для компенсации износа. (Я не знаю, насколько эффективно будет применение таких кодов, т.к. это будет зависеть от того, насколько независимы будут ошибки в битах в байтах счётчика, используйте на свой страх и риск, прим. авт.). Смотри аппноут: ww1.microchip.com/downloads/en/AppNotes/01449A.pdf

Примечание: для тех, кто хотел бы узнать больше, Microchip подготовил документ, содержащий детальную информацию об устройстве ячеек EEPROM и их износе с диаграммами:
ftp.microchip.com/tools/memory/total50/tutorial.html

Дайте мне знать, если у вас имеются какие-либо интересные идеи по поводу борьбы с износом EEPROM.

Источик: Phil Koopman, «Better Embedded System SW»
betterembsw.blogspot.ru/2015/07/avoiding-eeprom-wearout.html

Примечание переводчика: в последние годы появились микросхемы EEPROM со страничной организацией стирания (подобной микросхемам FLASH), где логически можно адресовать ячейки (читать, записывать и стирать) побайтно, но при этом микросхема невидимо для пользователя стирает всю страницу целиком и перезаписывает новыми данными. Т.е. стерев ячейки по адресу 0, мы фактически стёрли и перезаписали ячейки с адресами 0...255 (при размере страницы 256 байт), поэтому трюк с буфером в этом случае не поможет. При исчерпании ресурс записей у такой микросхемы выходит из строя не одна ячейка, а вся страница целиком. В даташитах для таких микросхем ресурс записи указан для страницы , а не для конкретной ячейки. Смотри, например, даташит на 25LC1024 от Microchip.

Теги: Добавить метки

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

Микросхема памяти — это электронный компонент, внутренняя структура которого способна сохранять (запоминать) внесённые программы, какие-либо данные или одновременно то и другое.

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

Следует отметить: чипы памяти всегда являются неотъемлемым дополнением микропроцессоров – управляющих микросхем. В свою очередь микропроцессор является основой электроники любой современной техники.

Набор электронных компонентов на плате современного электронного устройства. Где-то среди этой массы радиодеталей приютился компонент, способный запоминать информацию

Таким образом, микропроцессор управляет , а чип памяти хранит сведения, необходимые микропроцессору.

Программы или данные хранятся в чипе памяти как ряд чисел — нулей и единиц (биты). Один бит может быть представлен логическими нулем (0) либо единицей (1).

В единичном виде обработка битов видится сложной. Поэтому биты объединяются в группы. Шестнадцать бит составляют группу «слов», восемь бит составляют байт — «часть слова», четыре бита — «кусочек слова».

Программным термином для чипов, что используется чаще других, является байт. Это набор из восьми бит, который может принимать от 2 до 8 числовых вариаций, что в общей сложности даёт 256 различных значений.

Для представления байта используется шестнадцатеричная система счисления, где предусматривается использование 16 значений из двух групп:

  1. Цифровых (от 0 до 9).
  2. Символьных (от А до F).

Поэтому в комбинациях двух знаков шестнадцатеричной системы также укладываются 256 значений (от 00h до FFh). Конечный символ «h» указывает на принадлежность к шестнадцатеричным числам.

Организация микросхем (чипов) памяти

Для 8-битных чипов памяти (наиболее распространенный тип) биты объединяются в байты (8 бит) и сохраняются под определённым «адресом».

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


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

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

Микросхемы EEPROM созданы на основе транзисторов с плавающим затвором. Микросхема EEPROM запрограммирована путём принудительной программируемой информации в виде электронов через оксид затвора. Затем плавающий затвор обеспечивает хранение этих электронов. Ячейка памяти считается запрограммированной, когда она заряжается электронами, и это представляется нулём. Если ячейка памяти не заряжена, она не запрограммирована, и она представлена ​​единицей.

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

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

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

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

Описание памяти EEPROM

Ардуино предоставляет своим пользователям три типа встроенной памяти устройств: стационарное ОЗУ (оперативно-запоминающее устройство или SRAM - static random access memory) – необходимо для записи и хранения данных в процессе использования; флеш-карты – для сохранения уже записанных схем; – для хранения и последующего использования данных.

На ОЗУ все данные стираются, как только происходит перезагрузка устройства либо отключается питание. Вторые две сохраняют всю информацию до перезаписи и позволяют извлекать ее при необходимости. Флеш-накопители достаточно распространены в настоящее время. Подробнее стоит рассмотреть память EEPROM.

Аббревиатура расшифровывается, как Electrically Erasable Programmable Read-Only Memory и в переводе на русский дословно означает – электрически стираемая программируемая память только для чтения. Производитель гарантирует сохранность информации на несколько десятилетий вперед после последнего отключения питания (обычно приводят срок в 20 лет, зависит от скорости снижения заряда устройства).

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

Объем памяти, в сравнении с современными носителями, очень небольшой и разный для различных микроконтроллеров. Например, для:

  • ATmega328 – 1кБ
  • ATmega168 и ATmega8 – 512 байт,
  • и ATmega1280 – 4 кБ.

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

Для записи на EEPROM требуется значительное количество времени – около 3 мс . Если в момент записи отключается питание, данные не сохраняются вовсе либо могут быть записаны ошибочно. Требуется всегда дополнительно проверять внесенную информацию, чтобы избежать сбоев во время работы. Считывание данных происходит гораздо быстрее, ресурс памяти от этого не снижается.

Библиотека

Работа с памятью EEPROM осуществляется с помощью библиотеки, которая была специально создана для Ардуино. Главными являются способность к записи и чтению данных. активируется командой #include EEPROM.h .

  • для записи – EEPROM.write(address, data);
  • для чтения – EEPROM.read(address).

В данных скетчах: address – аргумент с данными ячейки, куда вносятся данные второго аргумента data; при считывании используется один аргумент address, который показывает, откуда следует читать информацию.

Функция Назначение
read(address) считывает 1 байт из EEPROM ; address – адрес, откуда считываются данные (ячейка, начиная с 0);
write(address, value) записывает в память значение value (1 байт, число от 0 до 255) по адресу address;
update(address, value) заменяет значение value по адресу address, если её старое содержимое отличается от нового;
get(address, data) считывает данные data указанного типа из памяти по адресу address;
put(address, data) записывает данные data указанного типа в память по адресу address;
EEPROM позволяет использовать идентификатор "EEPROM" как массив, чтобы записывать данные в память и считывать их из памяти.

Запись целых чисел

Запись целых чисел в энергонезависимую память EEPROM осуществить достаточно просто. Внесение чисел происходит с запуском функции EEPROM.write() . В скобках указываются необходимые данные. При этом числа от 0 до 255 и числа свыше 255 записываются по-разному. Первые вносятся просто – их объем занимает 1 байт, то есть одну ячейку. Для записи вторых необходимо использовать операторов highByte() высший байт и lowByte() низший байт.

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

3 * 256 + 21 = 789

Для « воссоединения» большого целого числа применяется функция word(): int val = word(hi, low) . Нужно читывать, что максимальное целое число для записи – 65536 (то есть 2 в степени 16). В ячейках, в которых еще не было иных записей, на мониторе будут стоять цифры 255 в каждой.

Запись чисел с плавающей запятой и строк

Числа с плавающей запятой и строк – это форма записи действительных чисел, где они представляются из мантиссы и показателя степени. Запись таких чисел в энергонезависимую память EEPROM производится с активацией функции EEPROM.put() , считывание, соответственно, – EEPROM.get() .

При программировании числовые значения с плавающей запятой обозначаются, как float, стоит отметить, что это не команда, а именно число. Тип Char (символьный тип) – используется для обозначения строк. Процесс записи чисел на мониторе запускается при помощи setup(), считывание – с помощью loop().

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

Примеры проектов и скетчей

Пример №1

Скетч запишет до 16 символов с последовательного порта и в цикле выведет 16 символов из EEPROM. Благодаря данные записываются в EEPROM и контролируется содержимое энергонезависимой памяти.

// проверка работы EEPROM #include int i, d; void setup() { Serial.begin(9600); // инициализируем порт, скорость 9600 } void loop() { // чтение EEPROM и вывод 16 данных в последовательный порт Serial.println(); Serial.print("EEPROM= "); i= 0; while(i < 16) { Serial.print((char)EEPROM.read(i)); i++; } // проверка есть ли данные для записи if (Serial.available() != 0) { delay(50); // ожидание окончания приема данных // запись в EEPROM i= 0; while(i < 20) { d= Serial.read(); if (d == -1) d= " "; // если символы закончились, заполнение пробелами EEPROM.write(i, (byte)d); // запись EEPROM i++; } } delay(500); }

Пример №2

Для большего понимания мы можем создать небольшой скетч, который поможет в понимании работы с энергонезависимой памятью. Считаем все ячейки этой памяти. Если ячейка не пустая - вывод в последовательный порт. После чего заполняем ячейки пробелами. Потом вводим текст через монитор последовательного порта. Его записываем в EEPROM, и при последующем включении считываем.

#include int address = 0; // адрес eeprom int read_value = 0; // считываемые с eeprom данные char serial_in_data; // данные последовательного порта int led = 6; // линия 6 для светодиода int i; void setup() { pinMode(led, OUTPUT); // линия 6 настраивается на выход Serial.begin(9600); // скорость передачи по последовательному порту 9600 Serial.println(); Serial.println("PREVIOUS TEXT IN EEPROM:-"); for(address = 0; address < 1024; address ++) // считываем всю память EEPROM { read_value = EEPROM.read(address); Serial.write(read_value); } Serial.println(); Serial.println("WRITE THE NEW TEXT: "); for(address = 0; address < 1024; address ++) // заполняем всю память EEPROM пробелами EEPROM.write(address, " "); for(address = 0; address < 1024;) // записываем пришедшие с последовательного порта данные в память EEPROM { if(Serial.available()) { serial_in_data = Serial.read(); Serial.write(serial_in_data); EEPROM.write(address, serial_in_data); address ++; digitalWrite(led, HIGH); delay(100); digitalWrite(led, LOW); } } } void loop() { //---- мигаем светодиодом каждую секунду -----// digitalWrite(led, HIGH); delay(1000); digitalWrite(led, LOW); delay(1000); }

Пример №3

Запись в память два целых числа, чтение их из EEPROM и вывод в последовательный порт. Числа от 0 до 255 занимают 1 байт памяти, с помощью функции EEPROM.write() записываются в нужную ячейку. Для чисел больше 255 их нужно делить на байты с помощью highByte() и lowByte() и записывать каждый байт в свою ячейку. Максимальное число при этом – 65536 (или 2 16).

#include // подключаем библиотеку EEPROM void setup() { int smallNum = 123; // целое число от 0 до 255 EEPROM.write(0, smallNum); // запись числа в ячейку 0 int bigNum = 789; // число > 255 разбиваем на 2 байта (макс. 65536) byte hi = highByte(bigNum); // старший байт byte low = lowByte(bigNum); // младший байт EEPROM.write(1, hi); // записываем в ячейку 1 старший байт EEPROM.write(2, low); // записываем в ячейку 2 младший байт Serial.begin(9600); // инициализация послед. порта } void loop() { for (int addr=0; addr<1024; addr++) { // для всех ячеек памяти (для Arduino UNO 1024) byte val = EEPROM.read(addr); // считываем 1 байт по адресу ячейки Serial.print(addr); // выводим адрес в послед. порт Serial.print("\t"); // табуляция Serial.println(val); // выводим значение в послед. порт } delay(60000); // задержка 1 мин }

Пример №4

Запись чисел с плавающей запятой и строк - метод EEPROM.put() . Чтение – EEPROM.get() .

#include // подключаем библиотеку void setup() { int addr = 0; // адрес float f = 3.1415926f; // число с плавающей точкой (типа float) EEPROM.put(addr, f); // записали число f по адресу addr addr += sizeof(float); // вычисляем следующую свободную ячейку памяти char name = "Hello, SolTau.ru!"; // создаём массив символов EEPROM.put(addr, name); // записываем массив в EEPROM Serial.begin(9600); // инициализация послед. порта } void loop() { for (int addr=0; addr<1024; addr++) { // для всех ячеек памяти (1024Б=1кБ) Serial.print(addr); // выводим адрес в послед. порт Serial.print("\t"); // табуляция float f; // переменная для хранения значений типа float EEPROM.get(addr, f); // получаем значение типа float по адресу addr Serial.print(f, 5); // выводим с точностью 5 знаков после запятой Serial.print("\t"); // табуляция char c; // переменная для хранения массива из 20 символов EEPROM.get(addr, c); // считываем массив символов по адресу addr Serial.println(c); // выводим массив в порт } delay(60000); // ждём 1 минуту }

Пример №5

Использование EEPROM как массива.

#include void setup() { EEPROM = 11; // записываем 1-ю ячейку EEPROM = 121; // записываем 2-ю ячейку EEPROM = 141; // записываем 3-ю ячейку EEPROM = 236; // записываем 4-ю ячейку Serial.begin(9600); } void loop() { for (int addr=0; addr<1024; addr++) { Serial.print(addr); Serial.print("\t"); int n = EEPROM; // считываем ячейку по адресу addr Serial.println(n); // выводим в порт } delay(60000); }

Работа с EEPROM

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

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

Такая память на Ардуино стандартно хранит самое важное для работы контроллера и устройства. К примеру, если на такой базе создается регулятор температуры и исходные данные окажутся ошибочными, устройство будет работать «неадекватно» существующим условиям – сильно занижать или завышать температуру.

Существует несколько ситуаций, когда память EEPROM содержит неправильные данные:

  1. При первоначальной активации – еще не было ни одной записи.
  2. В момент неконтролируемого отключения питания – часть или все данные не запишутся или запишутся некорректно.
  3. После завершения возможных циклов перезаписи данных.

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

Для контроля целостности информации используют контрольный код системы. Он создается по образцу записи первоначальных данных и, при проверке, он вновь просчитывает данные. Если результат отличается – это ошибка. Самым распространенным вариантом такой проверки является контрольная сумма – выполняется обычная математическая операция по сложению всех значений ячеек.

Опытные программисты добавляют к этому коду дополнительное «исключающее ИЛИ», например, E5h. В случае если все значения равны нулю, а система по ошибке обнулила исходные данные – такая хитрость выявит ошибку.

Таковы основные принципы работы с энергонезависимой памятью EEPROM для микроконтроллеров Arduino. Для определенных проектов стоит использовать только этот вид памяти. Он имеет как свои плюсы, так и свои недостатки. Для освоения методов записи и чтения лучше начать с простых задач.

Публикации по теме

  • Включаем Flash Player в Яндекс Включаем Flash Player в Яндекс

    Отключение плагина Adobe Flash актуально в случае, если вы хотите повысить стабильность браузера, уменьшить объем потребляемых им...

  • Что такое wifi и как им пользоваться Что такое wifi и как им пользоваться

    Введение Итак, Wi-Fi - это беспроводной способ передачи данных, использующий радиосигналы. Дословно wi-fi переводится - беспроводное...