Листинг 15.7

WriteEEP:  ;в ZH:ZL — адрес EEPROM куда писать

;в temp — записываемый байт

       sbic EECR,EEWE  ;ждем очистки бита

       rjmp WriteEEP  ;разрешения записи EEWE

       out EEARH,ZH  ;старший адреса

       out EEARL,ZL  ;младший адреса

       out EEDR,temp  ;данные

           sbi EECR,EEMWE  ;установить флаг разрешения записи

           sbi EECR,EEWE  ;установить бит разрешения

ret  ;(конец WriteEEP)

Установленный нами бит разрешения EEWE в регистре управления сбросится автоматически, когда запись закончится — этого сброса мы и ожидаем в начале процедуры. Естественно, в самый первый раз никакого ожидания на самом деле не потребуется. На всякий случай то же самое рекомендуется делать и при чтении, но практически всегда (если только мы не читаем непосредственно после записи), это не будет задерживать программу дольше, чем на время выполнения команды sbic, т. е. на два машинных цикла. Так как при чтении не требуется устанавливать никаких флагов, то процедура получается несколько короче (листинг 15.8).

Листинг 15.8

ReadEEP:  ;в ZH: ZL — адрес откуда читать

;возврат temp — прочтенный байт

        sbic EECR,EEWE  ;ожидание очистки флага записи

        rjmp ReadEEP

        out EEARH,ZH  ;старший адреса

        out EEARL,ZL  ;младший адреса

        sbi EECR,EERE  ;бит чтения

        in temp,EEDR  ;чтение

ret  ;конец ReadEEP

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

Первичная запись констант в EEPROM

В принципе можно избежать процедуры записи вообще, если просто записать в EEPROM необходимые константы в процессе программирования. Это нужно делать отдельно от записи программы во Flash, с помощью специально подготовленного hex-файла. Но это ничем не будет отличаться от ситуации, когда константы хранятся в тексте программы, только программировать МК придется значительно дольше, особенно при отладке. Гораздо грамотнее будет не пожалеть труда и составить программу так, чтобы она сама записывала нужные константы «по умолчанию». Как это правильно сделать?

Разумеется, это следует сделать при запуске МК, в процедуре Reset. Но записывать константы каждый раз при включении питания не только не имеет смысла (тогда проще их опять же хранить в тексте), но и еще более неудобно для пользователя, чем установка часов, о которой шла речь в главе 14 — в дальнейшем мы научимся отдельно от программы записывать коэффициенты, не меняя текст программы, и хочется, чтобы это не требовалось делать после каждого сбоя питания. Тогда при удаче (если схема спроектирована верно и EEPROM надежно защищена от сбоев) автоматическая запись будет производиться один-единственный раз: при первом запуске контроллера, сразу после загрузки в его память программы, которую мы сейчас создадим.

Для этого нам потребуется как-то узнавать, есть ли уже в EEPROM какие-то данные, или нет, и правильно ли они записаны. Можно учесть тот факт, что в пустой EEPROM всегда записаны одни единицы (любой считанный байт будет равен $FF), но в общем случае это ненадежно. Наиболее универсальный способ — выделить для этого один какой-то байт в EEPROM, и всегда придавать ему определенное значение, а при загрузке МК его проверять. Это не гарантирует 100 %-ной надежности при сбоях (т. к. данные в незащищенной EEPROM могут меняться произвольно, в том числе и с сохранением значения отдельных байтов), но мы будем считать, что от сбоев защищены «двойной броней» (из внешнего монитора питания и встроенной схемы BOD), и нам важно только распознать ситуацию, когда требуется первичная запись в еще не заполненную память. Приборы, которые я проектировал таким образом, работали, не выключаясь годами, без единого сбоя загруженных констант.

Итак, общая схема алгоритма такая: читаем контрольный байт из EEPROM, если он равен заданной величине (обычно я выбираю чередование единиц и нулей: $АА), то это значит, что коэффициенты уже записаны. Если же нет, то записывает значения «по умолчанию», в том числе и значение этого контрольного байта. Далее в любом случае переходим к процедуре чтения из EEPROM и перегрузки записанных констант в SRAM, откуда они при необходимости извлекаются точно так же, как ранее в процедурах расчета физических величин. Так мы сможем ничего не менять в основной программе, описанной ранее в этой главе, а лишь дописать некий текст в секции начальной загрузки.

Перейти на страницу:

Поиск

Похожие книги