Вы находитесь на странице: 1из 11

6/6/5. Работа модуля CCP в режиме сравнения.

Пример практической
реализации порогового устройства (счетчик событий, происходящих в "границах"
калиброванного интервала времени, с выдачей сигнала о превышении порога.
Частный случай - частотный компаратор).

Из названия режима понятно, что что-то с чем-то сравнивается, с целью достижения,


пока еще, "туманной" цели.
А раз это так, то "следствие продолжается".
Структурная схема модуля CCP, работающего в режиме сравнения, изображена на
этом рисунке:

Сравнивается содержимое двухбайтных регистров TMR1H/TMR1L и CCPR1H/CCPR1L.


Регистр CCPR1H/CCPR1L не считает (аналогия с регистром PR2 модуля TMR2).
В него можно только записать число или несколько чисел (последовательно), если
производится несколько сравнений.
Если есть такая необходимость, то можно и считать.
То есть, в регистр CCPR1H/CCPR1L, записывается некий числовой "эталон" ("порог"), с
которым что-то сравнивается.
Вопрос: "Что сравнивается"?
Ответ: числовое значение двухбайтного слова, "лежащего" в регистре TMR1H/TMR1L.
А вот он уже работает в динамике, то есть, считает количество импульсов внутреннего
или внешнего такта (зависит от настройки модуля TMR1).
Таким образом, значение числа, записанного в регистр CCPR1H/CCPR1L, делит
числовой диапазон на два "сектора".
В одном из них, "цветут ромашки и поют соловьи", а в другом кричат "караул,
убивают!"
Если речь идет о сравнении, значит должно иметь место быть устройство сравнения.
Оно и есть, причем, принцип его работы такой же, как и принцип работы устройства
сравнения модуля TMR2, который был описан ранее, разница только в байтности.
После того как TMR1H/TMR1L досчитает до "порга" (напоминаю, что содержимое
регистра TMR1H/TMR1L только инкрементируется), поднимается флаг прерывания от
модуля CCP (CCP1IF), причем, это происходит во всех подрежимах режима сравнения,
которых четыре.
Выбор одного из них зависит от состояний все тех же битов с №№3…0 регистра
CCP1CON.

№3 №2 №1 №0 Действия
1 0 0 0 Сравнение с установкой 1 на выводе RB3.
1 0 0 1 Сравнение с установкой 0 на выводе RB3.
1 0 1 0 Сравнение с отсутствием влияния на состояние вывода RB3
1 0 1 1 Сравнение с использованием триггера специальных функций

От этих кодовых комбинаций зависит результат "подрежимной рулежки",


осуществляемой устройством управляющей логики.

1
На мой взгляд, на практике, наиболее востребованным является подрежим сравнения с
использованием триггера специальных функций (грозно-то как… Смахивает на
присвоение курице статуса орла).
Особенность этого подрежима состоит в том, что событие совпадения числовых
значений содержимого регистров TMR1H/TMR1L и CCPR1H/CCPR1L приводит не только
к поднятию флага CCP1IF, но и к сбросу в ноль содержимого регистра TMR1H/TMR1L
(аппаратная предустановка нуля, см. рис 1).
После этого, TMR1H/TMR1L начнет считать от нуля, досчитает до "порога", опять
сбросится и т.д.
Таким образом можно сформировать периодическую последовательность калиброванных
интервалов времени, длительность которых зависит:
- от значения числа, записанного в регистр CCPR1H/CCPR1L (от 1 до 65535),
- от значения установленного Кдел. предделителя модуля TMR1 (1, 2, 4, 8),
- от значения периода импульсной последовательности, импульсы которой
подсчитываются.
Если предделитель модуля TMR1 имеет Кдел. = 1, то шаг этого калиброванного
интервала времени может быть равен либо периоду внутреннего такта, либо периоду
внешнего такта (зависит от настройки модуля TMR1).
В последнем случае, модуль TMR1 должен работать в режиме синхронизации.
Если Кдел. предделителя модуля TMR1 равен 2, 4 или 8 (отличен от 1), то шаг
калиброванного интервала времени увеличится соответственно в 2, 4 или 8 раз.
Например, в случае применения кварца на 4 Мгц. и работе модуля TMR1 от
внутреннего такта, можно сформировать калиброванные интервалы времени в
диапазоне:
- от 1 до 65535 мкс. с шагом = 1 мкс.,
- от 2 до 131071 мкс. с шагом = 2 мкс.,
- от 4 до 262143 мкс. с шагом = 4 мкс.,
- от 8 до 524288 мкс. с шагом = 8 мкс.
Если применить кварц другого номинала, но нужно, с учетом времени исполнения
одного машинного цикла, произвести соответствующий пересчет.
Можно "оставить кварц в покое" и перейти на внешний такт.
Таким образом, возможности подбора желаемого значения калиброванного интервала
времени достаточно внушительны.
Если прерывания от модуля CCP разрешены, то по факту окончания формирования
каждого такого калиброванного интервала времени (совпадение, триггер специальных
функций срабатывает), происходит уход в прерывание.
То есть, речь идет о периодических уходах в прерывания, частоту и период которых
можно точно задать.
Примерно о том же самом говорилось ранее, при "разборках" с модулем TMR2, но
модуль TMR2 "укомплектован" однобайтными регистрами, а модуль CCP, работающий в
режиме сравнения, "укомплектован" двухбайтными регистрами.
Чувствуете разницу в диапазонах возможностей?
Итак, периодически уходим в прерывания.
А нельзя ли "сваять" нечто более полезное и более "глобальное", чем разработанный
ранее мультивибратор?
После "завязывания в узел своей извилины и затягивания этого узла" (тренировка
гибкости), она "не выдержала пытки" и "выдала на гора" "нижележащее".
Используя модуль CCP, работающий в режиме сравнения (с использованием триггера
специальных функций), организую периодический уход в прерывания, то есть,
формирую интервалы времени подсчета.
За это время нужно что-то подсчитать.
В качестве этого "чего-то" выбираю количество импульсов импульсной
последовательности, подаваемой на счетный вход модуля TMR0 (вывод RA4).
Этот внешний сигнал может быть либо периодической последовательностью импульсов
той или иной частоты (например, с выхода внешнего генератора импульсов), либо
непериодической "абракадаброй", которая формируется датчиком, кнопкой, рубильником,
включаемым пьяным электриком, и т.д.
С точки зрения "ваяния" чего-то полезного, подсчет ради подсчета есть занятие, хотя
и самодостаточное, но слегка глуповатое (см. "Мертвые души" - Плюшкин).
2
Значит, после того, как "мешок с нулями и единицами будет заработан", его нужно
"пустить в оборот", с целью получения двух (желательно и больше, но нужно быть
скромнее) вышеупомянутых "мешков".
Следовательно, результат подсчета нужно "привязать" к какому-то событию,
неконтролируемость которого может привести к "печальным последствиям".
Слежение за такими событиями может быть произведено не только с целью
констатации факта возникновения (или нет) "бяки", но и с целью ее упреждения
(недопущения).
Не буду "широко замахиваться" на "саморегулирующиеся" системы с обратными
связями.
Пока ограничусь банальным контролем типа "бяки нет" - "бяка есть" (но "с дальним
прицелом").
Слова "есть/нет" наталкивают на мысль о применении порогового устройства,
осуществляющего слежение за этим "есть/нет".
А нельзя ли сделать так, чтобы, в ходе слежения за "бякой", делалось еще какое-то
полезное дело (в комплексе)?
Можно.
Но с учетом специфики.
Например, программа исполняется (в "зоне" разрешения прерываний), и одновременно,
аппаратно производится подсчет импульсов внутреннего или внешнего такта (с
помощью модуля CCP, работающего в режиме сравнения, это сделать можно).
Но все это выполняется "параллельно" только до момента окончания подсчета.
Как только это произойдет, выгоднее всего (по причине минимальной инерционности
отклика) уйти в прерывание.
Соответственно, на время отработки ПП прерывания, работа в "основном теле"
программы (а если конкретно, то в "зоне" разрешения прерываний) прекращается.
То есть, "делается только одно дело", а другое "дело" "стоит в очереди".
Чтобы минимизировать интервал времени этих "прекращений", увеличив тем самым
интервал времени одновременного "делания 2-х дел", нужно, чтобы большую (ударение
на "о") часть времени рабочая точка программы "крутилась" в "основном теле"
программы, а время исполнения ПП прерывания было минимальным (желателен
"реактивный свист").
Кроме того, частота ухода в прерывания не должна быть слишком высокой, что
означает: время подсчета должно быть не слишком коротким (чем больше, тем лучше.
В пределах разумного).
Только после этого можно говорить о минимальном воздействии прерываний на
результат работы программы в ее "основном теле".
Это особенно актуально, когда в нем осуществляются калиброванные задержки.
Например, в "основном теле" программы организована "моргалка".
Если уход в прерывание произойдет во время ее работы, то какой-либо из
полупериодов, который формирует эта "моргалка", будет затянут на время отработки
ПП прерывания.
Если частота "моргания" будет высокой, то, при одном и том же времени отработки
ПП прерывания, процентное отклонение периода "моргания" от расчетного будет
больше, чем в случае, если частота "моргания" будет низкой.
Кроме того, всегда нужно учитывать то, что, в "зоне" разрешения прерываний, возврат
из прерывания может произойти на любую команду.
О негативных последствиях игнорирования этой особенности говорилось при
"разборках" с режимом захвата.
Если в "зоне" разрешения прерываний имеется команда, возврат на которую приводит
к нарушению работы программы, то ее нужно "локализовать", запретив прерывания на
время исполнения этой команды и разрешив их после ее исполнения.
То же самое относится и к группе команд.
При этом нужно учитывать то, что прерывание может возникнуть в "зоне" этой
"локализации" (во время "локального" запрета прерываний).
Если такое произойдет, то уход в прерывание осуществлен не будет.
Из-за этого, в случае наличия узкой "зоны" разрешения прерываний, могут быть
большие проблемы.

3
Чем шире "зона" разрешения прерываний, тем этих проблем меньше, так как
вероятность сбоя, при уходе в прерывание, уменьшается.
Если имеет место быть периодическая последовательность каких-то действий,
например, подсчетов, то сбой, связанный с пропуском ухода в прерывание, приведет
либо к неверному результату подсчета (в пределах текущего цикла счета), либо к
игнорированию результатов текущего подсчета (зависит от "конструкции" программы).
В принципе, это не "страшно", так как следующие подсчеты будут произведены верно.
В этом случае, задача конструктора сводится к уменьшению (желательно, до
пренебрежимо малой величины) вероятности пропуска ухода в прерывание, который
(пропуск) происходит из-за наличия "локальной зоны" ("зон") запрета прерываний.
Проще говоря, создаются условия, при которых эта разновидность функциональных
сбоев происходит очень редко.
При наличии "обширной зоны" разрешения прерываний, с как можно более
немногочисленными "вкраплениями" в нее узких, "локальных зон" запретов прерываний
(в идеале, нужно стремиться к их отсутствию), эти условия достаточно легко
обеспечиваются.
А если еще программно позаботиться об игнорировании (блокировке) результата
подсчета, в цикле которого был проигнорирован уход в прерывание, то будет вообще
прекрасно.
Таким образом, в части касающейся заявленной темы, при конструировании устройств,
одновременно "делающих 2 дела", нужно:
- учитывать задержки, связанные с уходами в прерывания и иметь представления о
том, как минимизировать их негативное влияние (если оно существенно) на работу
программы в ее "основном теле",
- при наличии "локальных зон" запретов прерываний, нужно программно позаботиться о
"сведении на нет" количества функциональных сбоев, происходящих из-за наличия
этих "зон", и о блокировке результатов подсчетов, в циклах которых произошли эти
сбои.
"Артподготовка" закончена. Теперь "шашки наголо".

На рис. 2, Вы видите принципиальную схему учебно – тренировочного устройства, в


котором реализовано сказанное выше.
С помощью модуля CCP, работающего в режиме сравнения, с использованием
триггера специальных функций, формируются калиброванные интервалы времени
подсчета.
В пределах этих интервалов времени, модуль TMR0 считает количество импульсов,
поступающих на его счетный вход (вывод RA4) от внешнего генератора импульсов,
собранного на м/схеме 561ЛА7.

4
По окончании интервала времени подсчета, происходит уход в ПП прерывания, в
которой результат подсчета, "осевший" в TMR0, сравнивается с заданным, числовым
"порогом".
Если "порог" превышен, то "загорается" светодиод "Контроль" ("горит" в течение
всего времени превышения).
Если "порог" не превышен, то он либо не "загорается" (подтверждение ранее
установленного состояния), либо "гасится" (если он "горел" в предыдущем цикле
подсчета).
В данном случае, происходит слежение за тем, вышла ли частота внешнего
генератора импульсов за заданную частотную "границу" или нет.
В качестве этой частотной "границы", я назначил частоту 1000 Гц (для ровного счета),
но можно назначить и другую.
Таким образом, если внешний, импульсный генератор будет выдавать частоты более
1000 Гц., светодиод "Контроль" "загорится", а если он будет выдавать частоты менее
1000 Гц., светодиод "Контроль" "погаснет".
Этому устройству "глубоко наплевать" на характер импульсной последовательности
(равномерная, неравномерная или "гибрид"), подаваемой на вывод RA4.
Строго говоря, "его интересует" не частота как таковая, а количество импульсов,
"втискивающихся" в интервал времени подсчета (причем, он не равен 1 сек., а
меньше).
Просто, в данном случае, удобнее "привязаться" к частоте.
Получается что-то типа однопорогового, частотного компаратора.
На его основе вполне можно "состряпать" и двухпороговый, и N – пороговый.
А это уже прямой выход на "узкополосность".
Светодиод "Основное тело" есть оконечное устройство "моргалки", реализованной в
"основном теле" программы (в "зоне" разрешения прерываний).
По характеру его "моргания" можно визуально отследить и оценить работу программы
в ее "основном теле", с учетом величины "затягиваний" периодов "морганий",
происходящих из-за периодических "отлучек" рабочей точки программы в ПП
прерывания.
В идеале, светодиод "Основное тело" должен равномерно "моргать"
(неравномерность визуально не ощущается) в течение всего времени работы
устройства.
Итак, первое "дело" связано с подсчетом импульсов и "выдачей" результатов анализа
этих подсчетов "наружу" (светодиод "Контроль"), а второе - с "морганием" светодиода
"Основное тело".
И оба этих дела делаются "одновременно" (надеюсь, что смысл кавычек понятен).
Если рассуждать "глобально", то вместо "несерьезной моргалки" (частный случай),
можно организовать что-то "посолиднее", "помассивнее" и "пофункциональнее".
Простора для творчества - "выше крыши".
Пару слов о внешнем генераторе импульсов.
Естественно, что можно использовать и что-нибудь посолиднее того, что изображено
на рис. 2, но я ориентировался на людей, у которых нет генератора импульсов.
Этой простенькой схемой генератора импульсов я частенько пользуюсь.
Главная особенность такого генератора заключается в том, что он имеет широкий
диапазон перестройки частоты, и скважность, при этом, не слишком сильно "гуляет".
Так как используется м/схема 561 серии, то пяти вольт маловато и поэтому пришлось
запитать генератор с входа стабилизатора.
"Эксперименты" проводились при напряжении на 14-й ножке = 9,5 вольт.
А раз это так, то пришлось ограничить амплитуду импульсов при помощи
параметрического стабилизатора R4VD3.
U стабилизации КС147А = 4,7 вольт.
Вместо него можно поставить КС139А.
Это устройство "обслуживает" следующая программа:

;********************************************************************************
; Sravn_1.asm УЧЕБНОЕ УСТРОЙСТВО КОНТРОЛЯ ВЫХОДА (ИЛИ НЕТ) КОЛИЧЕСТВА
; СОБЫТИЙ, ПРОИСХОДЯЩИХ В ПРЕДЕЛАХ ЗАДАННОГО ИНТЕРВАЛА ВРЕМЕНИ,
; ЗА ЗАДАННУЮ "ГРАНИЦУ".

5
;--------------------------------------------------------------------------------
; Задействуется модуль CCP, работающий в режиме сравнения (с триггером
; специальных функций).
;********************************************************************************
; "Практикум по конструированию устройств на PIC контроллерах"
; (http://ikarab.narod.ru)
; Корабельников Евгений Александрович karabea@Lipetsk.ru
;********************************************************************************
; Функции выводов порта А:
; RA4 - счетный вход TMR0, остальные не задействованы.
; Функции выводов порта В:
; к RB0 подключен контрольный светодиод работы в "основном теле" программы,
; к RB7 подключен контрольный светодиод, индицирующий выход (или нет) за пределы
; заданного количества событий.
; Остальные выводы порта В не задействованы.
; Кварц 4000 Кгц (1 м.ц.= 1 мкс.).
; Используется PIC16F628A.
;----------------------------------------------
; Объем программы: 55 слов в памяти программ.
;********************************************************************************
LIST p=16F628A ; "Привязка" MPLAB к микроконтроллеру
; PIC16F628A.
__CONFIG 03F21H ; Определение значений битов конфигурации: бит
; защиты выключен, WDT выключен, стандартный
; генератор XT.
;================================================================================
; "Прописка" регистров специального назначения.
;================================================================================
Tmr0 equ 01h ; Таймер TMR0.
OptionR equ 01h ; Регистр Option-банк1.
Status equ 03h ; Регистр Status.
PortB equ 06h ; Регистр Port B.
TrisB equ 06h ; Регистр Tris B-банк1.
IntCon equ 0Bh ; Регистр IntCon.
CMCON equ 1Fh ; Регистр управления модулем компараторов.
PIE1 equ 0Ch ; Регистр разрешения прерываний
; от периферийных модулей.
PIR1 equ 0Ch ; Регистр флагов прерываний
; от периферийных модулей.
T1CON equ 10h ; Регистр управления модулем таймера TMR1.
CCP1CON equ 17h ; Регистр управления модулем CCP.
CCPR1L equ 15h ; Регистр младшего разряда CCP.
CCPR1H equ 16h ; Регистр старшего разряда CCP.
TMR1L equ 0Eh ; Регистр младшего разряда TMR1.
TMR1H equ 0Fh ; Регистр старшего разряда TMR1.
;================================================================================
; "Прописка" регистров общего назначения.
;================================================================================
SecL equ 70h ; Регистр младшего разряда счетчика.
SecM equ 71h ; ------- среднего ----------------
SecH equ 72h ; ------- старшего ----------------
;================================================================================
; Присваивание названий местам размещения результатов операций.
;================================================================================
F equ 1 ; Результат направить в регистр.
W equ 0 ; Результат направить в аккумулятор.
;================================================================================
; Присвоение названий битам регистров специального назначения.
;================================================================================
RP0 equ 5 ; Бит переключения банков.
C equ 0 ; Флаг переноса-заема.
CCP1IF equ 2 ; Флаг прерывания от модуля CCP.
;================================================================================
; Подготовка к началу исполнения программы.
;================================================================================
org 0 ; Начальная точка отсчета в PC - нулевой адрес
6
goto START ; Переход на начало программы.
org 4 ; Начать исполнение ПП прерывания c команды,
; которая, в PC, имеет адрес 04h.
;********************************************************************************

;================================================================================
; Подпрограмма прерывания.
;================================================================================
; Примечание: "граничное" количество событий равно:
; 16 (Кдел. предделителя TMR0) х {2 (константа)+1} = 48.
;------------------------------------------------------
movf Tmr0,W ; Копирование содержимого TMR0 в W.
sublw .2 ; .2 - Tmr0 = ...
bcf PortB,7 ; "Гашение" светодиода "Контроль"
; (для устранения триггерного эффекта).
btfss Status,C ; Результат вычитания "+" или "-" ?
bsf PortB,7 ; Если "-" (C=0), то "загорание"
; светодиода "Контроль"
; (выход за границу дозволенного).
clrf Tmr0 ; Если "+" (С=1), а также после исполнения
; предыдущей команды, содержимое TMR1
; сбрасывается в 0.
bcf PIR1,CCP1IF ; Сброс флага CCP1IF.
retfie ; Выход из прерывания.
;--------------------------------------------------------------------------------

;================================================================================
; Начало программы.
;================================================================================
; Подготовительные операции.
;--------------------------------------------------------------------------------
START bsf Status,RP0 ; Переход в 1-й банк.
clrf TrisB ; Все выводы порта В работают на выход.
movlw b'00100011' ; TMR0 работает от внешнего такта,
movwf OptionR ; с предделителем (K=16).
bcf Status,RP0 ; Переход в 0-й банк.

movlw 7 ; Выключение модуля


movwf CMCON ; компараторов.
;------------------------------------------
; Настройка модуля TMR1.
;------------------------------------------
movlw b'00000001' ; TMR1 работает от внутреннего
movwf T1CON ; такта, с Кдел. предделителя = 1.
;------------------------------------------
; Настройка модуля CCP.
;------------------------------------------
movlw b'00001011' ; Переход в режим сравнения с задействованием
movwf CCP1CON ; триггера специальных функций.
;------------------------------------------
; Задание интервала времени подсчета.
;------------------------------------------
movlw .187 ; Устанавливается интервал
movwf CCPR1H ; времени подсчета
movlw .128 ; 187*256+128=48000 мкс.
movwf CCPR1L ;
;------------------------------------------
; Сброс таймеров.
;------------------------------------------
clrf TMR1L ; Сброс
clrf TMR1H ; TMR1.
clrf Tmr0 ; Сброс TMR0.
;------------------------------------------
bcf PIR1,CCP1IF ; Сброс флага CCP1IF.

7
;------------------------------------------
; Разрешение прерываний от модуля CCP.
;------------------------------------------
movlw b'11000000' ; Глобальное разрешение прерываний и
movwf IntCon ; разрешение прерываний
; от периферийных модулей.
bsf Status,RP0 ; Переход в 1-й банк.
movlw b'00000100' ; Разрешение прерываний
movwf PIE1 ; от модуля CCP.
bcf Status,RP0 ; Переход в 0-й банк.
;------------------------------------------
; Мультивибратор.
;------------------------------------------
SNOVA bsf PortB,0 ; Формирование, на выводе
call PAUSE ; RB7, уровня 1.
;---> Возврат по стеку из ПП PAUSE.
bcf PortB,0 ; Формирование, на выводе
call PAUSE ; RB7, уровня 0.
;---> Возврат по стеку из ПП PAUSE.
goto SNOVA ; Переход на начало формирования
; следующего периода.
;------------------------------------------
; Задержка 0,3 сек.
;------------------------------------------
PAUSE movlw .153 ;
movwf SecL ;
movlw .134 ; Запись констант в
movwf SecM ; регистры счетчика.
movlw .2 ;
movwf SecH ;

WR decfsz SecL,F ; Стандартный,


goto WR ; 3-байтный,
decfsz SecM,F ; вычитающий
goto WR ; счетчик.
decfsz SecH,F ;
goto WR ;

return ; Возврат по стеку.


;********************************************************************************
end

Темно – синим цветом выделена ПП прерывания.


Темно – красным цветом выделена "зона" разрешения прерываний.
Синим цветом выделены подготовительные операции.

Работа программы.
Так как к выводам RB0 и RB7 подключены светодиоды, а остальные выводы порта В
не задействуются, то лучше всего настроить, на работу "на выход", все выводы порта
В, что и сделано (clrf TrisB).
Настройка направлений работы выводов порта А не производится по той причине, что,
по умолчанию, все выводы порта А работают "на вход" (см. окно SFR).
Далее, при помощи регистра OptionR, производится настройка TMR0.
TMR0 производит подсчет количества импульсов импульсной последовательности,
вырабатываемой внешним генератором импульсов, за калиброванный интервал времени
подсчета.
Длительность этого интервала времени не равна 1 сек. (она меньше).
То есть, если речь идет о "пороговой" частоте 1000 Гц., то, в данном случае, это не
говорит о том, что считаются 1000 (или другое количество) импульсов в секунду.
Считается количество импульсов за меньший интервал времени, но в пересчете на
количество импульсов в секунду, получается частота 1000 Гц.
Если использовать TMR0 без предделителя, то диапазон "пороговых" частот, одну из
которых можно выбрать, сужается.
8
Поэтому лучше использовать предделитель (хотя, есть случаи, когда он не нужен).
В данном случае, предделитель используется, и в нем установлен Кдел. = 16
("ориентирован" на "пороговую" частоту 1000 Гц.).
После настройки TMR0, производится стандартное отключение модуля компараторов,
хотя, его можно и не отключать (выводы RA0…RA3 не задействованы).
Теперь нужно настроить модуль TMR1.
В каждом цикле подсчета, он подсчитывает количество импульсов внутреннего такта
ПИКа (начиная от нуля).
Соответственно, модуль TMR1 настраивается на работу от внутреннего такта.
Кдел. предделителя TMR1 выбран равным 1, но можно выбрать и больший, только
нужно учесть, что при этом происходит кратное (в соответствии с Кдел.) увеличение
времени формирования интервала времени подсчета и шага.
Далее происходит настройка модуля CCP.
Ничего нового в ней нет, за исключением отсутствия команды clrf CCP1CON.
Она нужна при работе в режиме захвата, в случае переключений типа события
захвата, а в режиме сравнения она не нужна.
Действие - простейшее: устанавливается режим сравнения с задействованием триггера
специальных функций.
Итак, модули TMR0, TMR1 и CCP настроены и с ними можно работать.
Теперь нужно задать интервал времени подсчета.
В данном случае, можно установить любое значение интервала времени подсчета из
диапазона 1 … 65535 мкс. (шаг 1 мкс.).
Я установил 48000 мкс.
Разложение: 48000 = 256х187 + 128.
Вот Вам и константы, которые нужно записать в CCPR1H/CCPR1L, что и сделано.
После этой записи, значение числа, записанного в CCPR1H/CCPR1L, меняться не
будет ("эталон") вплоть до выключения питания.
Теперь, для обеспечения безошибочности первого подсчета, нужно обеспечить
одновременное начало счета TMR0 и TMR1, от нуля.
Пояснение: далее (начиная со 2-го подсчета), TMR1 будет сбрасываться триггером
специальных функций, а TMR0 будет сбрасываться в ПП прерывания.
В тексте программы Sravn_1.asm, Вы видите, на мой взгляд, самое оптимальное,
программное решение этой задачи, которое может пригодиться в будущем.
Сначала в ноль сбрасывается TMR1H/TMR1L.
При этом, счет TMR1 запрещен не только на время исполнения команд clrf TMR1L и
clrf TMR1H, но и на время исполнения следующей команды (аппаратная особенность, о
которой говорилось ранее).
Если этой "следующей" командой будет команда clrf Tmr0, то, после исполнения этой
команды, начиная со следующего машинного цикла, TMR0 и TMR1 синхронно
(одновременно) начнут считать от нуля (только каждый свое).
Если сбросить TMR0 до сброса TMR1, то такого одновременного начала счета, от
нуля, не будет (TMR0 начнет считать раньше TMR1).
Далее, флаг прерываний от модуля CCP опускается (в "зону" разрешения прерываний
нужно входить с опущенным флагом прерывания).
После этого, исполняется стандартная процедура разрешения прерываний от
периферийного модуля (в данном случае, ССP).
Таким образом, начиная с команды bcf Status,PR0, прерывания от модуля CCP
разрешаются, и эта команда является первой командой "зоны" разрешения прерываний.
Начиная с этого момента, прерывания от модуля CCP разрешаются вплоть до
выключения питания устройства.
В "зоне" разрешения прерываний, программно реализован автоколебательный
мультивибратор, вырабатывающий "меандр" с периодом 0,3 c. + 0,3 c. = 0,6 c.
Все это "хозяйство" работает на светодиод "Основное тело".
Ничего нового в этом мультивибраторе нет.
Итак, мультивибратор работает (светодиод "мигает").
Одновременно, TMR1 считает количество импульсов внутреннего такта ПИКа.
Как только он насчитает 48000 импульсов, устройство сравнения вырабатывает сигнал,
поднимающий флаг CCP1IF, и происходит уход в ПП прерывания.

9
В ПП прерывания, нужно быстренько скопировать то, что насчитал TMR0, в регистр W
(movf Tmr0,W), после чего можно, не опасаясь продолжения подсчета,
проанализировать его результат.
В предделителе и TMR0, на момент ухода в прерывание, "лежит" число импульсов,
выработанных внешним генератором за калиброванный интервал времени подсчета
(48000 мкс.).
Я организовал только проверку содержимого TMR0, но в случаях, когда требуется
особая точность, можно организовать и проверку содержимого "связки" предделитель –
TMR0.
В этом случае, нужно "ввести в эксплуатацию" блокировочный вывод порта, произвести
процедуру досчета и организовать проверку содержимого не однобайтного, а
двухбайтного регистра.
В большинстве случаев, без этого вполне можно обойтись.
Итак, числовое значение содержимого регистра Tmr0 сравнивается с константой,
величина которой и задает "порог".
В данном случае, это константа .2.
Из нее вычитается то, что насчитал TMR0.
После этого, с целью ответа на вопрос "результат вычитания положительный или
отрицательный?", проверяется состояние флага С.
При этом следует учесть, что нулевой результат вычитания "воспринимается флагом"
С как положительный результат.
А раз это так, то нужно уменьшить значение вычисленной константы на единицу.

Пример расчета "пороговой" константы для частоты 1000 Гц.

Период импульсной последовательности с частотой 1000 Гц. = 1/1000 = 1000 мкс.


В данном случае, интервал времени подсчета = 48000 мкс.
48000 мкс/1000 мкс. = 48.
48/16 (Кдел. предделителя) = 3.
3 – 1 = 2.
Вот Вам и объяснение, откуда взялась константа .2.

Как видите, ничего особо сложного нет.


Меняя величину этой константы (в том числе и в комплексе с изменением Кдел.
предделителя модуля TMR0) и величину интервала времени подсчета, можно назначить
частотным "порогом" частоту из достаточно широкого диапазона частот.
В зависимости от результата проверки содержимого регистра Tmr0, светодиод
"Контроль" может либо "загореться" (выход за "порог" есть), либо остаться
погашенным (выхода за "порог" нет).
Сигнал управления, присутствующий на выводе RB7, можно использовать для
воздействия на частоту внешнего генератора (при наличии управляющей обратной
связи) или для других целей.
Но если светодиод "Контроль" "загорается", значит он должен и "гаситься".
Я сделал это не в "зоне" разрешения прерываний, а в ПП прерывания (bcf PortB,7).
Если команду bcf PortB,7 убрать, то будет иметь место быть триггерный эффект: если
произойдет "загорание" светодиода "Контроль" (превышение "порога"), то после
уменьшения частоты до значений ниже 1000 Гц., светодиод не "погаснет", а будет
продолжать "гореть" вплоть до выключения питания.
"Топаю" дальше.
После анализа содержимого регистра Tmr0 и соответствующих "оргвыводов", нужно
обеспечить счет от нуля в следующем цикле подсчета (clrf Tmr0), сбросить флаг
прерывания CCP1IF и быстренько "покинуть" ПП прерывания (а в нем больше и
делать нечего).
Таким образом, интервал времени "отлучки" рабочей точки программы из "зоны"
разрешения прерываний составляет всего 11 м.ц. (мкс.).
Визуально заметить затягивание времени формирования того или иного полупериода,
происходящее в результате таких коротких "отлучек", практически невозможно.
Светодиод "Основное тело" будет равномерно "моргать".

10
Эти "отлучки" будут происходить с периодичностью в 48000 мкс. (периодичность
обеспечивает триггер специальных функций), и вне зависимости от того, что насчитает
TMR0 и какие "оргвыводы" из этого будут сделаны.
В данном случае, в "зоне" разрешения прерываний, нет ничего "криминального" (в
смысле возврата на команду-"бяку") и поэтому нет необходимости в создании
локальных "зон" запрета прерываний ("идеал", но в других, более сложных случаях, его
может и не быть).
Опять же, в данном случае, в ПП прерывания, не нужно "суетиться" с
сохранением/восстановлением содержимого регистров Status и W, а также и с
переходом в 0-й банк (необходимости в этом нет).
Я погонял это устройство в "железе" и заметил одну особенность.
При постепенном приближении к "порогу", в непосредственной близости от него,
светодиод "Контроль" начинает "моргать".
Частотная "зона" этого "моргания" достаточно узкая.
Это объясняется тем, что, из-за наличия несинхронности между внешним и внутренним
тактами, первое "плывет" относительно второго (или наоборот).
Указанное выше "моргание" есть следствие этого "заплыва".
Частотный компаратор это только одна из функций предлагаемого Вашему вниманию
устройства.
С его помощью можно контролировать и количество событий, происходящих по
случайному закону, в течение заданного интервала времени.
Это может быть, например, количество посетителей, количество бутылок пива,
"плывущих" по конвееру, количество оборотов, количество включений/выключений и еще
много кое-чего.
В этих случаях, в качестве внешних устройств, применяются либо датчики, либо
устройства, выполняющие их функции (с учетом согласования по уровням).

Попробуйте реализовать такую же задумку без использования модуля CCP (например,


на PIC16F84A), и после этого Вы зауважаете этот модуль.
А с его помощью, задача решается достаточно просто, качественно и компактно.

Особенности работы модуля CCP в режиме сравнения, с задействованием вывода RB3

Эти подрежимы не удобны тем, что TMR1H/TMR1L не сбрасывается (аппаратно) по


факту совпадения, и поэтому этот сброс (если он необходим) нужно организовывать
программно.
Кроме того, если речь идет не о банальном обнаружении факта одного совпадения, а
об обнаружении фактов нескольких совпадений, нужно позаботиться об устранении
триггерного эффекта (см. RS триггер на рис. 1).
В большинстве случаев, он (эффект) "убивается" перестройками из одного подрежима
в другой.
Таким способом можно последовательно сформировать, на выводе RB3, некое
двоичное слово (например, старт – стопный кадр) с заданным (калиброванным)
временем "прохождения" его битов.
И уровни битов тоже можно сформировать.
Пока что я не вижу каких-то веских, практических причин "копания" в этом
направлении, но если они, по ходу работы, появятся, то я вернусь к этой теме.

"Практикум по конструированию устройств на PIC контроллерах"      http://ikarab.narod.ru       E-mail: karabea@lipetsk.ru

11