На стр. 220 мы говорили о часах реального времени системы центрального отопления. Напишите процедуру обработки прерывания, которая при каждом прерывании, генерирующемся с периодом 0.1 с, увеличивала бы на единицу значение времени, хранящееся в четырех регистрах данных. Это значение представлено в 24-часовом формате. В каждом байте хранится два BCD-разряда, к примеру, BCD-число 40 в регистре MINUTES представляется как Ь’0100 0000’. Этот формат называется
Решение
При каждом вызове процедуры обработки прерывания необходимо добавлять 1 к четырехбайтному числу, хранящемуся в регистрах HOURS: MINUTES: SECONDS: JIFFY. Причем регистр JIFFY используется как счетчик по модулю 10, SECONDS и MINUTES — по модулю 60, a HOURS — по модулю 24. С учетом этого составим перечень задач:
1. Прибавить 1 kJIFFY.
2. Если JIFFY = 10, то обнулить JIFFY и прибавить единицу к SECONDS. В противном случае перейти к п. 6.
3. Если SECONDS = 60, то обнулить SECONDS и прибавить единицу к MINUTES. В противном случае перейти к п. 6.
4. Если MINUTES = 60, то обнулить MINUTES и прибавить единицу к HOURS. В противном случае перейти к п. 6.
5. Если HOURS = 24, обнулить HOURS.
6. Выйти из обработчика.
Код, реализующий описанный алгоритм, приведен в Программе 7.4. Сохранение и восстановление контекста реализовано обычным образом. Однако, поскольку в обработчике используется регистр FSR, он тоже сохраняется в регистре _fsr и восстанавливается при выходе из обработчика.
_work equ h’4D’; Копия W
_status egu h’4E’; Копия STATUS
_fsr equ h’4F’; Копия FSR
HOURS equ h’20’; Часы 2 разряда
MINUTES equ h’21’; Минуты (2 разряда)
SECONDS equ h’22’; Секунды (2 разряда)
JIFFY equ h’23’; Доли секунды (2 разряда)
; Сначала сохраним контекст
RTC movwf _work; Сохраняем W
swapf STATUS,w; и регистр STATUS,
movwf _status
movf FSR,w; а также регистр FSR
movwf _fsr
bcf INTCON,INTF; Сбрасываем флаг внешнего прерывания
; Основной код --------------
; Задача 1
incf JIFFY,f; Увеличим Jiffy на единицу
movlw d’10’; Сравним десятью
btfss STATUS,Z; ECЛИ равно, TO продолжаем
goto EXIT; ИНАЧЕ выходим из обработчика
; Задача 2
clrf JIFFY; ИНАЧЕ обнуляем Jiffy
movlw SECONDS; Устанавливаем FSR на Seconds
movwf FSR
call BCD_INC; и инкрементируем BCD-число
movlw h’60’; Сравниваем с 0110 0000 (60 BCD)
subwf SECONDS,w
btfss STATUS,Z; ЕСЛИ разно, TO продолжаем
goto EXIT; ИНАЧЕ выходим из обработчика
; Задача 3
clrf SECONDS; ИНАЧЕ обнуляем Seconds
decf FSR,f; Устанавливаем FSR на Minutes
call BCD_INC; и инкрементируем BCD-число
movlw ’60’; Сравниваем с 0110 0000 {60 BCD)
subwf MINUTES,w
btfss STATUS,Z; ЕСЛИ разно, TO продолжаем
goto EXIT; ИНАЧЕ выходим из обработчика
; Задача 4
clrf MINUTES; ИНАЧЕ обнуляем Minutes
decf FSR,f; Устанавливаем FSR ка Hours
call BCD_INC; и инкрементируем BCD-число
movlw h’24’; Сравниваем с 0010 0100 (24 BCD)
subwf HOURS,w
btfsc STATUS,Z; ЕСЛИ не равно, TO продолжаем
clrf HOURS; ИНАЧЕ обнуляем Hours
; --------------------------
; Задача 5
EXIT reovf _fsr,w; Восстанавливаем FSR
movwf FSR
swapf _status,w; Восстанавливаем STATUS
movwf STATUS
swapf _work,f; Восстанавливаем W,
swapf _work,w; не воздействуя на флаги,
retfie; и выходим из обработчика