Обработчик прерывания, код которого приведен в Программе 13.7, просто проверяет по очереди флаги прерывания от каждого модуля ССР и выполняет соответствующие блоки программы. Если установлен флаг прерывания от модуля ССР1 (обнаружен нарастающий фронт
Вообще говоря, операция сброса Таймера 1, осуществляемого по первому событию, вносит некоторую погрешность, поскольку занимает определенное время. В нашем случае это не принципиально, однако при измерении более коротких интервалов с большим разрешением могут возникнуть проблемы. В этих случаях можно оставить Таймер 1 работать в непрерывном режиме, а длительность импульса определять как разность между двумя захваченными 16-битными значениями.
MAIN movlw b100000101’; Модуль ССР1 — захват по нарастающему фронту
movwf CCP1CON
movlw b’00000100’; Модуль ССР1 — захват по спадающему фронту
movwf CCP2CON
bsf STATUS,RP0; Переключаемся в 1-й банк
bsf PIE1,CCP1IE; Разрешаем прерывание от ССР1
bsf PIE2,CCP2IE; Разрешаем прерывание от ССР2
bcf STATUS,RP0; Возвращаемся в 0-й банк
movlw b’00100001’; Таймер 1 включен (1), внутренний генератор (0!
movwf T1CON; Синхронный режим (0), предделитель 2:1 (10)
clrf NEW; Сбрасываем признак нового значения
bsf INTCON,PEIE; Разрешаем прерывания от Таймера/ССР
bsf INTCON,GIE; Разрешаем работу системы прерываний
<<<< Остальной код фоновой программы >>>>
; **************
; Сначала сохраним контекст
ISR movwf _work; Сохраняем W
swapf STATUS,w; и регистр STATUS
movwf status
; **************
; Основной код
btfsc PIR1,CCP1IF;Прерывание от CCP1 (нараст. фронт)?
goto CAPTURE1;ЕСЛИ да, ТО обработаем его!
btfss PIR2,CCP2IF;Прерывание от ССР2 (спад, фронт)?
goto ISR_EXIT
CAPTURE2
movf CCPR2L,w; Берем младший байт захваченного значения
movwf TIME+1; и сохраняем его
movf CCPR2H,w; Берем старший байт захваченного значения
movwf TIME; и сохраняем его
bcf PIR2,CCP2IF; Сбрасываем флаг прерывания
incf NEW,f; Сообщаем фоновой программе о наличии нового значения
goto ISR_EXIT
CAPTURE1
clrf TMR1L; Обнуляем счетный регистр таймера
clrf TMR1H
bcf PIR1,CCP1IF; Сбрасываем флаг прерывания
; ****************
ISR_EXIT swapf _status,w; Восстанавливаем регистр STATUS
movwf STATUS
swapf _work, f ; Восстанавливаем регистр W,
swapf _work,w; не затрагивая регистра STATUS,
retfie ; и выходим из прерывания
13.1. Используя Таймер 1 совместно с модулем ССР1, напишите программу, формирующую на выходе ССР1 меандр с периодом 20 мс. Частоту кварцевого резонатора примите равной 8 МГц. Подсказка: помните, что состояние выхода модуля ССР изменяется только при событии «совпадение», поэтому режим сравнения потребуется переключать «налету» каждые 10 мс.