ret
stopR:
ldi temp,$EE ;подтверждение не получено
rcall out_com
ret
Здесь нам пришлось оформить процедуру чтения из часов отдельно, прямым обращением к процедурам чтения через I 2С, т. к. часы имеют специальный и очень удобный протокол. Если вы им один раз даете команду на чтение (значение адреса 0b11010001), то они начинают выдавать последовательно все значения регистров, начиная с того, к которому было последнее обращение прошлый раз. Здесь мы начинаем с регистра секунд и заканчиваем регистром года. Чтобы остановить выдачу, надо в последнем чтении и не выдавать подтверждение (АСК).
Прочитанные значения складываются в память (в исходном BCD-виде) и отдельно, в процедуре RclockIni, распаковываются для индикации. Об индикации мы тут подробно говорить не будем, вы уже знаете, как ее организовать (для этого надо добавить еще четыре разряда ЧЧ:ММ в обработчик прерывания по таймеру TIM0, см. окончательный вариант измерителя в конце этой главы), остановимся на применении полученных значений времени для наших целей своевременной записи температуры и давления.
Сначала нам еще надо обеспечить ход времени в МК (в память МК должны все время попадать текущие значения времени) и научиться устанавливать часы: пока мы их только «заводили» и устанавливали секунды. Для счета времени установим отдельный регистр-счетчик секунд (не читать же каждую секунду значения часов) и запомним, что его нельзя трогать:
def count_sek = r26;счетчик секунд
Теперь начнем с последней задачи: как установить нужное время? Для этого напишем процедуру (листинг 16.15), которая будет вызываться из компьютера по команде $A1. А по команде $А2будем читать значение часов.
Листинг 16.15
…
Gcykle
cpi temp,0xA1 ;установить RTC + 6 байт BCD, начиная с секунд
breq ргос_А1
cpi temp,0xA2 ;читать часы в комп.
breq ргос_А2
…
rjmp Gcykle
proc_A1: ;А1 установка часов
rcall SetTime
rjmp Gcykle
proc_A2: ;А2 читать часы в комп. из памяти
rcall ReadTime;
rjmp Gcykle
…
;Процедура преобразования BCD в HEX, специально для времени HEX_time:
;на входе в ZL адрес секунды, часы или минуты на выходе в temp hex-значение,
ld temp,Z;
andi temp,0b11110000 ;распаковываем — старший
swap temp ;старший в младшей тетраде
mul temp,mult10 ; умножаем на 10 в r0 результат
ld temp,Z;
andi temp,0b00001111 ; младший
add temp,r0 ;получили hex
ret
Sclock: ;получить из компьютера 6 байт и записать в память
ldi ZH, 0x01 ;старший RAM
ldi ZL,Sek ;Ram
rcall in_com
st Z+,temp ;sek
rcall in_com
st Z+,temp ;min
rcall in_com
st Z+,temp ;hour
rcall in_com
st Z+,temp ;data
rcall in_com
st Z+,temp ;month
rcall in_com
st Z,temp ;year
push cnt ;сохраняем cnt на всякий случай
rcall SetClk ;переписываем в часы
pop cnt
ret
Setclk: ;установить часы
sbis PinC,pSDA ;линия занята
rcall err_i2c
ldi ZH,0x01
ldi ZL,Sek ;адрес секунд в памяти
ldi ClkA,0 ;регистр секунд ld DATA,Z+ ;извлекаем секунды
rcall write_i2c ;секунды записываем
brcs stops
ldi ClkA,1 ;регистр минут
ld DATA,Z+ ;извлекаем минуты
rcall write_i2c ;минуты записываем
brcs stopS
ldi ClkA,2 ;регистр часов
ld DATA,Z+
rcall write_i2c ;записываем часы
brcs stopS
ldi ClkA,4 ;регистр даты (день недели пропускаем)
ld DATA,Z+
rcall write_i2c ;записываем дату
brcs stopS
ldi ClkA,5 ;регистр месяца
ld DATA,Z+
rcall write_i2c ;месяц записываем
brcs stopS
ldi ClkA,6 ;регистр года
ld DATA,Z
rcall write_i2c ;год записываем
brcs stopS
ldi ClkA,7 ;регистр установок — на всякий случай
ldi DATA, 0Ь00010000
rcall write_i2c
brcs stopS
ldi temp,$AA ;все отлично
rcall out_com
ret
stopS:
ldi temp,$EE ;подтверждение не получено
rcall out_com
ret
SetTime: ;установка текущих значений в МК
cli
rcall Sclock ;записали из компьютера BCD-значения
ldi ZL,Sek ;упакованные секунды
rcall HEX_time ;имеем hex-секунды в temp
mov count_sek,temp ;переписываем в счетчик
Читать дальше
Конец ознакомительного отрывка
Купить книгу