; *********************
; * При каждом вызове обработчика прерывания внутренний *
; * счетчик увеличивается на 20-мс дискрет *
; * Каждую секунду в NEW_SEC заносится ненулевое значение *
; *********************
; Сначала сохраним контекст
ISR movwf _work; Сохраняем W
swapf STATUS,w; и регистр STATUS
movwf _status
; ================
; Основной код
btfss INTCON,T0IF; Произошло переполнение Таймера 0?
goto ISR_EXIT; ЕСЛИ нет, ТО ложная тревога
btfsc Pause,0; Проверяем флаг паузы
goto ISR_EXIT; ЕСЛИ нажата, не инкрементируем
incf JIFFY,f; Регистрируем очередные 1/50 с
movlw d’50’; Досчитали до 50?
subwf JIFFY,w
btfss STATUS,Z
goto ISR_EXIT; ЕСЛИ нет, ТО выходим
clrf JIFFY; ИНАЧЕ обнуляем счетчик дискретов
movf SECOND,f; Счетчик секунд равен нулю?
btfsc STATUS,Z
goto NEW_MIN; ЕСЛИ да, ТО смотрим минуты
decf SECOND,f; ИНАЧЕ декрементируем счетчик секунд,
incf NEW_SEC,f; извещаем основную программу о прохождении секунды
goto ISR_EXIT; и выходим
NEW_MIN movlw d’59’;Реинициализируем счетчик секунд
movwf SECOND
movf MINUTE,f; Счетчик минут равен нулю?
btfsc STATUS,Z
goto ISR_EXIT; ЕСЛИ да, ТО делать больше нечего
decf MINUTE,f; ИНАЧЕ декрементируем счетчик минут
; *************************
ISR_EXIT btfss PORTB,PAUSE; Проверяем кнопку ПАУЗА
call FREEZE; ЕСЛИ нажата, ТО обновляем флаг паузы
bcf INTCON,T0IF; Сбрасываем флаг прерывания
swapf _status,w; Восстанавливаем регистр STATUS
movwf STATUS
swapf _work,f; Восстанавливаем W,
swapf _work,w; не меняя состояния STATUS,
retfie ; и возвращаемся из прерывания
; ***********************
; * ФУНКЦИЯ: Инкрементирует флаг паузы. *
; * ЕСЛИ 1, ТО отображает десятичные точки *
; * ЕСЛИ 0, ТО отображает нормальный отсчет минут *
; * РЕСУРСЫ П/п SPI_WRITE, переменная Pause *
; * ВХОД;Кнопка ПАУЗА нажата *
; * ВЫХОД Кнопка ПАУЗА отжата; соответствующая индикация *
*************************
FREEZE incf Pause,f; Обновляем 0-й бит флага паузы
btfss Pause,0; Проверяем его состояние
goto UNFREEZE; Переход 1 —> 0, разблокируем
; Дисплей заблокирован
movlw b’01111111’;Код для десятичной точки
movwf DATA_OUT_L
movwf DATA_OUT_H
call SPI_WRITE
goto FREEZE EXIT
UNFREEZE; Сюда переходим, если 0-й бит флага изменился 1 —> 0.
movf MINUTE,w; Отображаем оставшееся количество минут
call OUTPUT
FREEZE_EXIT
btfss PORTB,PAUSE; Ждем отпускания кнопки
goto FREEZE_EXIT; Сбрасываем таймер/предделитель
clrf TMR0
return