Листинг 16.14

;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  ;мин младш. дес.

;<начиная с адреса $20 у нас хранятся коэффициенты>

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

        rcall ReadClk  ;сложили часы в память

        ldi ZH,0x01;

        ldi ZL,Sek  ;адрес секунд в памяти

        ld temp,Z  ;извлекаем из памяти упакованные Sek

        mov count_sek,temp

        andi temp,0b11110000  ;распаковываем — старший

        swap temp  ;старший в младшей тетраде

        ldi data,10

        mov mult10,data  ;в mult10 всегда будет 10

        mul temp,mult10  ;умножаем на 10 в r1:r0 результат умножения

        andi count_sek,0b00001111  ;младший

        add count_sek,r0  ;получили hex-секунды

                ldi ZL,Hour  ;распакованные в память

                ld temp,Z

                mov data,temp

                andi temp,0b00001111  ;младший часов

                ldi ZL,DeH

                st Z,temp

                andi data, 0b11110000  ;старший часов

                swap data  ;старший в младшей тетраде

                ldi ZL,DdH

                st Z,data

                ldi ZL,Min  ;распакованные в память

                ld temp,Z

                mov data,temp

                andi temp,0b00001111  ; младший минут

                ldi ZL,DeM

                st Z,temp

                andi data,0b11110000  ;старший минут

                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,0b11010000  ;I2С-адрес часов+запись

           rcall write

           brcs stopR  ;C=1 если ошибка

           mov DATA,ClkA  ;адрес регистра секунд

           rcall write

           brcs stopR  ;С=1 если ошибка

           rcall start

           ldi DATA,0b11010001  ; адрес часов+чтение

           rcall write

           brcs stopR  ;C=1 если ошибка

           set;CK

           rcall read  ;читаем секунды

           brcs stopR  ;C=1 если ошибка

           st Z +,DATA  ;записываем секунды в память

           rcall read  ;читаем минуты

           brcs stopR  ;С=1 если ошибка

           st Z+,DATA  ;записываем минуты

           rcall read  ;читаем часы

           brcs stopR  ;С=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

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

Поиск

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