Главная страница
Библиотека (скачать книги)
Скачать софт
Введение в программирование
Стандарты для C++
Уроки по C#
Уроки по Python
HTML
Веб-дизайн
Ассемблер в среде Windows
ActiveX
Javascript
Общее о Линукс
Линукс - подробно
Линукс - новое
Delphi
Паскаль для начинающих
Турбопаскаль
Новости
Партнеры
Наши предложения
Архив новостей





Здесь FEnEE — флаг, который будет запрещать запись, если достигнут конец памяти. Его значение $FF разрешает запись в память, любое другое, (мы будем писать $00) — запрещает. Обратите внимание, что запись возможна, если байт FEnEE равен $FF, т. е. в самом начале, когда EEPROM еще пуста, запись по умолчанию разрешается. Этот флаг разрешения независим от текущего адреса: он обязательно устанавливается в запрещающее состояние при заполнении памяти (см. далее), но также может быть установлен в произвольный момент по команде извне для остановки записи. Теперь инициализируем таймер. В загрузочную секцию вместо строк инициализации TimerO (ldi temp, (1«TOIEO) и out TIMSK, temp) добавляем код, приведенный в листинге 12.2.

Листинг 12.2
;======= Set Timer 1
ldi temp,high(58594) out OCRlAH,temp ldi temp,low(58594) out OCRlAL,temp ldi temp,ObOOOOllOl
out TCCRIB,temp ;1/1024, очистить после совпадения ldi temp, (l«TOIE0) | (l«OCIElA) ;разреш. прерывания
;по совпадению для Timer 1 и переполнению Timer 0 out TIMSK,temp

Обратите внимание, что вывод ОС1А таймера не инициализируется (вывод PD6, который в ATmega8535 соответствует ОС1А, у нас занят в передаче данных): для сигнализации того, что запись идет, эта функция не подходит — в данном случае светодиод, подсоединенный к этому выводу, мигал бы с периодом 30 с или еще реже. Можно подсоединить светодиод к любому свободному выводу и заставить его зажигаться на пару секунд в момент записи, что целесообразно предусмотреть для проверки работоспособности программы, но мы здесь не будем загромождать код.

Далее в секции начальной загрузки инициализируем регистры адреса (листинг 12.3). Получится довольно сложная процедура, которая должна проверять значения адреса в EEPROM, и если он там был записан (т. е. содержимое отлично от $FF), то еще и сравнивать его с последним возможным адресом (в нашем случае 32 767 или 7FFFh).

Процедуры доступа к EEPROM ReadEEP и WriteEEP см. в главе 9.
Листинг 12.3
;=========инициализация адреса внешней памяти
clr ZH /старший EEPROM
ldi ZL,EaddrL /младший EEPROM
rcall ReadEEP
mov AddrL, temp
ldi ZL,EaddrH
rcall ReadEEP
mov AddrH,temp /теперь в AddrH:AddrL адрес из EEPROM ldi temp,0xFF /если все FF, то память была пуста ср AddrL, temp ldi temp, OxFF cpc AddrH,temp
brne cont_l /если не пусто, то переход далее clr AddrH /если пуста, то присваиваем адрес = О clr AddrL - clr ZH /старший EEPROM ldi ZL,EaddrL /младший EEPROM mov
temp,AddrL rcall WriteEEP /и записываем его опять в EEPROM inc ZL mov temp,AddrH rcall WriteEEP cont 1:

Теперь в секции прерываний поставим команду rjmp TIMICOMPA в строке для прерывания Timerl Compare А (шестое сверху, не считая RESET), и Напишем его обработчик (листинг 12.4).
Т1М1_С0МРА: /15 секунд /проверять разрешение записи clr ZH /старший EEPROM . ldi ZL, FEnEE /младший EEPROM
rcall ReadEEP
cpi temp, $FF
breq flag_WF
reti /если запрещено, то выходим из прерывания flag_WF:
ldi ZL,Tres /адрес значения в SRAM
Id DATA, Z+ ; старший T rcall WriteFlash ;пишем adiw AddrL,1 Id DATA, Z+ ; младший T rcall WriteFlash adiw AddrL,1 Id DATA, Z+ /старший P rcall WriteFlash adiw AddrL,1 Id DATA, Z+ /младший P rcall WriteFlash /проверяем адрес на 7FFF ldi temp,0xFF cp AddrL, temp ldi temp,0x7F cpc AddrH, temp
breq clr_FE если равен, на clr_FE
adiw AddrL,1 /иначе сохраняем след. адрес: clr ZH
ldi ZL,EaddrL /в EEPROM mov temp,AddrL rcall WriteEEP inc ZL
mov temp, AddrH rcall WriteEEP reti /выход из прерывания clr_FE /если конец памяти: clr temp
clr ZH /старший EEPR ldi ZL,FEnEE
rcall WriteEEP /запрещаем запись reti /выход из прерывания

Как мы видим, здесь каждые 15 с идет запись в EEPROM текущего адреса (того, по которому должна производиться следующая запись), т. е. если в какой-то момент питание пропадет, то при следующей загрузке запись все равно начнется с текущего адреса. Адреса отсчитываются при каждой записи группами по четыре, а число адресов кратно этому числу, потому максимальное значение можно проверять только один раз на каждую процедуру записи.
Отметим, что можно не опасаться исчерпания ресурса встроенной EEPROM: серия АТ24 допускает до 1 миллиона циклов перезаписи.

Часы с интерфейсом l2C
Моделей часов реального времени (RTC) существует множество. Все пользователи ПК с ними хорошо знакомы заочно: именно микросхема RTC питается от резервной батарейки, находящейся на любой материнской плате. Такие часы, кроме собственно функций счета времени и календаря, имеют небольшую встроенную SRAM, в которой записаны установки BIOS. Хранить их именно в энергозависимой памяти удобно, т. к. часы реального времени все равно требуются, а в случае чего установки легко сбросить в исходное состояние, просто лишив микросхему питания (или замкнув специальные контакты).
Встроенную SRAM имеют не все такие микросхемы, но в остальном RTC внутри устроены примерно одинаково: ведут счет времени и календарь, имеют функции будильника и/или таймера, обязательную возможность автономной работы от батарейкН в течение длительного времени. Такие часы обычно снабжают кварцем на 32 768 Гц, иногда даже встроенным в микросхему. Кроме этого, значительная часть моделей имеет дополнительный выход (иногда! и не один), на котором формируется некая частота, задаваемая программно. Этот выход можно использовать для управления прерыванием микроконтроллера, и таким образом организовать счет времени и его индикацию. Еще одна особенность микросхем RTC — единицы времени в них традиционно представлены в десятичном виде (в упакованном BCD-формате). Именно так выдают значения времени RTC, встроенные в ПК. Например, число минут, равное 59, так и выдается, как байт со значением 59, но это не $59, что в десятичной системе есть 89! Соответствующее шестнадцатеричное число записалось бы, как $ЗВ. BCD-представление удобно для непосредственной индикации, но при арифметических операциях (или, например, при сравнении) его приходится преобразовывать к обычному двоичному виду. На самом деле это почти не доставляет неудобств, скорее наоборот.

Для наших целей аыберем модель RTC под названием DS1307. Это простейшие часы с 12С-интерфейсом, в 8-выводном корпусе с внешним резонатором на 32 768 Гц, 5-вольтовым питанием и возможностью подключения резервной батарейки на 3 В (т. е. обычной литиевой "таблетки"). Схема переключения питания на батарейку— встроенная и не требует внешних элементов. Эти часы допускают максимальную тактовую частоту интерфейса 12С 100 кГц. Отметим, что DS1307 практически без изменений в программе можно заменить на более современную модель DS1338, допускающую напряжения питания 3,3, 3,0 или 1,8 В (в зависимости от модели), а также повышенную скорость передачи по 12С.



     
 

Библиотека программиста. 2009.
Администратор: admin@programmer-lib.ru