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





Если бит 3 регистра Flag установлен, то мы будем писать время в виде отдельного кадра, а точнее — двух кадров, потому что в один 4-байтовый кадр время + дата у нас не уместится. Можно в принципе и сэкономить, уменьшив размер этой записи, но сделать размер вспомогательного кадра времени кратным кадру данных удобно с точки зрения отсчета адресов в памяти. Два кадра займут 8 байтов, пять из них есть значение времени, а оставшиеся три мы используем так: будем придавать самым, первым двум определенное значение — $FA. Тогда считывающая программа, встретив два $FA подряд, будет "знать", что перед ней кадры времени, а не данных, и их нужно интерпретировать соответствующим образом.
Тут мы учтем тот факт, что ни данные (10-битовые), нН значения времени не могут содержать байтов, имеющих величину, когда старшая тетрада принимает значение $F. Так что в принципе хватило бы и одного такого байта, но для надежности мы их вставим два подряд (благо их количество позволяет), и у нас даже еще один байт останется в запасе. И его мы также используем: будем писать в него значение регистра MCUCSR, В котором содержатся сведения о том, откуда ранее пришла команда на сброс. Отдельные биты в этом байте сбоев (БС) означают следующее:
□ Bit 3 — Watchdog Reset Flag (БС = 08) устанавливается, если сброс был от сторожевого таймера;
□ Bit 2 — Brown-out Reset Flag (БС = 04) устанавливается, если был сброс от снижения питания ниже 4 В;
□ Bit 1 — External Reset Flag (БС = 02) устанавливается, если сброс был от внешнего сигнала Reset (характерно для перепрограммирования);
□ Bit 0 — Power-on Reset Flag (БС = 01) устанавливается, если было включение питания МК.

Эта информация пригодится для сбора статистики сбоев. После записи кадров времени флаг первичной записи сбрасывается. В листинге 12.10 приведен вариант соответствующей процедуры, включающий в себя и запись во внешнюю память. Счет времени я опускаю — он соответствует тому, что написано по этому поводу в главе 8, только с учетом необходимости писать в память и обычные hex-значения, и распакованные BCD-значения. По адресу Min будут храниться hex-значения минут, по следующему по порядку адресу— hex-значения часов.

Листинг 12.10
EXT_INT0: ;=== основное прерывание часов
ldi* ZH, 0x01 ; раз и навсегда старший адреса SRAM
<здесь счет времени>
cpi count_sek,0 ;если секунды =0, то проверяем время на запись
breq sek_0
reti ;выход из прерывания sek_0: ; ===== запись во флешь
;rjmp mml ;вспомогательный минутный цикл для проверки записи ldi ZL,Min /минуты Id temp,Z+
cpi temp,0 ;сравниваем минуты =0 — запись breq mmO
reti ;выход из прерывания mmO: ;проверяем часы на кратность 3
Id temp,Z ;в temp — значение часов
cpi temp,, 0
breq mml
cpi temp,$03
breq mml
cpi temp,$06
breq mml
cpi temp,$09
breq mml 5
cpi temp,$12
breq mml
cpi temp,$15
breq mml
cpi temp,$18
breq mml
cpi temp,$21
breq mml ;если да, то на mml reti ;иначе выход из прерывания mml: ;проверяем разрешение записи
clr ZH ;старший EEPROM
ldi ZL,FEnEE ;младший EEPROM
rcall ReadEEP
cpi temp, $FF
breq flag_WF
reti ;если запрещено, то выходим из прерывания flag_WF: ;проверка флага первичной записи sbrs Flag,3
rjmp zapisFO ;иначе на запись данных cbr Flag,8 ;сбросить флаг первичной записи ;пишем кадр времени
rcall ReadClk ;правильную дату в память
ldi DATA,$FA /начало кадра времени FA FA
rcall WriteFlash
adiw AddrL,1
ldi DATA, $ FA
rcall WriteFlash
adiw AddrL,1
in DATA,MCUCSR ;для определения источника reset rcall WriteFlash clr DATA
out MCUCSR,DATA /обнуляем его после записи
adiw AddrL,1
ldi ZL,Min
Id DATA,Z+ ;min
rcall WriteFlash
adiw AddrL,1
Id DATA,Z+ ;chs
rcall WriteFlash
adiw AddrL,1
Id DATA,Z+ ;data
rcall WriteFlash
adiw AddrL,1
Id DATA,Z+ ;mes
rcall WriteFlash
adiw AddrL,1
Id DATA,Z ;god
rcall WriteFlash
;проверяем адрес на 7FFF, если равен, сбрасываем разрешение записи
ldi temp, OxFF
ср AddrL,temp
ldi temp,0x7F
cpc AddrH, temp
brne zapisF clr_FE:
clr temp
clr ZH ;старший EEPR
ldi ZL,FEnEE
rcall WriteEEP
reti ;и на выход
zapisF:
adiw AddrL,1 zapisFO: ;запись кадра данных
ldi ZL,Thex ;пишем
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
rrcall WriteFlash
проверяем адрес на 7FFF, если равен, сбрасываем разрешение записи
ldi temp,0xFF
ср AddrL,temp
ldi temp,0x7F
cpc AddrH, temp
breq clr_FE
adiw AddrL,1 ;сохраняем следующий адрес:
clr ZH
ldi ZL,EaddrL mov temp,AddrL
rcall WriteEEP inc ZL
mov temp,AddrH rcall WriteEEP reti /основное прерывание часов



     
 

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