include "p16F877a.inc"
__config _WDT_ON; Разрешаем работу сторожевого таймера
cblock h’20’
_work:1, _status:1
COUNT:2
endc
org 0; Вектор сброса
btfss STATUS,NOT_TO; Сброс от сторожевого таймера?
goto MAIN_LOOP; ЕСЛИ да, TO пропускаем секцию инициализации
goto MAIN; ИНАЧЕ начинаем с нуля
org 4; Вектор прерывания
goto ISR; Обработчик
MAIN bsf PORTB,1; Неактивное состояние линии управления упаковщиком
bsf STATUS,RP0; Переключаемся в 1-й банк
bsf TRISA,4; Вывод TOCKI — вход, а вывод RB1, управляющий
bcf TRISB,1; упаковочной машиной, — выход
movlw b’00101111’; Таймер 0 работает от внешнего сигнала, активный фронт -
movwf OPTION_REG; спадающий, предделитель подключен к сторожевому таймеру
movlw b’0110’; He забыть переключить порт А в цифровой режим
movwf ADCON1; To есть выключить аналоговые входы
bcf STATUS,RP0; Возвращаемся в 0-й банк
bsf INTCON,T0IE; Разрешаем прерывание от Таймера 0
movlw -d'24'; Загружаем в таймер -24 (E8h)
movwf TMR0
clrf COUNT+1; Сбрасываем 2-байтный счетчик коробок
clrf COUNT
bsf INTCON,GIE; Разрешаем прерывания
; Фоновая процедура, которая выполняет различные операции
MAIN_LOOP
clrwdt; Периодически сбрасываем сторожевой таймер
... ...; Остальной код фонового цикла
Находясь в 1-м банке, мы также инициализируем регистр OPTION_REG — подключаем предделитель к сторожевому таймеру и увеличиваем его период тайм-аута в 128 раз. После этого конфигурируем Таймер 0, который должен тактироваться по спадающему фронту сигнала, поступающего на вход T0CKI. И наконец, после возвращения в 0-й банк заносим в счетный регистр таймера значение h’E8’ (т. е. -24), чтобы после поступления 24 импульсов отдатчика происходило переполнение таймера и генерировалось прерывание. После этого для разрешения данного прерывания мы устанавливаем флаги T0IE и GIE регистра INTCON.
Основная фоновая программа начинается с команды clrwdt. Если время выполнения одного прохода основного бесконечного цикла будет не более 7 х 128 = 0.8961 с, т. е. меньше периода сторожевого таймера, то тайм-аут никогда не наступит.
Теперь нам осталось только написать процедуру обработки прерывания, которая будет автоматически вызываться после накопления 24 банок, т. е. после поступления 24 импульсов на вход Таймера 0 и его переполнения. При этом устанавливается флаг T0IF и микроконтроллер переходит по адресу вектора сброса h’004’. В нашем инициализационном коде по указанному адресу мы разместили команду goto ISR. Сам код обработчика прерывания приведен в Программе 13.1.