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





Процедурой iniSek мы можем при желании и остановить, и запустить часы. Если нужно остановить, то следует temp придать значение, большее 127. Если temp меньше 128, то в часы запишется значение секунд, и они пойдут. Процедура inicik необходима для запуска выдачи внешней частоты. Раздельные процедуры нам понадобились потому, что иногда часы идут, а выход на прерывание МК у них может оказаться отключенным вследствие какого-то сбоя. Тогда нам требуется только подключить его, а установленное время сбивать не следует.

А когда вызывать эти процедуры? Во-первых, при включении контроллера: мы помним, что при самом первом запуске часы следует "заводить" обязательно. Но могут быть и сбои при пропадании питания (на практике бывало так, что выход SQW при переходе на работу от батарейки самопроизвольно отключался). Для того чтобы правильно организовать процедуру, нам следует сначала выяснить, в каком состояний часы находятся (листинг 12.6).

Листинг 12.6
ReadSet:
sbis PinC,pSDA ;линия занята
rcall err_i2c ldi ClkA,7 ;адрес регистра управления rcall read_i2c
mo.v temp, data ;в temp значение регистра управления
ldi ClkA,0 /адрес регистра секунд
rcall read_i2c ;в data значение регистра секунд brcs stopW ret
Записав все эти процедуры в любом месте программы (но поблизости друг от друга, чтобы обеспечить беспроблемный переход на метку stopw), мы включаем в процедуру начального фрагмент кода, приведенный в листинге 12.7.

===========инйциализация часов ==========================
rcall ReadSet ;прочли установочные байты
;в temp регистр управления, в data секунды cpi DATA,$80 ;если больше или равно 128 brsh
setsek ;то завести часы cpi temp,$10 /если только выход не установлен brne st_clk /тогда только его установка rjmp
setRAM setsek: clr temp real! IniSek /устанавливаем секунды = 0 st_clk:
rcall IniClk /установка выхода setRAM:
<чтение часов в память Rclocklni, см. далее>

Значение $10 регистр установок должен иметь, если мы ранее устанавливали часы.
Теперь нужно написать процедуру чтения часов в память МК. Текст поделим на две отдельные процедуры: Readcik для чтения BCD-значений и Rclocklni для преобразования их в распакованный формат. Предварительно зададим место в SRAM, куда мы будем складывать значения всех разрядов времени (включая календарь), и отдельно только часы и минуты, но распакованные (они могут пригодиться для индикации) так, как показано в листинге 12.8.

Листинг 12.8
;SRAM старший байт адреса SRAM=0x01
.equ'Sek = 0x10 /текущие сек BCD -значение
.equ Min = 0x11 /текущие мин
.equ Hour = 0x12 /текущие часы
.equ Date = 0x13 /текущая дата
.equ Month = 0x14 /текущий мес
.equ Year = 0x15 /текущий год
/распакованные часы .equ DdH = 0x16 ; часы старш дес .equ DeH = 0x17 ; часы младший дес .equ DdM = 0x18 ;мин старш дес .equ DeM = 0x19 /минмладш дес
Rclocklni: ;инициализация часов
rcall ReadClk ;сложили.часы в память ldi ZH,0x01;
ldi ZL,Sek ;адрес секунд в памяти
Id temp,Z ;извлекаем из памяти упакованные sek
mov count_sek, temp
andi temp,Obi1110000 /распаковываем — старший swap temp ;старший в младшей тетраде ldi data,10
mov multl0,data ;в multlO всегда будет 10
mul temp,multl0 /умножаем на 10 в rl:r0 результат умножения andi count_sek,ObOOOOllll /младший add count_sek,гО /получили hex-секунды
ldi ZL,Hour /распакованные в память
Id temp, Z
mov data, temp .
andi temp,ObOOOOllll /младший часов ldi ZL, DeH st Z,temp
andi data, 0M1110000 /старший часов swap data /старший в младшей тетраде ldi ZL, DdH st Z,data
ldi ZL,Min /распакованные в память Id temp, Z mov data,temp
andi temp,ObOOOOllll /младший минут ldi ZL, DeM st Z,temp
andi data,0M1110000 /старший минут swap data /старший в младшей тетраде ldi ZL, DdM st Z,data
ret ReadClk: /чтение часов
ldi ZH, 1 -/старший RAM ldi ZL,Sek /адрес секунд в памяти ldi ClkA,0 /адрес секунд в часах
sbis PinC,pSDA
rcall err_i2c
rcall start
ldi DATA, 0Ы1010000 ; 12С-адрес часов+запись
rcall write
brcs stopR ;C=1 если ошибка
mov DATA,ClkA ;адрес регистра секунд
rcall write
brcs stopR.; C=l если ошибка
rcall start
ldi DATA, 0Ы1010001 ;адрес часов+чтение rcall write
brcs stopR ;C=1 если ошибка
set ;CK
rcall read /читаем секунды
brcs stopR ;C=1 если ошибка
st Z+,DATA ;записываем секунды в память
rrcall read /читаем минуты
brcs stopR ;C=1 если ошибка
st Z+,DATA /записываем минуты в память
rcall read /читаем часы
brcs stopR ;C=1 если ошибка
st Z+,DATA /часы записываем в память
rcall read /день недели читаем, но никуда не пишем
brcs stopR ;С=1 если ошибка
rcall read /дата — читаем
brcs stopR / С=1 если ошибка
st Z+,DATA /дату записываем в память
rcall read /месяц читаем
brcs stopR / С=1 если ошибка
st Z+,DATA /месяц записываем в память
clt /НЕ давать АСК — конец чтения
rcall read /год читаем
brcs stopR / С=1 если ошибка
st Z+,DATA /год записываем в память
rcall stop
ret stopR:
ldi temp,$EE /подтверждение не получено rcall out_com
ret



     
 

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