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

7/9. "Быстрый" ШИМ-модулятор на основе программы Schim_6.asm.

или что
нужно сделать для того чтобы "заставить тунеядца работать". Две стратегии
построения программ, в которых осуществляется преобразование "напряжение -
скважность".

Пояснение: слово "быстрый" "закавычено" потому, что "все в этом мире относительно".
Формально, ШИМ-модуляторами можно назвать все устройства, в которых
осуществляется преобразование уровней внешнего, аналогового сигнала в длительность
импульсов. Разница только в скорости.
Скорость преобразования определяется значением частоты дискретизации (Fд).
Чем она выше, тем более высокочастотный (более "быстрый"), аналоговый сигнал
можно обработать.
Во многих случаях, это очень актуально и "геморройно".
Человеку, который как следует "присосался" к АЦП, обязательно нужно сформировать
четкое представление о частоте дискретизации, в контексте встроенности, связанной с
ней "геморройности", в полный цикл программы, а то ведь может быть так, что один цикл
АЦП "пролетает с реактивным свистом", а потом "состаришься", дожидаясь следующего.
Какая уж тут высокая частота дискретизации?
В тех случаях, когда она позарез нужна, получается недоразумение и конфуз
(потенциальный источник ненормативной лексики).
Поэтому нужно как следует научиться "насаживать червяка на крючок", иначе "не одна
уважающая себя рыба на него не клюнет".
В качестве "червяка" используется "левовыровненная" программа Schim_6.asm.

1
Выше Вы видите блок-схему этой программы.
Я ее, специально, составил таким образом, чтобы сверху оказалась "граница",
разделяющая периоды.
Справа, в зеленых рамках, Вы видите числовые значения интервалов времени, в
течение которых выполняются соответствующие действия.
Пояснения:
- 12 мкс. это максимальное время отработки процедуры "загрузки" результата
преобразования, из Temp_H/Temp_L, в CCPR1L/CCP1CON,5,4 (ориентируюсь на
худшее),
- 26 мкс. это суммарное время отработки 13-ти интервалов времени Tad (12 + 1).
Один из этих интервалов - "ефрейторский зазор" под "разброд и шатания"
(в подобных случаях, лучше "перебор", чем "недобор").
После суммирования значений интервалов времени всех строк, за исключением самой
нижней строки (ожидание момента начала "загрузки"), получилось:
12 + 1 + 2 + 2 + 19 + 1 + 26 + 6 + 1 + 1 = 71 мкс.
Плюс, еще 3 мкс. на "шаляй – валяй" "плавающей" задержки (пусть хоть немного
поработает, прежде чем рабочая точка программы ее покинет. Это намек на
замышляемое, в дальнейшем, "убийство" того, что пока "туманно" ).
Получилось 71 +3 = 74 мкс.
В данном случае, частота дискретизации равна частоте ШИМ-сигнала (разъяснения -
ниже), то есть, 1000 Гц, что соответствует периоду 1000 мкс.
1000 – 74 = 926 мкс.
Что это за "чудо – юдо"?
Это значение того интервала времени, в течение которого рабочая точка программы
бесполезно "мотает витки" в "плавающей" задержке (в той, которая работает с флагом
TMR2IF).
"Расшифровка" слова "бесполезно: даже в худшем случае, за 74 мкс., гарантированно
будет отработано "все то, что шевелится", а в течение остальных 926 мкс., по причине
полного отсутствия и стыда, и совести, "железяка нагло и ехидно устроила перекур"!!!
И это в то время, когда "пятилетку нужно сделать за один год"!!!
Короче, "форменное безобразие с признаками тунеядства".
А ведь "ей, за это безобразие, платится аж 1000 казенных рубликов" (в смысле,
микросекунд).
"Управа на этого тунеядца" такая:
1. Нужно "нагрузить его работой на 926 рубликов".
Можно чуть поменьше, чтобы "палку не перегнуть", а то ведь может и надорваться,
бедолага (меру нужно знать).
Пусть "вагоны разгружает, заборы красит, двор метет" или еще что-нибудь делает.
Трудотерапия пойдет ему (и всем остальным) только на пользу.
2. Нужно "не платить ему 926 рубликов, а платить 74 рублика".
Вот пускай и поработает в поте лица, ведь в этом случае, для того чтобы "заработать
те же 1000 рубликов (прокормить семью)", ему нужно будет сделать ту же самую
работу, но только не один, а 1000/75 (чтобы "пупок не надорвался" от такой скорости
работы) = примерно 13,333… раза.
3. Нужно сделать и то, и другое, в той или иной пропорции (зависит от решения
"работодателя").
- В случае реализации пункта 1, можно смело "врезать" в программу нечто,
исполняющееся не более чем за 926 мкс.
Это "нечто" может быть "всем, чем угодно" (зависит от конструктора).
- В случае реализации пункта 2, нужно уменьшить время периода ШИМ-сигнала с
1000 мкс. до 75 мкс., что соответствует увеличению частоты дискретизации
(Fд.) с 1 КГц до, примерно, 13,333… КГц.
- В случае реализации пункта 3, решение о конкретной пропорции зависит от
конструктора. "Гибридных" вариантов может быть много.
В данном случае, речь идет о пункте 2, ведь частота дискретизации повысится в
13,333… раза, а это уже кое-что, так как на такой скорости можно преобразовать
аналоговый сигнал с верхней границей частотного диапазона 13,3 Кгц./2 = примерно
6,7 КГц. (например, речевой).
Из этого "проистекают" исходные данные для расчета:
2
- то, что относится к АЦП, не изменилось.
- Fд = Fшим = 13,333… Кгц. (Тд = Тшим = 75 мкс.)
Разъяснения по поводу последнего ( внимание! Далее следуют "глобальные,
стратегические" выводы ):
Стратегия программы, в которой осуществляется преобразование типа "напряжение –
скважность", может быть одной из следующих:
Стратегия №1: "базируется" на условии время исполнения полного цикла
программы (без учета "плавающей" задержки) должно быть меньше интервала
времени одного периода ШИМ-сигнала.
Пример: тот случай, который рассматривается в этом подразделе.
В этом случае, имеет место быть равенство Fд = Fшим (Тд = Тшим), которое
"автоматически" обеспечивается "плавающей" задержкой (той, которая работает с
флагом TMR2IF).
В этом случае, при отсутствии "врезки" (в программе Schim_9.asm, см. ниже, ее нет),
можно обеспечить наивысшее значение частоты дискретизации.
При наличии "врезки", "масса" которой не позволяет выполнить сформулированное
выше условие, нужно оптимально уменьшить значение Fшим (Fд) таким образом,
чтобы это условие было выполнено.
Стратегия №2: время полного цикла программы (без учета "плавающей"
задержки) больше интервала времени одного периода ШИМ-сигнала.
Пример: тот случай, который рассматривался в предыдущем подразделе.
В этом случае, Fд будет меньше Fшим.
Это означает то, что в пределах фиксированного и достаточно продолжительного
интервала времени, количество выборок будет меньше количества периодов
ШИМ-сигнала, и, если Fшим не меняется, то это расхождение будет увеличиваться по
мере увеличения "массивности врезки".
Практический вывод:
- стратегию №1 выгодно применять в тех случаях, когда ("с оглядкой на массу
врезки") нужно обеспечить как можно меньшую инерционность (как можно более
высокую скорость) преобразования,
- если этого не требуется, то можно применить стратегию №2.
Напоминание/уточнение: так как, за один, полный цикл АЦП, происходит одна выборка,
то частота дискретизации и количество выборок за секунду это одно и то же.
Как видите, для того чтобы стать "хозяином" этого достаточно "хитрого и ехидного"
программно – аппаратного
"комплекса", нужно несколько
поднапрячься и как следует
прочувствовать временные
соотношения, в контексте того
полного цикла программы,
который нужно "сваять".
Все "песни и пляски" вокруг
АЦП и всего того, что с ним
связано, должны начинаться
именно от этого, а все
остальное к этому
прилагается.
Можно утешиться тем, что
"на всякого мудреца
довольно простоты", и эта
"железяка" не есть
исключение.
"Претворяю в жизнь нарытое".
Слева Вы видите результат
расчета параметров
настройки модуля CCP,
произведенного с помощью
PIC-калькулятора, для
Fшим = 13,333 Кгц.
3
Наилучший вариант находится в красной рамке.
Если применяется кварц на 4 Мгц., то больше чем на 300 градаций (10-й бит всегда в
нуле) "не тянет". И с этим ничего не поделаешь.
Для того чтобы увеличить количество градаций (и битность), нужно либо увеличить
частоту кварца, либо перейти на меньшее значение Fшим.
Так как оба этих варианта, в данном случае, не подходят, то приходится
довольствоваться тем, что есть.
В принципе, 300 градаций это не так уж и мало.
Например, для "оШИМления" речевого, аналогового сигнала (с вполне приличным
качеством), хватит.
Примечание: то, что не нужно, "залито" серым цветом (можно не обращать внимания).
Итак:
- необходимо выставить Кдел. предделителя TMR2 = 1,
- в регистр PR2 нужно записать число .74.
Вот и все "программные дела".
Не правда ли, как просто? Только сменить две константы.
Но за этим "кульминационным мычанием коровы" (в смысле кажущейся простоты)
"спрятано" много того, чего назвать "мычанием" язык не поворачивается.
Получилась программа Schim_9.asm (прилагается):
;********************************************************************************
; Schim_9.asm "Быстрый" ШИМ-модулятор
; (вариант с левым выравниванием)
;--------------------------------------------------------------------------------
; Задействуется модуль АЦП и модуль ССP, работающий в режиме ШИМ.
; Скважность регулируется внешним, "быстрым" источником аналогового сигнала.
;********************************************************************************
; "Практикум по конструированию устройств на PIC контроллерах"
; (http://ikarab.narod.ru)
; Корабельников Евгений Александрович karabea@Lipetsk.ru
;********************************************************************************
; Функции выводов порта А:
; RA0 - активный входной канал АЦП,
; остальные выводы порта А не задействованы.
; Функции выводов порта В:
; выводы порта В не задействованы.
; Функции выводов порта С:
; RC2 - выход модуля CCP (выход ШИМ),
; остальные выводы порта C не задействованы.
; Кварц 4000 Кгц (1 м.ц.= 1 мкс.).
; Опорное напряжение -> Uпит. ПИКа.
; Частота дискретизации -> 13,333 Кгц.
; Используется PIC16F873A.
;----------------------------------------------
; Объем программы: 44 слова в памяти программ.
;================================================================================
LIST p=16F873A ; "Привязка" к типу микроконтроллера.
__CONFIG 3F31H ; XT-генератор, PWRT вкл., защита выкл., сброс
; BOR запрещен, LVP выкл., DEBUG выкл.
;================================================================================
; Регистры специального назначения.
;================================================================================
Status equ 03h ; Регистр Status.
TrisC equ 07h ; Регистр выбора направлений работы
; выводов порта C (банк 1).
;-------------------------------------
; Регистры, обеспечивающие АЦП.
;-------------------------------------
AdresH equ 1Eh ; Регистр старшего байта результата АЦП.
AdresL equ 1Eh ; Регистр младшего байта результата АЦП
; (банк 1).
Adcon0 equ 1Fh ; Регистр настройки модуля АЦП.
Adcon1 equ 1Fh ; Регистр настройки модуля АЦП (банк 1).
;-------------------------------------

4
; Регистры, обеспечивающие ШИМ.
;-------------------------------------
PIR1 equ 0Ch ; Регистр флагов прерываний
; от периферийных модулей.
T2CON equ 12h ; Регистр управления модулем таймера TMR2.
CCP1CON equ 17h ; Регистр управления модулем CCP.
CCPR1L equ 15h ; Регистр младшего байта CCP.
PR2 equ 12h ; Регистр периода (банк 1).
;================================================================================
; Регистры общего назачения.
;================================================================================
Count equ 20h ; Регистр счетчика.
Temp_L equ 21h ; Регистр младшего разряда 2-байтного
; двоичного числа.
Temp_H equ 22h ; Регистр старшего разряда 2-байтного
; двоичного числа.
;================================================================================
; Определение места размещения результатов операций.
;================================================================================
W equ 0 ; Результат направить в аккумулятор.
F equ 1 ; Результат направить в регистр.
;================================================================================
; Присвоение битам названий.
;================================================================================
RP0 equ 5 ; Бит выбора банка.
GO equ 2 ; Бит статуса модуля АЦП.
TMR2IF equ 1 ; Флаг прерывания по переполнению TMR2.
;================================================================================
org 0 ; Начать выполнение программы с 0-го адреса PC
;********************************************************************************

;********************************************************************************
; НАЧАЛО ПРОГРАММЫ.
;********************************************************************************
; Подготовительные операции.
;================================================================================
; Задание длительности периода сигнала ШИМ
; и подготовка к работе вывода RC2.
;-------------------------------------------
bsf Status,RP0 ; Переход в 1-й банк.
movlw .74 ; Задание длительности
movwf PR2 ; периода (.74).
bcf TrisC,2 ; RC2 работает на выход.
;-------------------------------------------
; Работа с регистром Adcon1.
;-------------------------------------------
movlw b'00001110' ; Диапазон квантования напряжения от -Vss до +
movwf Adcon1 ; Vdd, AN0-аналоговый вход, AN1...AN4-цифровые
; каналы ввода/вывода, левое выравнивание.
bcf Status,RP0 ; Переход в 0-й банк.
;------------------------------------------
; Настройка модуля CCP.
;------------------------------------------
movlw b'00001111' ; Включение
movwf CCP1CON ; режима ШИМ.
;------------------------------------------
; Настройка модуля TMR2.
;------------------------------------------
movlw b'00000100' ; TMR2 включен, Кдел.предделителя = 1,
movwf T2CON ; Кдел.выходного делителя = 1.
;################################################################################
; Циклическая подпрограмма "оцифровки" уровня аналогового сигнала,
; присутствующего на выводе RA0, и перевода результата этой "оцифровки"
; в длительность импульса.
;################################################################################
; Сначала производится "оцифровка" (задействуется модуль АЦП).
5
;********************************************************************************
; Работа с регистром Adcon0.
;-------------------------------------------
SNOVA movlw b'01000001' ; Включение модуля АЦП, выбор канала AN0
movwf Adcon0 ; (RA0), источник тактового сигнала Fosc/8,
; состояние ожидания, конденсатор подключен к
; выбранному аналоговому входу и начал
; перезаряжаться.
;------------------------------------------------
; Задержка для перезаряда конденсатора.
;------------------------------------------------
movlw .6 ; Стандартный,
movwf Count ; вычитающий,
decfsz Count,F ; однобайтный
goto $-1 ; счетчик.
;-------------------------------------------
; Начало аналого-цифрового преобразования.
;-------------------------------------------
bsf Adcon0,GO ; Включение преобразования. Конденсатор
; отключается от аналогового входа на время
; преобразования.
;-------------------------------------------
; Ожидание окончания АЦП ("плавающая" задержка).
;-------------------------------------------
btfsc Adcon0,GO ; Ожидание окончания аналого-цифрового
goto $-1 ; преобразования.
;-------------------------------------------
; АЦП закончено. Результат - в AdresH/AdresL.
; Копирование результата в Temp_H/Temp_L.
;-------------------------------------------
bsf Status,RP0 ; Переход в 1-й банк.
movf AdresL,W ; AdresL --> W.
bcf Status,RP0 ; Переход в 0-й банк.
movwf Temp_L ; W --> Temp_L.

movf AdresH,W ; AdresH --> W.


movwf Temp_H ; W --> Temp_H.
;-------------------------------------------
; В Temp_H/Temp_L "лежит" результат АЦП.
;-------------------------------------------
; Теперь модуль АЦП можно выключить.
;-------------------------------------------
clrf Adcon0 ; Для снижения потребляемого устройством тока,
; модуль АЦП выключается до конца отработки
; текущего полного цикла программы.
;********************************************************************************
; Далее производится перевод результата "оцифровки" в длительность импульса
; (задействуется модуль CCP, работающий в режиме ШИМ).
;********************************************************************************
; "Загрузка" результата АЦП, из Temp_H/Temp_L, в CCPR1L/CCP1CON,5,4.
;================================================================================
; Определение момента начала "загрузки" в CCPR1L/CCP1CON,5,4.
;------------------------------------------------------------
bcf PIR1,TMR2IF ; Сброс флага прерывания по переполнению TMR2.

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


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

6
btfsc Temp_L,6 ;
goto $+3 ; Бит №6 регистра Temp_L
bcf CCP1CON,4 ; копируется в бит №4
goto $+2 ; регистра CCP1CON.
bsf CCP1CON,4 ;
;------------------------------------------------------------
; "Загрузка" Temp_H в CCPR1L.
;------------------------------------------------------------
movf Temp_H,W ; Содержимое Temp_H
movwf CCPR1L ; "загружается" в CCPR1L.

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


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

"Пошевелив своей извилиной", я пришел к выводу, что, с целью обеспечения


универсальности, нужно "укомплектовать" ШИМ-модулятор эмиттерным повторителем.
И в самом деле, источники аналогового сигнала могут быть разными.
А что если имеет место быть разделительный конденсатор?
В этом случае, "можно заказывать панихиду", так как не будут выполнены "штатные"
требования, предъявляемые к цепям заряда/разряда конденсатора Hold.
А что если Rвых. источника аналогового сигнала более 10 Ком?
А что если амплитуда аналогового сигнала превышает Uпит. ПИКа?
Все эти "а что если" "убиваются" введением в принципиальную схему эмиттерного
повторителя, запитанного от источника питания ПИКа.
На рис. 2, Вы видите вариант эмиттерного повторителя, "адаптированного" к уровням
аналогового сигнала, находящимся в положительной области напряжения.
Если же нужно обработать аналоговый сигнал, имеющий положительные и
отрицательные полупериоды (например, после разделительного конденсатора), то, в
простейшем случае, при отсутствии сигнала, нужно выставить, на эмиттере
транзистора, половину напряжения питания ПИКа.
Это делается при помощи резистора, включенного между базой и коллектором.
Его номинал нужно подобрать.
На схеме этот резистор не указан, но имейте это ввиду.
В качестве источника аналогового сигнала, я использовал осциллограф.
7
Дело в том, что он вырабатывает пилообразное напряжение (выводится "наружу"),
которое очень удобно использовать при оценке линейности преобразования.
"Пила" находится в области положительных напряжений (в моем осциллографе) и
поэтому "коллекторно-базовый" резистор не нужен.
Резистором R1 можно подобрать оптимальный вариант диапазона изменения уровней
аналогового сигнала, приведенных к аналоговому входу модуля АЦП.
Примечание: номиналы резисторов R1 и R2 могут быть и другими.
Эмиттерный повторитель не инвертирует входной сигнал и обеспечивает быстрый
заряд/разряд конденсатора Hold, вне зависимости от величины Rвых источника
аналогового сигнала ("развязка").
"Быстрота" объясняется тем, что номинал R3 равен всего 680 Ом. (можно сделать и
меньше), плюс, заряд происходит через транзистор, который открывается тем больше,
чем быстрее нарастает уровень аналогового сигнала.
И уровень напряжения, на выходе эмиттерного повторителя, не превысит величины
Uпит. ПИКа (если сигнал будет слишком "амплитудистый", то он просто будет
ограничен).
С учетом сказанного, по большому счету, можно сократить длительность
фиксированной задержки процедуры АЦП на 9 мкс.
Кто желает, тот может это сделать (нужно заменить константу .6 на константу .3).
По мере нарастания уровня "пилы", происходит постепенное увеличение длительности
импульсов.
Затем - резкий переход от максимальной длительности импульса к минимальной, и все
повторяется снова.
При постепенном увеличении частоты "пилы", количество импульсов, "втискивающихся"
в интервал времени одного периода "пилы", будет уменьшаться, вплоть до 2-х
импульсов на частоте 6,7 Кгц.
Можно использовать сигнал ГСС или "соорудить" простенький микрофонный усилитель,
или еще что-то. На принцип это не влияет.
В части касающейся работы с речевым сигналом от микрофонного усилителя, нужно
отметить следующее.
Так как аналоговая составляющая "заложена" в среднем значении напряжения, то для
его выделения подойдет то, что обладает инерционностью.
Например, в простейшем случае, какой-нибудь высокоомный (чтобы не перегружать
выход модуля CCP) телефонный капсюль.
Но есть одна неприятная особенность - прослушивается сигнал (тон) с частотой
дискретизации.
Отстроиться от него можно двумя способами: либо "задиранием" значения частоты
дискретизации до 20 Кгц и более (человеческое ухо не воспринимает эти частоты),
либо использованием фильтров (в основном, ФНЧ или режекторных), которые, с той
или иной эффективностью, "убивают" эту "бяку".
Первое не всегда получается.
Что касается второго, то, в простейшем случае, применяются RC фильтры, но их
добротность оставляет желать лучшего, да и сигнал они сильно ослабляют.
Лучше всего применить фильтр на операционном усилителе, так как он имеет высокое
входное сопротивление, что позволяет получить высокую добротность (высокую
крутизну склонов АЧХ).
При этом, аналоговый сигнал можно линейно усилить (если в этом есть
необходимость).

Пояснение: в составе PIC – калькулятора имеется утилита, с помощью которой можно


рассчитать настройки модуля АЦП, но она "адаптирована" не под модуль АЦП
PIC16xxx, а под модуль АЦП PIC18xxx (не два бита ADCS, а три).
Во избежание возможной путаницы, я пока "попридержу" эту утилиту "до лучших
времен".
И еще. В тех конструкциях этого раздела, в которых десятичная запятая не
используется, можно освободить вывод RB7.

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

Оценить