Юрий Ревич - Занимательная микроэлектроника
- Название:Занимательная микроэлектроника
- Автор:
- Жанр:
- Издательство:БХВ-Петербург
- Год:2007
- Город:Санкт-Петербург
- ISBN:978-5-9775-0080-7
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Юрий Ревич - Занимательная микроэлектроника краткое содержание
Для широкого круга радиолюбителей
Занимательная микроэлектроника - читать онлайн бесплатно ознакомительный отрывок
Интервал:
Закладка:
Раздельные процедуры нам понадобились потому, что иногда часы идут, а выход на прерывание МК у них может оказаться отключенным. Тогда нам надо только его подключить, а время сбивать не следует. А когда вызывать эти процедуры? Прежде всего, при включении контроллера: мы помним, что при самом первом запуске часы следует заводить обязательно. Но могут быть и сбои при перебоях с питанием (на практике бывало так, что выход 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, куда мы будем складывать значения всех разрядов времени (включая календарь), и отдельно только часы и минуты, но распакованные (они могут пригодиться для индикации).
Листинг 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
Здесь нам пришлось оформить процедуру чтения из часов отдельно, прямым обращением к процедурам чтения через I 2С, т. к. часы имеют специальный и очень удобный протокол. Если вы им один раз даете команду на чтение (значение адреса 0b11010001), то они начинают выдавать последовательно все значения регистров, начиная с того, к которому было последнее обращение прошлый раз. Здесь мы начинаем с регистра секунд и заканчиваем регистром года. Чтобы остановить выдачу, надо в последнем чтении и не выдавать подтверждение (АСК).
Прочитанные значения складываются в память (в исходном BCD-виде) и отдельно, в процедуре RclockIni, распаковываются для индикации. Об индикации мы тут подробно говорить не будем, вы уже знаете, как ее организовать (для этого надо добавить еще четыре разряда ЧЧ:ММ в обработчик прерывания по таймеру TIM0, см. окончательный вариант измерителя в конце этой главы), остановимся на применении полученных значений времени для наших целей своевременной записи температуры и давления.
Сначала нам еще надо обеспечить ход времени в МК (в память МК должны все время попадать текущие значения времени) и научиться устанавливать часы: пока мы их только «заводили» и устанавливали секунды. Для счета времени установим отдельный регистр-счетчик секунд (не читать же каждую секунду значения часов) и запомним, что его нельзя трогать:
Читать дальшеИнтервал:
Закладка: