OVEN movwf _work; Сохраняем W в памяти данных
swapf STATUS,w; Считываем текущее состояние STATUS
movf _status; и сохраняем его в памяти данных
; --------------------
CHECK bcf INTCON,INTF; Сбрасываем флаг внешнего прерывания
btfsc PORTA,0; Сигнал IN?
goto IN; ЕСЛИ не ноль, банка только что вошла в печь
btfsc PORTA,1;Сигнал OUT?
goto OUT;ЕСЛИ не ноль, банка только что вышла из печи
; --------------------
; Точка выхода
swapf _status,w; Восстанавливаем исходное состояние STATUS
movwf STATUS; из памяти данных
swapf _work,f; Теперь восстанавливаем исходное состояние
swapf _work,w; рабочего регистра, не воздействуя на флаги,
retfie ; и возвращаемся в фоновую программу
; --------------------
; Основное тело процедуры обработки прерывания
IN incf EVENT,f; Регистрируем вхождение банки в печь
bcf PORTA,2; Сбрасываем внешний триггер IN,
bsf PORTA,2; формируя импульс его сброса,
goto ALARM; и проверяем наличие аварийной ситуации
OUT decf EVENT,f; Регистрируем выход банки из печи
bcf PORTA,3; Сбрасываем внешний триггер OUT,
bsf PORTA,3; формируя импульс его сброса
ALARM movf EVENT,w; Берем количество банок
addlw -5; Вычитаем 5
btfss STATUS,С; ЕСЛИ нет заема, пищим
goto BUZ_OFF; ИНАЧЕ все в порядке, выключаем звук
bcf PORTB,7; Включаем звуковой излучатель
goto CHECK; и снова опрашиваем внешние триггеры
BUZ_OFF
bsf PORTB,7; Выключаем звук
goto CHECK; и снова опрашиваем внешние триггеры
Основная часть кода просто сбрасывает внутренний флаг прерывания INTF и по очереди проверяет состояние внешних триггеров. В зависимости от их состояния выполняется одна из трех секций обработчика:
1. Если на выводе RA0 ВЫСОКИЙ уровень, значит, банка пересекла луч входного детектора. Соответственно к счетчику (регистру EVENT) прибавляется единица и триггер входного детектора сбрасывается. Если значение счетчика больше четырех, то путем подачи на выход RB0 НИЗКОГО уровня включается звуковой сигнализатор, в противном случае он выключается. Выполняется повторная проверка триггеров.
2. Если на выводе RA1 ВЫСОКИЙ уровень, значит, банка пересекла луч выходного детектора. Соответственно из счетчика EVENT вычитается единица и триггер выходного детектора сбрасывается. Счетчик проверяется на равенство четырем, и звуковой излучатель переключается в соответствующее состояние. Выполняется повторная проверка триггеров.
3. Если ни один из триггеров не установлен, выполняется выход из обработчика.
Данная последовательность повторяется до завершения секций 1 или 2. Это позволяет гарантировать корректную обработку ситуации, когда оба луча перекрываются одновременно или в пределах небольшого временного окна.
Фоновая программа на листинге не показана. Она аналогична фоновой программе из Программы 7.2, т. е. в ней будут сконфигурированы различные порты, регистр-счетчик событий при старте программы будет сброшен, а прерывания разрешены. Очевидно, что данная фоновая программа будет отвечать за формирование сигнала излучателя, а также за выполнение других задач, обработку которых не следует возлагать на обработчик прерывания, чтобы максимально уменьшить размер кода обработчика. В реальной системе фоновая программа могла бы управлять цифровым индикатором, показывающим общее количество банок в печи (четыре — это смешное значение, взятое только для примера). Кроме того, следует реализовать сброс на ненулевое значение после затора, а также предусмотреть какой-нибудь знак, индицирующий (ошибочно вычисленное) отрицательное значение количества банок.