Листинг 16.11

IniSek: ;секунды — в temp, если бит 7=1

           ;то остановить, иначе завести часы

           sbis PinC,pSDA  ;линия занята

           rcall err_i2c

     ldi ClkA,0  ;адрес регистра секунд

     mov DATA,temp

     rcall write_i2c

     brcs stopW

     ldi temp,$AA  ;все отлично

     rcall out_com

ret

IniClk:  ;установить выход SQW

     ldi ClkA,7  ;адрес регистра управления

     ldi DATA,0b00010000  ;выход SQW с частотой 1 Гц

     rcall write_i2c

     brcs stopW

     ldi temp,$AA  ;все отлично

     rcall out_com

ret

stopW:

             ldi temp,$ЕЕ  ;подтверждение не получено

             rcall out_com

ret

err_i2c:

             ldi temp,$AE  ;линия занята

             rcall out_com

sei

ret

Напомню, ЧТО процедура write_i2c (как и использующаяся далее read_i2c) для доступа к часам уже имеется в файле i2c.prg (см. Приложение 5). Процедурой IniSek мы можем при желании и остановить, и запустить часы. Если нужно остановить, то следует temp придать значение, большее 127. Если temp меньше 128, то в часы запишется значение секунд, и они пойдут. При обнаружении ошибок в компьютер (без запроса с его стороны) выдается определенный код: $АЕ, если линия занята, и $ЕЕ, если подтверждение со стороны часов (АСК) не получено. Если все в порядке, то выдается код $АА. Те же самые вызовы для выдачи кодов у нас будут в других процедурах обращения к часам.

Раздельные процедуры нам понадобились потому, что иногда часы идут, а выход на прерывание МК у них может оказаться отключенным. Тогда нам надо только его подключить, а время сбивать не следует. А когда вызывать эти процедуры? Прежде всего, при включении контроллера: мы помним, что при самом первом запуске часы следует заводить обязательно. Но могут быть и сбои при перебоях с питанием (на практике бывало так, что выход SQW при работе от батарейки самопроизвольно отключался). Для того чтобы правильно организовать процедуру, нам следует сначала выяснить, в каком состоянии часы находятся (листинг 16.12).

Листинг 16.12

ReadSet:

            sbis PinC,pSDA  ;линия занята

            rcall err_i2c

       ldi ClkA,7  ;адрес регистра управления

       rcall read_i2c

       mov temp,data  ;в temp значение регистра управления

       ldi СlкА,0  ;адрес регистра секунд

       rcall read_i2c  ;в data значение регистра секунд

brcs stopW

ret

Записав все эти процедуры в любом месте программы (но поблизости друг от друга, чтобы обеспечить беспроблемный переход на метку stopw), мы включаем в процедуру начального запуска такой фрагмент (листинг 16.13).

Листинг 16.13

;======инициализация часов =======

           rcall ReadSet  ;прочли установочные байты

                                 ;в temp регистр установок, в data секунды

          cpi DATA,$80  ;если больше или равно 128

          brsh setsek  ;то завести часы

          cpi temp,$10  ;если выход не установлен

          brne st_clk  ;тогда только его установка

          rjmp setRAM

setsek:

          clr temp

          rcall IniSek  ;устанавливаем секунды = 0

st_clk:

          rcall IniClk  ;установка выхода

setRAM:

          rcall Rclocklni  ;в любом случае чтение часов в память

...

Значение $10 регистр установок должен иметь, если мы ранее уже устанавливали часы. Процедура чтения значений часов RclockIni в память у нас отсутствует, и мы поспешим исправить это, включив в текст туда же, где находятся остальные процедуры для часов, еще две: ReadClk для чтения BCD-значений и RclockIni для преобразования их в распакованный формат (листинг 16.14). Предварительно зададим место в SRAM, куда мы будем складывать значения всех разрядов времени (включая календарь), и отдельно только часы и минуты, но распакованные (они могут пригодиться для индикации).

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

Поиск

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