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

6/6/8.

Использование модуля CCP, работающего в режиме ШИМ, в "связке" с


модулями TMR0 или TMR1. Примеры практической реализации устройств,
осуществляющих преобразование типа "частота - длительность импульса".

В предыдущем подразделе, речь шла о задании длительности импульсов


программными средствами.
В этом случае, устройство самодостаточно в том смысле, что им, кроме программы,
ничто не управляет, и оно выдает четко "оговоренный" сигнал, на параметры которого
внешние сигналы не влияют.
Если зафиксировать период и поставить длительность импульса (скважность) в
зависимость от параметра внешнего сигнала, то можно сформировать сигнал
управления, воздействующий на источник внешнего сигнала (обратная связь) таким
образом, что это приводит контролируемый параметр внешнего сигнала к заданному
значению.
В простейшем случае, при помощи внешней RC цепочки, импульсная
последовательность с изменяющейся скважностью "превращается" в управляющий,
аналоговый сигнал, уровень которого зависит от скважности.
Итак, нужно поставить скважность в зависимость от какого-либо параметра внешнего
сигнала.
Какого?
Первое что приходит на ум - частота.
"Ваяю" преобразователь типа "частота - длительность импульса".
Что в PIC16F628A может посчитать частоту?
Таймеры TMR0 или TMR1.
Таймер TMR2 не подходит, так как он задействуется при работе модуля CCP в
режиме ШИМ.
По принципу "от простого к сложному", начну с TMR0 (один байт).

Принципиальная схема учебного устройства такая же, как и в подразделе 6/6/5, только
добавлен конденсатор C4 (15 н), и изменилась "дислокация" контрольного светодиода
(второй светодиод не нужен).
Возможно, для того чтобы выйти в наиболее удобный для Вас "сектор частотного
обстрела", нужно будет подобрать емкость частотозадающего конденсатора.
Программа под это устройство:

;********************************************************************************
; Schim_3.asm Устройство преобразования частоты в длительность импульса.
; Вариант №1.
;--------------------------------------------------------------------------------

1
; Задействуется модуль CCP, работающий в режиме ШИМ, и TMR0.
;********************************************************************************
; "Практикум по конструированию устройств на PIC контроллерах"
(http://ikarab.narod.ru)
; Корабельников Евгений Александрович karabea@Lipetsk.ru
;********************************************************************************
; Функции выводов порта А:
; RA4 - счетный вход TMR0,
; остальные выводы порта А не задействованы.
; Функции выводов порта В:
; к RB3 подключен контрольный светодиод,
; остальные выводы порта В не задействованы.
; Кварц 4000 Кгц (1 м.ц.= 1 мкс.).
; Используется PIC16F628A.
;----------------------------------------------
; Объем программы: 44 слова в памяти программ.
;********************************************************************************
LIST p=16F628A ; "Привязка" MPLAB к микроконтроллеру
; PIC16F628A.
__CONFIG 03F21H ; Определение значений битов конфигурации: бит
; защиты выключен, WDT выключен, стандартный
; генератор XT.
;================================================================================
; "Прописка" регистров специального назначения.
;================================================================================
Tmr0 equ 01h ; Регистр Tmr0.
OptionR equ 01h ; Регистр OptionR-банк1.
Status equ 03h ; Регистр Status.
TrisB equ 06h ; Регистр Tris B-банк1.
PIR1 equ 0Ch ; Регистр флагов прерываний
; от периферийных модулей.
T2CON equ 12h ; Регистр управления модулем таймера TMR2.
CCP1CON equ 17h ; Регистр управления модулем CCP.
CCPR1L equ 15h ; Регистр младшего разряда CCP.
PR2 equ 12h ; Регистр периода-банк1.
;================================================================================
; "Прописка" регистров общего назначения.
;================================================================================
Temp equ 70h ; Регистр временного хранения.
Reg_L equ 71h ; Регистр младшего байта счетчика.
Reg_H equ 72h ; Регистр старшего байта счетчика.
;================================================================================
; Присвоение названий местам размещения результатов операций.
;================================================================================
F equ 1 ; Результат направить в регистр.
W equ 0 ; Результат направить в аккумулятор.
;================================================================================
; Присвоение названий битам регистров специального назначения.
;================================================================================
RP0 equ 5 ; Бит переключения банков.
TMR2IF equ 1 ; Флаг прерывания по переполнению TMR2.
C equ 0
;================================================================================
; Подготовка к началу исполнения программы.
;================================================================================
org 0 ; Начальная точка отсчета в PC – нулевой
; адрес.
;********************************************************************************

;================================================================================
; Начало программы.
;================================================================================
; Подготовительные операции.
;--------------------------------------------------------------------------------

2
; Задание длительности периода, длительности импульса,
; подготовка TMR2 и настройка RB3 на работу "на выход".
;------------------------------------------------------
bsf Status,RP0 ; Переход в 1-й банк.
movlw b'00100000' ; TMR0 работает с предделителем (К=2),
movwf OptionR ; считает внешний такт.
movlw .249 ; Задание длительности
movwf PR2 ; периода (.249).
bcf TrisB,3 ; RB3 работает на выход.
bcf Status,RP0 ; Переход в 0-й банк.
;------------------------------------------
; Настройка модуля CCP.
;------------------------------------------
movlw b'00011111' ; Включение режима ШИМ и задание начальной
movwf CCP1CON ; длительности импульса в части касающейся
; CCP1CON,5,4 (.1).
; Примечание: работа устройства начинается с CCPR1L/CCP1CON,5,4 = .1
;------------------------------------------
; Настройка модуля TMR2.
;------------------------------------------
movlw b'00000101' ; TMR2 включен, Кдел.предделителя = 4,
movwf T2CON ; Кдел.выходного делителя = 1.
;--------------------------------------------------------------------------------
; Счет импульсов за время 0,1 сек.
;--------------------------------------------------------------------------------
SNOVA clrf Tmr0 ; Сброс TMR0 (начало счета).
;------------------------------------------
; Задержка 0,1 сек. (счет TMR0 от нуля).
;------------------------------------------
movlw .221 ;
movwf Reg_L ; Загрузка калибровочных
movlw .130 ; констант.
movwf Reg_H ;

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


goto WR ; 2-байтный,
decfsz Reg_H,F ; вычитающий
goto WR ; счетчик.
nop ;

movf Tmr0,W ; Копирование результата счета в W


; (конец счета).
movwf Temp ; Копирование содержимого W в регистр Temp.
;--------------------------------------------------------------------------------
; "Загрузка" результата подсчета количества импульсов из Temp
; в CCPR1L/CCP1CON,5,4.
;--------------------------------------------------------------------------------
; Определение момента начала "загрузки" в CCPR1L/CCP1CON,5,4.
;------------------------------------------------------------
bcf PIR1,TMR2IF ; Сброс флага прерывания по переполнению TMR2.

btfss PIR1,TMR2IF ; Проверка состояния флага


goto $-1 ; прерывания по переполнению TMR2.
;------------------------------------------------------------
; "Загрузка" Temp,1,0 в CCP1CON,5,4 (1-->5, 0-->4).
;------------------------------------------------------------
btfsc Temp,1 ;
goto $+3 ; Бит №1 регистра Temp
bcf CCP1CON,5 ; копируется в бит №5
goto $+2 ; регистра CCP1CON.
bsf CCP1CON,5 ;

btfsc Temp,0 ;
goto $+3 ; Бит №0 регистра Temp
bcf CCP1CON,4 ; копируется в бит №4
goto $+2 ; регистра CCP1CON.
3
bsf CCP1CON,4 ;
;------------------------------------------------------------
; "Загрузка" Temp,7...2 в CCPR1L,5...0.
;------------------------------------------------------------
bcf Status,C ; Содержимое Temp сдвигается вправо на 2 бита.
rrf Temp,F ; В результате этого, младшие 2 бита
bcf Status,C ; "погибают", а в старшие 2 бита записываются
rrf Temp,F ; (подтверждаются) нули.

movf Temp,W ; Содержимое Temp


movwf CCPR1L ; "загружается" в CCPR1L.

bcf PIR1,TMR2IF ; Сброс флага прерывания по переполнению TMR2.


goto SNOVA ; Переход на новый цикл преобразования.
;********************************************************************************
end ; Конец программы.

Темно-синим цветом выделено то, что относится к TMR0.


Синим цветом выделена группа команд "загрузки" содержимого регистра временного
хранения (Temp) в CCPR1L/CCP1CON,5,4.

Общая стратегия программы состоит в следующем.


TMR0 считает, от нуля, количество импульсов, поступающих от внешнего источника, за
время 100000 мкс. (0,1 c.).
После этого, результат подсчета копируется в регистр временного хранения.
Далее, "выжидается подходящий момент", и, после его наступления, организуется
"перегрузка" битов из 8-битного регистра временного хранения в 10-битный регистр
CCPR1L/CCP1CON,5,4.
Это есть не что иное, как "привязка" частоты к скважности.
Исходные данные для настройки модуля CCP, работающего в режиме ШИМ, те же,
что и были ранее (см. предыдущий подраздел), за исключением смены Кдел.
выходного делителя модуля TMR2 с 4 на 1.
Что касается времени цикла преобразования, то оно достаточно большое - 0,1 c. c
маленьким "хвостиком" (примерно 10 преобразований в секунду).
Если требуется существенно сократить время этого цикла, то нужно перейти на замер
периода (а он "привязан" к частоте), с использованием модуля CCP, работающего в
режиме захвата.
Но это уже более сложный случай, и он связан с перестройками модуля CCP из
режима захвата в режим ШИМ (и наоборот).
Если в этом возникнет практическая необходимость, то я "распишу" этот вариант, а
пока давайте займемся тем, что попроще.

Работа программы.
В "подготовительные операции" добавлена настройка модуля TMR0.
Он считает импульсы внешнего такта, и к нему подключен предделитель с
минимальным Кдел. = 2.
С учетом того, что интервал времени подсчета импульсов составляет 0,1 c., TMR0
первый раз переполнится при подсчете количества импульсов импульсной
последовательности с частотой 256 х 2 х 10 = 5120 Гц. ("граница").
На частоте 5120 Гц. х 2 = 10240 Гц., TMR0 переполнится 2-й раз и т.д., через каждые
5120 Гц.
В пределах любого из этих поддиапазонов, будет происходить одно и то же: по мере
удаления от "пограничной" частоты (в сторону увеличения частоты), скважность
импульсной последовательности, присутствующей на выводе RB3, будет уменьшаться.
Затем (на "границе") - переход от минимальной скважности к максимальной (или от
максимального коэффициента заполнения к минимальному) и т.д. (работа по кольцу).
Для определенности, "привяжусь" к самому низкочастотному из этих поддиапазонов.
Верхняя его "граница" составляет 255 х 2 х 10 = 5100 Гц.
Примечание: если предделитель подключить к WDT (TMR0 работает без
предделителя), то значение "граничной" частоты (частот) уменьшится вдвое.

4
Вернусь к "подготовительным операциям".
С целью акцентирования Вашего внимания на начальной установке TMR2 и CCPR1L, в
программах Schim_1 и _2.asm, имели место быть команды clrf TMR2 и clrf CCPR1L.
В программе Schim_3.asm, я их убрал по причине того, что они подтверждают
соответствующие настройки по умолчанию.
Cоответственно, "прописка" регистра TMR2 из "шапки" программы удалена (обращений
к TMR2 нет).
При настройке модуля CCP, в CCP1CON,5,4 выставлена .1, но можно выставить и .0,
и .2, и .3.
Это кому как нравится, ведь все равно, хочешь – не хочешь, а что-то выставить нужно.
В настройке модуля TMR2, выставлен Кдел. выходного делителя = 1 (в Schim_1 и
_2.asm было 4).
Остальные настройки - по умолчанию.
После окончания "подготовительных операций", начинается исполнение циклической ПП
SNOVA.
ПП SNOVA начинается с процедуры подсчета количества импульсов, "проскакивающих"
за время 0,1 c.
Для того чтобы обеспечить счет от нуля, TMR0 и предделитель сбрасываются в ноль
(clrf Tmr0).
Далее начинается счет, который производится в интервале времени отработки
фиксированной задержки величиной 0,1 с.
По истечении этого времени, содержимое TMR0 быстренько копируется в регистр W.
После этого, TMR0 продолжит счет, но это уже не важно, так как результат подсчета
"осел" в аккумуляторе.
Из него он копируется в регистр временного хранения Temp.
Теперь нужно подумать о "привязке" момента начала копирования байта регистра
Temp, в регистр CCPR1L/CCP1CON,5,4, к поднятию флага TMR2IF.
Это делается точно так же, как и в программах Schim_1 и _2.asm - используется
"плавающая" задержка.
Чтобы она "штатно сработала", перед входом в нее, флаг TMR2IF сбрасывается.
Теперь нужно, в соответствии с порядком старшинства (или "младшинства" - кому как
нравится), "переправить" содержимое 2-х младших битов регистра Temp в 2 младшие
бита регистра CCPR1L/CCP1CON,5,4.
Я это сделал так:

;------------------------------------------------------------
; "Загрузка" Temp,1,0 в CCP1CON,5,4 (1-->5, 0-->4).
;------------------------------------------------------------
btfsc Temp,1 ;
goto $+3 ; Бит №1 регистра Temp
bcf CCP1CON,5 ; копируется в бит №5
goto $+2 ; регистра CCP1CON.
bsf CCP1CON,5 ;

btfsc Temp,0 ;
goto $+3 ; Бит №0 регистра Temp
bcf CCP1CON,4 ; копируется в бит №4
goto $+2 ; регистра CCP1CON.
bsf CCP1CON,4 ;

Эта процедура достаточно простая (2 раза делается одно и то же, только на разные
лады) и комментировать в ней особо нечего.
Теперь нужно то, что осталось не скопированным (содержимое битов №№7…2
регистра Temp), скопировать в регистр CCPR1L.
Если это сделать стандартно (копирование байта из одного регистра в другой, через
W), то, во-первых, скопируется то, что уже было скопировано, а во-вторых,
копирование произойдет "не по адресу" (не в те биты, в какие нужно).
Значит, 2 младших бита регистра Temp нужно "убить" двумя сдвигами вправо, в
комплексе со сбросами бита С, так как в 2 старших бита регистра Temp нужно
записать нули.

5
Я об этом уже говорил ранее, но повтор не помешает.

;------------------------------------------------------------
; "Загрузка" Temp,7...2 в CCPR1L,5...0.
;------------------------------------------------------------
bcf Status,C ; Содержимое Temp сдвигается вправо на 2 бита.
rrf Temp,F ; В результате этого, младшие 2 бита
bcf Status,C ; "погибают", а в старшие 2 бита записываются
rrf Temp,F ; (подтверждаются) нули.

movf Temp,W ; Содержимое Temp


movwf CCPR1L ; "загружается" в CCPR1L.

bcf PIR1,TMR2IF ; Сброс флага прерывания по переполнению TMR2.


goto SNOVA ; Переход на новый цикл преобразования.
;********************************************************************************

После всей этой "свистопляски", флаг TMR2IF подготавливается к следующему циклу


преобразования (сбрасывается), текущий цикл преобразования заканчивается, и
осуществляется переход на следующий цикл.
Что получилось (нужен осциллограф)?
При постепенном увеличении частоты импульсной последовательности, формируемой
внешним источником импульсов, от 0 Гц. до 5100 Гц., в импульсной
последовательности, присутствующей на выводе RB3 (F = 1 Кгц.), происходит
постепенное увеличение длительности импульсов.
При дальнейшем увеличении частоты, происходит переход с минимальной на
максимальную скважность, после чего она опять начинает уменьшаться.
Это подтверждает то, о чем говорилось выше.
Есть один недостаток - импульс максимальной длительности занимает только четверть
периода.
И это вполне объяснимо, так как, в этом случае, CCPR1L/CCP1CON,5,4 заполнен (в
числовом "эквиваленте") не полностью, а на одну четверть (в двух старших битах
CCPR1L всегда нули).
И ничего с этим не поделаешь.
Как сделать так, чтобы было полное заполнение?
Нужно "вводить в эксплуатацию" еще 2 бита.
Значит нужно "вводить в эксплуатацию" один байт (ПИКам байты подавай).
Если использовать TMR0, значит нужно организовывать процедуру досчета, что, как
сами понимаете, и хлопотно, и дополнительный вывод порта задействуется.
Вопрос: "Как быть"?
Ответ: нужно отказаться от "услуг" модуля TMR0 и воспользоваться "услугами" модуля
TMR1.
В нем 2 байта и досчет организовывать не нужно.
В связи с этим, в принципиальную схему устройства (см. рис. 1) нужно внести
изменения:
- конденсатор С4 (15 н) нужно убрать (почему? Поймете позднее).
- сигнальный провод нужно "перебросить" с вывода RA4 на вывод RB6.
После такой "модернизации", нужно "зашить" в PIC16F628A HEX файл программы
Schim_4.asm.

;********************************************************************************
; Schim_4.asm Устройство преобразования частоты в длительность импульса.
; Вариант №2.
;--------------------------------------------------------------------------------
; Задействуется модуль CCP, работающий в режиме ШИМ, и TMR1.
;********************************************************************************
; "Практикум по конструированию устройств на PIC контроллерах"
; (http://ikarab.narod.ru)
; Корабельников Евгений Александрович karabea@Lipetsk.ru
;********************************************************************************
; Функции выводов порта А:

6
; выводы порта А не задействованы.
; Функции выводов порта В:
; к RB3 подключен контрольный светодиод,
; RB6 - счетный вход TMR1,
; остальные выводы порта В не задействованы.
; Кварц 4000 Кгц (1 м.ц.= 1 мкс.).
; Используется PIC16F628A.
;----------------------------------------------
; Объем программы: 58 слов в памяти программ.
;********************************************************************************
LIST p=16F628A ; "Привязка" MPLAB к микроконтроллеру
; PIC16F628A.
__CONFIG 03F21H ; Определение значений битов конфигурации: бит
; защиты выключен, WDT выключен, стандартный
; генератор XT.
;================================================================================
; "Прописка" регистров специального назначения.
;================================================================================
OptionR equ 01h ; Регистр OptionR-банк1.
Status equ 03h ; Регистр Status.
TrisB equ 06h ; Регистр Tris B-банк1.
PIR1 equ 0Ch ; Регистр флагов прерываний
; от периферийных модулей.
T1CON equ 10h ; Регистр управления модулем таймера TMR1.
T2CON equ 12h ; Регистр управления модулем таймера TMR2.
CCP1CON equ 17h ; Регистр управления модулем CCP.
CCPR1L equ 15h ; Регистр младшего байта CCP.
PR2 equ 12h ; Регистр периода-банк1.
TMR1L equ 0Eh ; Регистр младшего байта TMR1.
TMR1H equ 0Fh ; Регистр старшего байта TMR1.
;================================================================================
; "Прописка" регистров общего назначения.
;================================================================================
Temp_L equ 70h ; Регистр временного хранения младшего разряда
Temp_H equ 71h ; Регистр временного хранения старшего разряда
Reg_L equ 72h ; Регистр младшего байта счетчика.
Reg_H equ 73h ; Регистр старшего байта счетчика.
;================================================================================
; Присвоение названий местам размещения результатов операций.
;================================================================================
F equ 1 ; Результат направить в регистр.
W equ 0 ; Результат направить в аккумулятор.
;================================================================================
; Присвоение названий битам регистров специального назначения.
;================================================================================
RP0 equ 5 ; Бит переключения банков.
TMR2IF equ 1 ; Флаг прерывания по переполнению TMR2.
;================================================================================
; Подготовка к началу исполнения программы.
;================================================================================
org 0 ; Начальная точка отсчета в PC – нулевой
; адрес.
;********************************************************************************

;================================================================================
; Начало программы.
;================================================================================
; Подготовительные операции.
;--------------------------------------------------------------------------------
; Задание длительности периода, длительности импульса,
; подготовка TMR2 и настройка RB3 на работу "на выход".
;------------------------------------------------------
bsf Status,RP0 ; Переход в 1-й банк.
bsf OptionR,7 ; Подтягивающие резисторы порта В отключены.

7
movlw .249 ; Задание длительности
movwf PR2 ; периода (.249).
bcf TrisB,3 ; RB3 работает на выход.
bcf Status,RP0 ; Переход в 0-й банк.
;------------------------------------------
; Настройка модуля CCP.
;------------------------------------------
movlw b'00011111' ; Включение режима ШИМ и задание начальной
movwf CCP1CON ; длительности импульса в части касающейся
; CCP1CON,5,4 (.1).
; Примечание: работа устройства начинается с CCPR1L/CCP1CON,5,4 = .1
;------------------------------------------
; Настройка модуля TMR2.
;------------------------------------------
movlw b'00000101' ; TMR2 включен, Кдел.предделителя = 4,
movwf T2CON ; Кдел.выходного делителя = 1.
;------------------------------------------
; Настройка модуля TMR1.
;------------------------------------------
movlw b'00000010' ; TMR1 выключен, считает внешний такт с вывода
movwf T1CON ; RB6, внешний такт синхронизируется,
; Кдел. предделителя = 1.
;================================================================================
; Подпрограмма преобразования частоты в длительность импульса.
;================================================================================
; Счет TMR1 количества импульсов за время 0,1 сек.
;--------------------------------------------------------------------------------
SNOVA clrf TMR1L ; Подготовка к началу
clrf TMR1H ; счета от нуля.

bsf T1CON,0 ; Включение модуля TMR1 (начало счета).


;------------------------------------------
; Задержка 0,1 сек. (счет TMR1 от нуля).
;------------------------------------------
movlw .221 ;
movwf Reg_L ; Загрузка калибровочных
movlw .130 ; констант.
movwf Reg_H ;

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


goto WR ; 2-байтный,
decfsz Reg_H,F ; вычитающий
goto WR ; счетчик.
nop ;

bcf T1CON,0 ; Выключение модуля TMR1 (конец счета).


movf TMR1L,W ; Теперь можно, не опасаясь продолжения счета,
movwf Temp_L ; скопировать результат подсчета
movf TMR1H,W ; из TMR1H/TMR1L в Temp_H/Temp_L,
movwf Temp_H ; что и сделано.
;--------------------------------------------------------------------------------
; "Загрузка" результата подсчета количества импульсов из Temp_H/Temp_L
; в CCPR1L/CCP1CON,5,4.
;--------------------------------------------------------------------------------
; Определение момента начала "загрузки" в CCPR1L/CCP1CON,5,4.
;------------------------------------------------------------
bcf PIR1,TMR2IF ; Сброс флага прерывания по переполнению TMR2.

btfss PIR1,TMR2IF ; Проверка состояния флага


goto $-1 ; прерывания по переполнению TMR2.
;------------------------------------------------------------
; "Загрузка" Temp_L,1,0 в CCP1CON,5,4 (1-->5, 0-->4).
;------------------------------------------------------------
btfsc Temp_L,1 ;
goto $+3 ; Бит №1 регистра Temp_L
bcf CCP1CON,5 ; копируется в бит №5
8
goto $+2 ; регистра CCP1CON.
bsf CCP1CON,5 ;

btfsc Temp_L,0 ;
goto $+3 ; Бит №0 регистра Temp_L
bcf CCP1CON,4 ; копируется в бит №4
goto $+2 ; регистра CCP1CON.
bsf CCP1CON,4 ;
;------------------------------------------------------------
; "Загрузка" Temp_L,7...2 в CCPR1L,5...0.
;------------------------------------------------------------
rrf Temp_L,F ; Содержимое Temp_L сдвигается
rrf Temp_L,F ; вправо на 2 бита.

movf Temp_L,W ; Содержимое Temp_L


movwf CCPR1L ; "загружается" в CCPR1L.
;------------------------------------------------------------
; "Загрузка" Temp_H,1,0 в CCPR1L,7,6.
;------------------------------------------------------------
btfsc Temp_H,1 ;
goto $+3 ; Бит №1 регистра Temp
bcf CCPR1L,7 ; копируется в бит №7
goto $+2 ; регистра CCP1CON.
bsf CCPR1L,7 ;

btfsc Temp_H,0 ;
goto $+3 ; Бит №0 регистра Temp
bcf CCPR1L,6 ; копируется в бит №6
goto $+2 ; регистра CCP1CON.
bsf CCPR1L,6 ;

bcf PIR1,TMR2IF ; Сброс флага прерывания по переполнению TMR2.


goto SNOVA ; Переход на новый цикл преобразования.
;********************************************************************************
end ; Конец программы.

Работа программы.
То, о чем рассказано, повторять не буду.
Остановлюсь на различиях.
В "подготовительных операциях", используется все тот же регистр OptionR, но на этот
раз, он нужен только для отключения подтягивающих резисторов порта В (в случае,
если оконечный каскад внешнего источника сигнала не имеет открытого коллектора или
открытого стока).
Собственно говоря, "подтяжку" нужно отключить только от вывода RB6.
Остальные - "за компанию".
Напоминаю, что по умолчанию, выводы портов А и В настроены на работу "на вход".
Настройка модуля TMR1: TMR1 выключен, считает внешний такт с вывода RB6,
внешний такт синхронизируется, Кдел. предделителя = 1.
В начале ПП SNOVA, с целью обеспечения начала счета от нуля, содержимое
регистра TMR1H/TMR1L сбрасывается в ноль.
Затем, включением модуля TMR1, обеспечивается начало счета.
По истечении 0,1 секунды, выключением модуля TMR1, счет запрещается
(останавливается).
Примечание: выключение модуля TMR1 не приводит к сбросу содержимого
регистра TMR1H/TMR1L. Оно фиксируется. Этот способ остановки счета очень хорош
и симпатичен. Советую "положить на него глаз".
Далее, стандартное копирование содержимого TMR1H/TMR1L в регистр временного
хранения Temp_H/Temp_L.
Далее, подготовка флага TMR2IF (сброс) и "плавающая" задержка.
"Загрузка" битов в CCP1CON,5,4 и в CCPR1L,5...0 происходит по принципу, описанному
выше.

9
Разница только в том, что вместо регистра Temp, используется регистр Temp_L, и в
том, что отпадает практическая необходимость в работе с флагом С.
Пусть, в результате двух сдвигов содержимого Temp_L, в биты №№7,6 регистра
CCPR1L записывается все что угодно.
Все равно этому будет "Гитлер капут".
И в самом деле, зачем "пихать", в биты №№7,6 регистра CCPR1L, нули, если далее,
в эти биты скопируются биты №№1 и 0 регистра Temp_H ?
"Загрузка" Temp_H,1,0 в CCPR1L,7,6 происходит точно по такому же принципу, как и
"загрузка" Temp_L,1,0 в CCP1CON,5,4.
Разница только в деталях.
Далее, сброс флага TMR2IF и переход на новый "виток" полного цикла программы.
Что получилось?
Теперь коэффициент заполнения регулируется от 0% (импульсов нет, низкий уровень
логического нуля) до 100% (импульсов нет, высокий уровень логической единицы).
В "промежутке" между этим, на экране осциллографа, наблюдаются очень симпатичные
(когда желаемое достигается, то это всегда симпатично) эпюры различных
"конструкций", что и требуется (светодиод изменяет яркость свечения).
При увеличении частоты от 0 Гц., частота внешнего сигнала, при которой имеет место
быть коэффициент заполнения 100%, находится где-то в районе 10 Кгц.
Считаем: 1023 х 1 (Кдел. предделителя TMR1) х 10 (т.к. время измерения= 0,1c.) = 10230 Гц.
Все сходится.
Изменяя Кдел. предделителя модуля TMR1 и время счета, можно "двигать" эту
"границу" в достаточно широком диапазоне частот.
Можно также произвести предустановку не нуля, а какого-то другого числа, и считать
от этого числа.
Если к выводу RB3 "подцепить" фильтр нижних частот, то уровень напряжения на его
выходе будет зависить от значения частоты внешнего источника сигнала.

К вопросу о многоразрядной "оцифровке" аналогового сигнала (параметра), с целью


осуществления широтно – импульсной модуляции (применительно к PIC16F628A).
Выше показан один из способов (косвенный) такой "оцифровки", который может быть
использован для осуществления широтно – импульсной модуляции, при условии
применения внешнего, частотного модулятора.
Но этот способ, в части касающейся инерционности преобразования, оставляет желать
лучшего даже тогда, когда подсчитывается не количество импульсов за время
калиброванного интервала времени измерения (то, о чем шла речь выше - большая
инерционность преобразования), а длительность периода (меньшая инерционность
преобразования).
Это "режет потолок" диапазона возможных частот дискретизации (частот выборок), и во
многих случаях, "губит дело на корню", хотя, есть случаи, когда такой способ ШИМ-
модуляции может оказаться приемлемым (невысокие требования к качеству ШИМ-
сигнала, нежелательность перехода на другой тип ПИКа т.п.).
Кроме того, и это немаловажно, усложняется принципиальная схема устройства.
Гораздо выгоднее и эффективнее "протащить" ("оцифровать") аналоговый сигнал (или
аналоговый параметр) через "шустрый" модуль АЦП, работающий непосредственно с
аналоговым сигналом, а после этого "грузить цифирь" в CCPR1L/CCP1CON,5,4.
Модуль АЦП обеспечивает быстрое, линейное преобразование уровней аналогового
сигнала, имеющих место быть в моменты выборок, в N-разрядную "цифирь", с которой,
в дальнейшем, можно "вытворять все что угодно" (в пределах дозволенного).
PIC16F628A модуля АЦП не имеет, что является его недостатком, и сужает диапазон
его возможностей.

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

11

Оценить