Device = 16F877 'Выберем микроконтроллер
Xtal = 4 'Укажем тактовую частоту
Dim Timer As TMR1L.Word 'Для удобства зададим имя для TMR1
Dim Fact As Bit 'Переменная для фиксирования факта прерывания
TRISD = 0 'Порты PORTB и PORTD - на выход
TRISB = 0
Fact = 0 'Сбросим переменную в ноль, чтобы указать программе, что прерывания еще нет
On_Interrupt GoTo ISR 'Зададим адрес обработчика прерываний
'(он находится по адресу метки ISR)
Timer = 28036 'Загрузим таймер значением
'Это значение я вычислил с помощью программы ProtonHeaderMaker
'чтобы он переполнился через 300 мСек
PIE1.0 = 1
INTCON.6 = 1 'Разрешим прерывание от периферийных устройств микроконтроллера
'так как TMR1 - периферия
INTCON.7 = 1 'Установим бит глобального разрешения прерываний
'Этот бит разрешает работу всех запросов вообще
T1CON = %00110001 'Настроим предделитель для TMR1 и включим таймер
GoTo Main 'После всех настроек перейдем на выполнение главной программы
'А таймер уже тикает и увеличивает свое значение с каждым тиком
'Как вы помните, мы его загрузили значением 28036 в начале
'Как только он дотикает до 65535 и придет следующий тик - это вызовет его
'переполнение и, соответственно, прерывание по переполнению TMR1
ISR:
Context Save 'Сохраним регистры STATUS и аккумулятор
If PIR1.0 = 1 Then 'Проверим, было ли вызвано прерывание именно переполнением таймера TMR1
PIR1.0 = 0 'Если это так, то сразу сбросим флаг этого прерывания, чтобы
'при выходе снова не попасть в обработчик
Nop 'Эти NOPы - корректирующие
Nop 'Но нам они никак не помешают, так как время нам не критично
Nop 'Я оставил как в предыдущем примере
Nop
Nop
Nop
Nop
Fact = 1 'Установим факт запроса прерывания
Timer = 28040 'Загружаем таймер новым значением. Обратите внимание - оно отлично от начального
EndIf
Context Restore 'Восстановим значения регистров W и STATUS
Retfie 'Возврат из обработчика
Main:
Inc PORTD 'Увеличиваем значение 8-разрядного регистра PORTD
DelayMS 100 'Задержка для видимости человеком смены состояния порта
If Fact = 1 Then
PORTB.4 = ~PORTB.4 'А вот и само действие
Fact = 0 'И сброс флага - указание, что мы обработали запрос
EndIf
GoTo Main 'Отправляемся на начало |