Как бы это ни казалось странным, но если вывод ССР сконфигурировать как выход, то захват состояния таймера можно будет осуществлять, программно изменяя состояние данного вывода. Эта особенность позволяет использовать модуль ССР для определения длительности какого-либо внутреннего события или же для «хитрого» одновременного считывания обоих байтов таймера. Позже результат можно будет считать из регистров модуля безо всяких проблем, связанных с раздельным чтением двух регистров.
В качестве примера воспользуемся модулем ССР для измерения периода сигнала кардиограммы, подключив пиковый детектор, показанный на Рис. 7.1 (стр. 208), к выводу ССР1. Предполагая, что Таймер 1 работает в синхронном режиме от собственного кварцевого резонатора частотой 32.768 кГц, инициализационная часть программы может выглядеть следующим образом:
movlw b’00001011’
; Таймер включен, внешний такт, сигнал, синхр. режимmovwf T1CON
; Генератор включен, предделитель — 1:1movlw b’00000100’
; Режим захвата по спадающему фронтуmovwf CCP1CON
clrf NEW
; Обнуляем флаг NEWclrf TMR1H
; Обнуляем Таймер 1clrf TMR1H
bsf STATUS,RP0
; Переключаемся в 1-й банкbsf PIE1,CCP1IE
; Разрешаем прерывание от ССР1bcf STATUS,RP0
; Возвращаемся в 0-й банкbcf PIR1,CCP1IF
; Сбрасываем флаг прерыванияbsf INTCON,PEIE
; Разрешаем прерывания от периферийных устройствbsf INTCON,GIE
; Разрешаем работу системы прерыванийВ обработчике прерывания просто считывается содержимое регистра ССР, которое затем сохраняется в двух временных регистрах. Затем в регистр NEW заносится ненулевое значение, извещающее фоновую программу о наличии нового значения. После этого Таймер 1 сбрасывается для регистрации следующего события.
При использовании резонатора частотой 32.768 кГц и отключенном предделителе разрешающая способность считываемого значения составит 30.5 мкс. Переполнение Таймера 1 при таких параметрах конфигурации будет происходить каждые 2 с, и этого достаточно для регистрации сердечного ритма частотой до 30 ударов в минуту (см. Программу 13.4).
; **************
; Сначала сохраняем контекст обычным образом
ISR movwf _work
; Сохраняем Wswapf STATUS,w
; и регистр STATUSmovwf _status
; ===========
; Основной код
btfss PIR1,CCP1IF
; Было прерывание от CCP1?goto ISR_EXIT
; ЕСЛИ нет, ТО ложная тревогаincf NEW, f
; Сообщаем о новом захватеbcf PIR1,CCP1IF
; Сбрасываем флаг прерыванияmovf CCPR1L,w
; Считываем младший байтmovwf TEMP+1
; Запоминаем егоmovf CCPR1H,W
; Считываем старший байтmovwf TEMP
; Запоминаем егоclrf TMR1L
; Обнуляем Таймер 1clrf TMR1H
; ============
ISR_EXIT swapf _status,w
; Восстанавливаем регистр STATUSmovwf STATUS
swapf _work,f
; Восстанавливаем регистр W,swapf _work,w
; не затрагивая регистр STATUS,retfie
; и выходим из прерыванияВ системах с повышенной надежностью также может быть разрешено прерывание по переполнению Таймера 1. Возникновение этого прерывания означает, что последующее захваченные данные будут некорректны, хотя можно подсчитать количество таких тайм-аутов и таким образом увеличить длительность определяемого интервала. Однако в нашей системе это прерывание было бы логичнее использовать для включения сигнала тревоги!
Режимы 1000…1011, указанные на Рис. 13.7, соответствуют четырем
Помимо установки флага CCP1IF при наступлении события «совпадение» может выполняться одно из четырех действий, определяемое состоянием битов ССР1М[3:0]: