Обработчик прерывания, код которого приведен в Программе 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
; Разрешаем прерывание от ССР1bsf PIE2,CCP2IE
; Разрешаем прерывание от ССР2bcf 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
; Сохраняем Wswapf STATUS,w
; и регистр STATUSmovwf 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
; Восстанавливаем регистр STATUSmovwf STATUS
swapf _work, f
; Восстанавливаем регистр W,swapf _work,w
; не затрагивая регистра STATUS,retfie
; и выходим из прерывания13.1. Используя Таймер 1 совместно с модулем ССР1, напишите программу, формирующую на выходе ССР1 меандр с периодом 20 мс. Частоту кварцевого резонатора примите равной 8 МГц. Подсказка
: помните, что состояние выхода модуля ССР изменяется только при событии «совпадение», поэтому режим сравнения потребуется переключать «налету» каждые 10 мс.