Широтно-импульсно модулированный сигнал очень часто применяется в электронике для передачи информации, регулировки мощности или формирования постоянного напряжения произвольного уровня. В этой статье описано устройство на операционном усилителе, размером 20х20мм из 15 элементов, которое генерирует ШИМ-сигнал.
ШИМ-сигнал (PWM) представляет собой последовательность импульсов, частота которых неизменна, а модулируется длительность импульсов. Большинство микроконтроллеров легко справляются с этой задачей, но что делать если нет желания программировать и использовать такое мощное средство для такой простой задачи? В этом случае можно использовать дискретные элементы.
Для начала необходимо сформировать последовательность пилообразных импульсов и подать ее на вход компаратора. На второй вход компаратора подается модулирующий сигнал, например, напряжение с переменного резистора. Если напряжение генератора выше напряжения на втором входе — на выходе напряжение близко к напряжению питания. Если напряжение генератора ниже — на выходе ноль.
Формирование ШИМ-сигнала
На рисунке Uк — напряжение команды (постоянный уровень, заданный переменным резистором), Uген — напряжение генератора, UPWM — ШИМ-сигнал.
Все эти задачи можно легко выполнить при помощи двух операционных усилителей так как показано на схеме.
Схема генератора ШИМ
В схеме применена микросхема LM358N, которая использует однополярное питание и содержит два канала в одном корпусе SO8.
Все элементы, кроме резистора R3, предназначены для поверхностного монтажа и располагаются на плате с минимальным размером. R3 расположен на обратной стороне платы. Генераторные схемы очень капризны с точки зрения трассировки печатных плат. Если изменить топологию платы нельзя гарантировать ее работоспособность. Первая версия платы генерировала пилообразное напряжение с очень низкой амплитудой и ее было невозможно использовать.
Плата генератора ШИМ-сигнала
Сама плата очень маленькая — 20х20 мм и легко изготавливается методом ЛУТ. Она лишь немного больше переменного резистора, изменяющего скважность сигнала.
Плата генератора ШИМ в сборе
Рабочая частота определяется конденсатором C1. Для снижения частоты можно увеличить его емкость и наоборот.
Работает плата достаточно стабильно. На видео видно, как меняется яркость светодиода. Неудобство только в том, что используется лишь половина диапазона резистора R3. То есть в первой и последней четверти положения вала напряжение остается без изменения.
Файл печатной платы в формате Sprint Layout 5.0 можно скачать по ссылке.
Мы будем очень рады, если вы поддержите наш ресурс и посетите магазин наших товаров shop.customelectronics.ru.
www.customelectronics.ru
Итак, данный девайс имеет размеры 79х43х24 (ШхВхГ), установочное отверстие 72х39, плюс выборки по бокам для защелок.
Клеммники не особо высокого качества, что и неудивительно; подписаны. 4 контакта: + и — питания, — и сигнал ШИМ. Минусы объединены. По питанию стоит диод.
Внутренний мир прост и незатейлив:
Тут у нас драйвер дисплея HT1621, микроконтроллер Nuvotek N76E003AT20, стабилизатор напряжения M5333B и выходной транзистор с маркировкой 1АМ — надо полагать это 3904.
На передней панели ЖКИ с на удивление неплохими углами обзора и 4 кнопки: частота+- и коэффициент заполнения +-
Посмотрим как оно работает.
Вот на самой низкой частоте для понимания принципов ШИМ-регулировки, кто не знает:
Индикация частоты следующим образом: герцы — без точки, килогерцы — с точкой, больше сотни килогерц — с двумя точками.Максимальная частота — 150кГц. Инкремент по 1% ШИМ и по единице младшего разряда, то есть 1Гц, либо 0.01кГц, либо 0.1кГц, либо 1кГц, либо 10кГц, в зависимости от частоты.
И сразу осциллки на высоких частотах, 20кГц, 50кГц, 100кГц, 150кГц.
Как видим сигнал не шибко красивый, но тут не может быль ничего другого, ибо выходная цепь — транзистор с парой резисторов.
А теперь осциллки на промежуточных частотах, если кому это интересно:
Ну вот такой, в общем, приборчик. Понравился, если честно. прям вот за 5 баксов, за которые я его взял — очень хорошо.
Ну а теперь — диайвай немножко рукоделия. Я придумал два применения данному генератору: проверка всеразличных соленоидов, например Регуляторов Холостого Хода, и промывка форсунок. При промывке форсунок в ультразвуковой ванне мне нравится загонять их в режим самопрокачки. Но аналоговый генератор не обладает достаточной стабильностью (а может дело и в форсунках — уходят характеристики при прогреве), так что я решил применить данный цифровой, в надежде на более высокую стабильность. Я в любом случае собирался делать еще один генератор, так что решил не заморачиваться и купил этот, сразу как только увидел.
Но у нас тут явно недостаточная мощность для управления форсунками, значит придётся ставить выходные ключи. Типа такого:
Возможно, придётся заменить выходной транзистор в самом устройстве, ну и надо подобрать силовые транзисторы получше, возможно мои любимые IRFZ44 — жаль, закончились. Собственно, на данном этапе устройство собрано на 50% — я впаял два первых попавшихся полевика, кажется IRF630 — ну потому что больше одинаковых нету у меня 🙁 чисто для проверки идеи и картинок/видосиков для обзора.
Далее нам понадобится корпус. Примерно такой:
Ну и 3Д-принтер для его изготовления. Плату делал по фоторезистивной технологии описанной в прошлом обзоре.
Ну и сразу результат.
Внутренности:
И наружа:
В боксе холодно, так что детали к сожалению не сильно хорошо прилипают к столу, так что качество корпуса получилось не ахти. Меня-то устроит, но в целом чувствуется недосказанность какая-то, поэтому файлы моделей не выкладываю, благо рисуется это всё быстро и просто.
Выключатели: верхний подает питание на всю схему, нижний отключает выходной каскад.
А теперь — примеры работы. проверка РХХ
youtu.be/EyyQr8ObVao
И режим самопрокачки форсунки
youtu.be/iExGA3-VhlQ
Подытоживая: отличный генератор. Повторять конструкцию возможно и не стОит в том виде в котором она сейчас показана в обзоре, но в целом что-то подобное — однозначно маст хэв в каждом сервисе. Да и не только в сервисе. Так что берите идею, и ваяйте своё.
mysku.ru
Лабораторный генератор ШИМ с широким диапазоном частот для проектирования высокочастотных импульсных стабилизаторов, преобразователей и испытания различных схем.
В наше время весь мир крутится вокруг широтно-импульсной модуляции (ШИМ), да что и говорить, даже день и ночь – и те подвластны ШИМу (зимой день короче чем ночь и наоборот J ). ШИМ сейчас используется везде, где только можно представить его применение: регуляторы, стабилизаторы, преобразователи, блоки питания и прочие устройства. Учитывая тенденцию увеличения мощности, неуклонного роста используемых частот в силовой и преобразовательной технике, а также уменьшению массо — габаритных показателей, я решил что иметь у каждого в домашней лаборатории широкодиапазонный генератор ШИМ просто обязательно. Но это, конечно же, должен быть не просто генератор. Нужно что бы он имел регулировку частоты в широком диапазоне, регуляторы коэффициента заполнения, регуляторы DEAD TIME, однотактный и двухтактный выходы, а также инверсию выходов для каждого. Инверсия выходов необходима для проверки мостового преобразователя. Да и мало ли чего ещё захочется исследовать. Но в тоже время он должен быть простым для сборки, наладки и повторения. В данном случае будет достаточно перекрыть диапазон частот в однотактном режиме от 60 кГц до 2 МГц, в двухтактном режиме от 30 кГц до 1 МГц. Регулировать коэффициент заполнения в однотактном режиме от 1 % до 99%, а в двухтактном режиме от 2 % до 98%, с возможностью регулирования паузы DEAD TIME («мертвая зона»). Генератор должен иметь минимальное число переключателей по диапазонам. Все должно регулироваться плавно и без скачков. Желательно иметь настройку грубо и точно на каждый параметр регулирования.
С помощью такого генератора можно проверять качество работы драйверов управления полевых транзисторов, скоростные показатели работы различных компонентов и многое–многое другое.
Чтобы не утомлять прочтением всей статьи, сразу покажу, какой сигнал получился на выходах в разных режимах и на разных частотах:
С помощью этого генератора я запускаю любой блок питания, в котором микросхема не дает импульсов на запуск, или уходит в защиту по непонятной причине. Плавно увеличивая коэффициент заполнения, смотрю, что происходит на выходе блока, или токовом шунте ключевого транзистора. Отыскание неисправности в любых импульсных блоках с этим генератором — просто сказка и занимает по времени считанные минуты. Откидываю, например, затвор силового транзистора от родной микросхемы, и цепляю его к своему генератору с драйвером. Для того что бы подключаться например по высокой стороне к двухтактникам, иногда такое надо, необходимо использовать оптодрайвер на 6N137 или любых других быстрых оптопарах.
Ещё можно проверять на что годны операционные и аудио усилители. Поскольку самые низкие искажения имеют только повторители напряжения, проверку буду производить именно в этом режиме. Приведу пример проверки самого распространенного операционного усилителя типа LM358. Тем самым ввергну в шок некоторых аудиофилов. Так вот, использовать LM358 в аудиоусилителях даже низкого класса категорически не рекомендую.
Ради прикола, беру самый первый советский операционник К140УД1Б и загоняю его на испытания. Показатели у него значительно лучше, чем у LM358.
Можно проверять время задержки в логических элементах и минимальную длительность импульса для триггеров.
Даже проверил, как себя поведет стабилитрон TL431 на частоте 1,3 МГц:
Желтым — вход, синим — выход.
А также испытать и проверить многое другое…….
Вот, вкратце, возможности моего генератора.
Когда я поставил перед собой задачу, попробовал погуглить и найти готовое решение. Поиски не увенчались успехом. В итоге было решено самому создать схему отвечающую запросам. Теперь я ознакомлю вас с результатами моих исследований длившихся около года
Мои исследования
На первый взгляд самой привлекательной и простой схемой, найденной в даташитах и интернете, показалась схема на основе готового PULSE WIDTH MODULATION контроллера типа TL494 и её аналогах КА7500. TL 494 и ее последующие версии — наиболее часто применяемая микросхема для построения двухтактных преобразователей питания.
Но на деле это решение подходит под наши задачи только на 1/10 решения и её нельзя использовать на частотах более 100 кГц — в однотактном режиме и до 50 кГц — в двухтактном режиме. Почему? Хотя по даташиту она может использоваться и до 300кГц, мне не понравилось, как она себя ведет на частотах выше 100 кГц.
Что гласит даташит:
Допустимы рабочие частоты от 1 до 300 кГц, рекомендованный диапазон Rt = 1…500кОм, Ct=470пФ…10мкФ. При этом типовой температурный дрейф частоты без учета дрейфа навесных компонентов +/-3%, а уход частоты в зависимости от напряжения питания — в пределах 0.1% во всем допустимом диапазоне. Да только дело то не в уходе частоты, а в непостоянстве регулирования коэффициента заполнения в зависимости от частоты.
Я попробовал испытать её возможности, и хотел перекрыть нужный мне диапазон в 2 МГц, но на частоте выше 1 МГц она нормально так и не запустилась. Пришлось пока ограничиться только 1 МГц. Сделал пять диапазонов регулирования частоты, поставил стабилизатор напряжения на 12 вольт по питанию с блокировочными конденсаторами, чтобы не нарушалась чистота эксперимента и начал испытание.
Схема:
Макетная плата подопытной схемы:
Джамперы для выбора частоты:
Результаты проведенного испытания возможностей TL494:
Данная микросхема для моего требования к генератору не подходит, и никакие средства и ухищрения разогнать её на большую частоту так ни к чему и не привели. Предел мечтаний с ней это 100 кГц (с большой натяжкой 150 кГц). На более высокой частоте даёт о себе знать очень уж медленный компаратор, использующийся в схеме кристалла. Также мешает повышению частоты и встроенная коррекция. Читаем из даташита особенности данной микросхемы:
Для стабильной работы триггера — время переключения цифровой части TL494 составляет 200 нс. На тактовых частотах до 150 кГц при нулевом управляющем напряжении фаза покоя = 3% периода (эквивалентное смещение управляющего сигнала 100..120 мВ), на больших частотах встроенная коррекция расширяет фазу покоя до 200..300 нс. Так как в ней очень медленные усилители ошибки (фактически, операционные усилители с Ку = 70..95 дБ по постоянному напряжению, Ку = 1 на 300 кГц), я их не использую в схеме испытания вообще, и они заблокированы. Эти усилители не предназначены для работы в пределах одного такта рабочей частоты. При задержке распространения сигнала внутри усилителя в 400 нс они для этого слишком медленные, да и логика управления триггером не позволяет (возникали бы побочные импульсы на выходе). В реальных схемах преобразователей напряжения частота среза цепи ОС выбирается порядка 2 — 10кГц.
Замечания по работе микросхемы 494 на повышенной частоте, которые меня не устраивают:
1. Встроенный генератор пилообразного напряжения на большое время замыкает конденсатор, вследствие этого перед новым циклом заряда появляется площадка с нулевым потенциалом.
Осциллограммы работы генератора на разных частотах:
2. Сильная зависимость коэффициента заполнения от частоты, которая проявляется с нарастающим эффектом после прохождения частоты 100 кГц.
Рассматривая осциллограммы работы ШИМ регулятора с TL494 на разных частотах, при максимальном и минимальном коэффициенте заполнения, чётко заметны изменения минимального и максимального коэффициента заполнения в зависимости от частоты.
Как видно, изменение минимального коэффициента заполнения на частоте 50 кГц =5% и на частоте 1 МГц = 14,3% отличаются почти в три раза. А вот изменение максимального коэффициента заполнения, тут вообще удивляет: на частоте 50 кГц = 93% и на частоте 1 МГц = 60,7% отличаются на 32%!!!
Вот почему эту простую и удобную схему я отложил в сторонку. Она мне еще пригодится в дальнейшем: я к ней все-таки вернусь, но уже на дискретных быстрых компараторах и нормальных быстрых триггерах.
Дальше на пути у меня была схема на NE555 таймере, которую я использовал лишь только в качестве генератора пилообразного напряжения. Я и не предполагал, что он тоже окажется довольно медленным, но все же, немного лучше, чем предыдущая TL494. С ним можно подняться к частотам около 200 кГц в однотактном режиме. Только надо добавить компаратор и триггер с логикой ИЛИ-НЕ.
Схема генератора на 555 таймере:
Осциллограммы работы генератора пилообразного напряжения на 555 таймере на частотах 332 кГц и 462 кГц.
Тут видно округление вершин и спада импульса. На частоте более 500 кГц пила становится неузнаваема.
Разочаровавшись в готовых решениях только на аналоговых элементах, я пробовал синтезировать ШИМ чисто на цифровых логических элементах и счетчиках с триггерами, без использования аналоговых компонентов, но там меня подстерегали другие, куда более сложные проблемы. Выравнивание задержек распространения сигнала по элементам и т.п. Особенно большую проблему составляют триггеры и счетчики, которые совсем не хотят щелкать на малой длительности импульса и просто тупо пропускают счет. А это значит, что ключам, на которые будет работать генератор, очень скоро придет конец. Отказался от этой затеи через неделю боя с 561 логикой. Она, оказывается, ну уж очень медленная для таких частот — 20 МГц при делении ШИМа по 10 %. Ещё через две недели отказался и от 1533 тоже.
Финальная схема генератора.
После нескольких неудачных попыток воплотить мечту в реальность (иметь в своей домашней лаборатории генератор с 2 МГц ШИМа), недельку- другую отдохнул, подумал, набрался сил и снова приступил к решению проблемы. На этот раз без выкрутасов и лёгких путей, учитывая предыдущие наработки и ошибки. Из всех опробованных решений самое большее удобство пользования предоставляла схема на TL494 или на таймере. Поэтому было решено клонировать начинку NE555 и TL494 на быстродействующих компонентах и собирать некий «симбиоз» двух микросхем на отдельных компараторах и логике. Компараторы с ТТЛ выходом я взял те, что были у меня в столе — КР597СА2, но можно и любые другие, главное быстродействующие и с ТТЛ выходом. Ну, если вдруг захочется позверствовать, то ЭСЛ будет куда круче (тогда и 20 МГц не предел), но мне пока не нужна такая большая частота (разве для преобразователя с индуктивностью без ферритового сердечника). Тогда надо ставить КР597СА1, и логику серии К500.
После первого запуска схемы обнаружилось много казусов, но по мере отладки многие грабли были убраны, и схема заработала как часы.
Схема:
Схема состоит из генератора пилообразного напряжения (состоящего из стабилизатора тока на транзисторах VT1, VT2, VT3; двух компараторов DA1, DA2; триггера DD1 и разрядного транзистора VT4), схемы выделения прямоугольных импульсов (с шириной зависящей от порогового напряжения на DA3), двух стабилизаторов опорного напряжения (2,5в и 2,9в), формирователя двухтактного сигнала (на триггере DD2 и элементах DD3 DD4 2-ИЛИ-НЕ), повторителя и инвертора для однотактного выхода (на DD5, DD6).
Фото макетной платы:
Для облегчения процесса настройки я приведу осциллограммы напряжений в каждой важной точке схемы. Итак…
Генератор пилообразного напряжения. Конденсатор заряжается через стабилизатор тока. Канал 1 – напряжение на конденсаторе С5, канал 2 – напряжение на базе разрядного транзистора VT4.
По графикам заметен необъяснимый факт ухода напряжения в область отрицательных значений, но это работе не мешает, так как в схему выделения прямоугольных импульсов в задающее напряжение позже я также внесу небольшое отрицательное смещение с помощью делителя R6, R10 для охвата всего диапазона изменения напряжения «пилы». R1 подбирается для ограничения верхней максимальной частоты (я ограничился лишь 2 МГц, хотя вся схема нормально работает и до 5 МГц).
Осциллограммы напряжений на выходах компараторов DA1, DA2 на разной частоте. Канал 1 – напряжение на компараторе DA1 вывод 14, канал 2 – напряжение на компараторе DA2 вывод 14:
Для борьбы со «звоном» компаратора вблизи зоны переключения, в схеме выделения прямоугольных импульсов на DA3, я ввел резисторы ПОС (положительной обратной связи) R16, R15 на одноименных входах — выходах компаратора. ПОС нужна на частоте ниже 1 МГц. На частоте в 2МГц данная цепь не требуется и сама перестает участвовать в работе, что видно по осциллограммам. Осциллограммы напряжений на входах компаратора DA3 на разной частоте. Канал 2 – напряжение на компараторе DA3 вывод 2 – задание порога переключения, канал 1 – напряжение на компараторе DA3 вывод 3 с генератора «пилы». Осциллограмма на частоте 96 кГц. Канал 2 увеличено. Видна волнистая линия синхронно переключению компаратора – это и есть работа ПОС для задания гистерезиса. Глубину гистерезиса можно было бы и уменьшить, но на карту поставлены ключи, которыми будет управлять генератор, поэтому оставим все без изменения.
Далее схема выделения прямоугольных импульсов с шириной зависящей от порогового напряжения на DA3. На прямой вход компаратора подается пилообразное напряжение, а на инверсный вход – напряжение задания порога переключения компаратора. На выходе получается прямоугольный импульс. Смотрим осциллограммы, разбираемся и вникаем.
Здесь все понятно. Только если нужен для работы двухтактный выход, то увлекаться очень малым (99%) коэффициентом заполнения не стоит. Так как триггер на малой длительности входного импульса не успевает переключаться, и будет просто пропускать периоды, выдавая на выходе вместо двухтактных импульсов по очереди – два одинаковых, однотактных, а это чревато нехорошими последствиями, типа сквозного пробоя одновременно открытых ключей.
Дальше я покажу, как переключается триггер, когда длительность импульса достаточна для его нормальной работы на разных входных частотах. Частота на выходе D триггера равна половине частоты на входе, и всегда имеет коэффициент заполнения 50% независимо от коэффициента заполнения на входе. Все это видно ниже на графиках.
А вот так хулиганит триггер при входных импульсах недостаточной длительности:
Видно как сбивается развертка и просматривается тот самый пропуск импульса. А это приводит например в полумостовом преобразователе к сквозному «кототоку».
Далее покажу, как формируется полтакта двухтактного импульса, пройдя компаратор, триггер и логический элемент 2ИЛИ-НЕ:
То, что получилось на выходных контактах, я поместил в первой картинке. Внимательно смотрим, изучаем. Как видно из графиков, минимальная длительность импульсов на двухтактном выходе завышена до 5%, для того, чтобы триггер четко переключался при входной частоте 2 МГЦ. На частотах до 500 кГц её можно установить и 1 % не опасаясь за пропуски импульса.
Основной нюанс по настройке генератора: самое главное – чтобы стояли блокировочные керамические конденсаторы типа КМ-5 по 0,1 мкф минимум, или SMD импортные, на каждом корпусе микросхемы. Без них схема работает очень неустойчиво. Одна сторона платы используется для дорожек, а вторая используется как экран, её нужно соединить с корпусом в нескольких точках.
Блок питания каких–либо особенностей не имеет. Для канала +12в используется КРЕНка или 7812, а для канала – 6в используется 7906
Об выходных драйверах на 2 МГц напишу позже, а то и так много читать надо. Можно использовать готовые микросхемы драйверов, можно собирать на дискретных элементах.
Спасибо за внимание, и за терпение, и за то, что хватило сил дочитать до этой строки.
Ещё поздравляю и желаю много валерианки!!!
Макетная плата в Layout 5, видео работы генератора в разных режимах и картинки отдельно в файлах.
Файлы:
плата
архив картинок
видео
Все вопросы в Форум.
www.radiokot.ru
Обычно генераторы сигналов представляют собой оборудование, которые стоит несколько сотен долларов, но в зависимости от ваших потребностей, вы также можете использовать гораздо более дешевые решения, такие как плата лаборатории электроники PSLab ($65) или плата Arduino для генерации сигнала.
Также существует другой вариант приобрести ультра-дешевый генератор сигналов, такой как XY-PWM1, который можно найти на ICStation всего за $4.19. Его функции ограничивается ШИМ импульсами от 1 Гц до 150 кГц с диапазоном напряжения от 3,3 до 30 В.
Технические характеристики XY-PWM1:
В нем нет определенной кнопки для выбора режима, но скорей всего, вам просто нужно использовать комбинацию короткого и длинного нажатия, чтобы выбрать нужный режим, а с помощью потенциометра можно настроить коэффициент заполнения и частоту.
Типичный рабочий процесс выглядит следующим образом:
Он имеет очень интересный способ отображения частот на дисплее при 100 кГц или выше:
Данный тип инструмента может использоваться для генерации прямоугольных импульсов, для управления двигателями, а также в качестве диммера или регулятора скорости и так далее.
XY-PWM1 также можно приобрести на Aliexpress или eBay менее чем за $5. Также можно найти аналогичную модуль на Amazon (WHDTS) с практически такими же функциями, за исключением того, что вращающийся переключатель заменен четырьмя сенсорными кнопками..
Выражаем свою благодарность источнику из которого взята и переведена статья, сайту cnx-software.com.
Оригинал статьи вы можете прочитать здесь.
www.cnx-software.ru
Простейший генератор широтно-импульсных сигналов.
Основным назначением программы PWM Generator является формирование сигналов широтно-импульсной модуляции в режиме реального времени. Данные тоны генерируются на основе заданных значений частоты (в Герцах), рабочего цикла – соотношения времени между низким и высоким состоянием сигнала (в процентах) и амплитуды – уровня цифрового сигнала (в dBFS). Все вышеперечисленные параметры могут быть мгновенно изменены во время работы. Максимально возможный уровень генерируемого сигнала равен 0 dBFS, а наибольшая частота составляет половину частоты дискретизации. Для настройки генерирования звука оптимального уровня качества предусмотрено целое меню выходных характеристик. Здесь присутствует возможность изменения количества и размера внутренних буферов данных, частоты дискретизации и квантования.
Программное обеспечение может использоваться для создания управляющих тонов различных электрических и электромеханических устройств. В частности результирующий ШИМ-сигнал, снятый с выхода звуковой карты персонального компьютера и пропущенный через стандартный аудиоусилитель, применяется для регулирования двигателей, вентиляторов, приборов освещения.
PWM Generator поддерживает работу с несколькими звуковыми картами, причем предоставляется возможность выбора той из них, которая будет использоваться для вывода искомого сигнала (по умолчанию программа работает с устройством вывода, указанным в панели управления Windows). Стоит отметить, что рабочий ШИМ-сигнал может быть сохранен в качестве WAV-файла и в дальнейшем прослушан с помощью стандартного программного обеспечения. А при регулярном использовании определенных тонов генератор ШИМ-сигналов дает возможность сохранять (и загружать) их в виде пресетов. Кроме того, несколько пресетов поставляются вместе с приложением.
PWM Generator поддерживает опцию синхронизации всех запущенных экземпляров программы, позволяя генерировать сразу несколько тонов. Необходимо отметить возможность работы программного обеспечения в фоновом режиме, позволяя, пользователям переключить внимание на другие приложения. Кроме того PWM Generator может управляться с помощью скриптовых команд, а также через системы Windows Messaging.
Авторы сообщают, что чем быстрее рабочая станция, тем выше будет качество звука и «отзывчивость» элементов управления во время воспроизведения тонов.
Рассматриваемое приложение было написано работниками немецкой компании Esser Audio. Данная организация занимается созданием и распространением программных продуктов (Filtered Noise Generator, Test Tone Generator, Multi Tone Generator и т.д.), предназначенных, в основном, для тестирования и испытания аудиоаппаратуры. Программы от Esser Audio отличаются неплохой функциональностью и крайне простым интерфейсом.
Программа PWM Generator является условно-бесплатной, ознакомительная версия дает возможность свободного запуска и тестирования приложения в течение первых тридцати дней. Стоимость программы для стран не входящих в Европейский союз составляет 14 евро, для входящих – 16,66 евро (за счет добавления налога на продажу). При покупке нескольких лицензий предоставляется скидка.
Приложение распространяется на английском и немецком языках. Справочный файл содержит подробное описание всех возможностей софта, а для дополнительной поддержки пользователей программного пакета был создан справочный онлайн-форум. Русской версии PWM Generator пока не существует.
Последняя версия программного обеспечения работоспособна на любых компьютерах с 32- или 64-разрядной операционной системой Microsoft Windows (9x, NT, 2000, 2003, XP, Vista, 7, 8) и звуковой картой.
Распространение программы: условно-бесплатная 14 евро. Есть триал-версия (30 суток)
Официальный сайт PWM Generator: http://www.esseraudio.com
Скачать PWM Generator
Обсуждение программы на форуме
cxem.net
Широтно-импульсная модуляция (ШИМ) – это метод преобразования сигнала, при котором изменяется длительность импульса (скважность), а частота остаётся константой. В английской терминологии обозначается как PWM (pulse-width modulation). В данной статье подробно разберемся, что такое ШИМ, где она применяется и как работает.
С развитием микроконтроллерной техники перед ШИМ открылись новые возможности. Этот принцип стал основой для электронных устройств, требующих, как регулировки выходных параметров, так и поддержания их на заданном уровне. Метод широтно-импульсной модуляции применяется для изменения яркости света, скорости вращения двигателей, а также в управлении силовым транзистором блоков питания (БП) импульсного типа.
Широтно-импульсная (ШИ) модуляция активно используется в построении систем управления яркостью светодиодов. Благодаря низкой инерционности, светодиод успевает переключаться (вспыхивать и гаснуть) на частоте в несколько десятков кГц. Его работа в импульсном режиме воспринимается человеческим глазом как постоянное свечение. В свою очередь яркость зависит от длительности импульса (открытого состояния светодиода) в течение одного периода. Если время импульса равно времени паузы, то есть коэффициент заполнения – 50%, то яркость светодиода будет составлять половину от номинальной величины. С популяризацией светодиодных ламп на 220В стал вопрос о повышении надёжности их работы при нестабильном входном напряжении. Решение было найдено в виде универсальной микросхемы – драйвера питания, работающего по принципу широтно-импульсной или частотно-импульсной модуляции. Схема на базе одного из таких драйверов детально описана здесь.
Подаваемое на вход микросхемы драйвера сетевое напряжение постоянно сравнивается с внутрисхемным опорным напряжением, формируя на выходе сигнал ШИМ (ЧИМ), параметры которого задаются внешними резисторами. Некоторые микросхемы имеют вывод для подачи аналогового или цифрового сигнала управления. Таким образом, работой импульсного драйвера можно управлять с помощью другого ШИ-преобразователя. Интересно, что на светодиод поступают не высокочастотные импульсы, а сглаженный дросселем ток, который является обязательным элементом подобных схем.
Масштабное применение ШИМ отражено во всех LCD панелях со светодиодной подсветкой. К сожалению, в LED мониторах большая часть ШИ-преобразователей работает на частоте в сотни Герц, что негативно отражается на зрении пользователей ПК.
Микроконтроллер Ардуино тоже может функционировать в режиме ШИМ контроллера. Для этого следует вызвать функцию AnalogWrite() с указанием в скобках значения от 0 до 255. Ноль соответствует 0В, а 255 – 5В. Промежуточные значения рассчитываются пропорционально.
Повсеместное распространение устройств, работающих по принципу ШИМ, позволило человечеству уйти от трансформаторных блоков питания линейного типа. Как результат – повышение КПД и снижение в несколько раз массы и размеров источников питания.
ШИМ-контроллер является неотъемлемой частью современного импульсного блока питания. Он управляет работой силового транзистора, расположенного в первичной цепи импульсного трансформатора. За счёт наличия цепи обратной связи напряжение на выходе БП всегда остаётся стабильным. Малейшее отклонение выходного напряжения через обратную связь фиксируется микросхемой, которая мгновенно корректирует скважность управляющих импульсов. Кроме этого современный ШИМ-контроллер решает ряд дополнительных задач, способствующих повышению надёжности источника питания:
Задача ШИМ контроллера состоит в управлении силовым ключом за счёт изменения управляющих импульсов. Работая в ключевом режиме, транзистор находится в одном из двух состояний (полностью открыт, полностью закрыт). В закрытом состоянии ток через p-n-переход не превышает несколько мкА, а значит, мощность рассеивания стремится к нулю. В открытом состоянии, несмотря на большой ток, сопротивление p-n-перехода чрезмерно мало, что также приводит к незначительным тепловым потерям. Наибольшее количество тепла выделяется в момент перехода из одного состояния в другое. Но за счёт малого времени переходного процесса по сравнению с частотой модуляции, мощность потерь при переключении незначительна.
Широтно-импульсная модуляция разделяется на два вида: аналоговая и цифровая. Каждый из видов имеет свои преимущества и схемотехнически может реализовываться разными способами.
Принцип действия аналогового ШИ-модулятора основан на сравнении двух сигналов, частота которых отличается на несколько порядков. Элементом сравнения выступает операционный усилитель (компаратор). На один из его входов подают пилообразное напряжение высокой постоянной частоты, а на другой – низкочастотное модулирующее напряжение с переменной амплитудой. Компаратор сравнивает оба значения и на выходе формирует прямоугольные импульсы, длительность которых определяется текущим значением модулирующего сигнала. При этом частота ШИМ равна частоте сигнала пилообразной формы.
Широтно-импульсная модуляция в цифровой интерпретации является одной из многочисленных функций микроконтроллера (МК). Оперируя исключительно цифровыми данными, МК может формировать на своих выходах либо высокий (100%), либо низкий (0%) уровень напряжения. Однако в большинстве случаев для эффективного управления нагрузкой напряжение на выходе МК необходимо изменять. Например, регулировка скорости вращения двигателя, изменение яркости светодиода. Что делать, чтобы получить на выходе микроконтроллера любое значение напряжения в диапазоне от 0 до 100%?
Вопрос решается применением метода широтно-импульсной модуляции и, используя явление передискретизации, когда заданная частота переключения в несколько раз превышает реакцию управляемого устройства. Изменяя скважность импульсов, меняется среднее значение выходного напряжения. Как правило, весь процесс происходит на частоте в десятки-сотни кГц, что позволяет добиться плавной регулировки. Технически это реализуется с помощью ШИМ-контроллера – специализированной микросхемы, которая является «сердцем» любой цифровой системы управления. Активное использование контроллеров на основе ШИМ обусловлено их неоспоримыми преимуществами:
Получить на выводах микроконтроллера ШИМ сигнал можно двумя способами: аппаратно и программно. В каждом МК имеется встроенный таймер, который способен генерировать ШИМ импульсы на определённых выводах. Так достигается аппаратная реализация. Получение ШИМ сигнала с помощью программных команд имеет больше возможностей в плане разрешающей способности и позволяет задействовать большее количество выводов. Однако программный способ ведёт к высокой загрузке МК и занимает много памяти.
Примечательно, что в цифровой ШИМ количество импульсов за период может быть различным, а сами импульсы могут быть расположены в любой части периода. Уровень выходного сигнала определяется суммарной длительностью всех импульсов за период. При этом следует понимать, что каждый дополнительный импульс – это переход силового транзистора из открытого состояния в закрытое, что ведёт к росту потерь во время переключений.
Один из вариантов реализации ШИМ простого регулятора уже описывался ранее в этой статье. Он построен на базе микросхемы NE555 и имеет небольшую обвязку. Но, несмотря на простату схемы, регулятор имеет довольно широкую область применения: схемы управления яркости светодиодов, светодиодных лент, регулировка скорость вращения двигателей постоянного тока.
Читайте так жеledjournal.info
Вот уже несколько раз я ругался странным словом ШИМ. Пора бы внести ясность и разьяснить что же это такое. Вообще, я уже расписывал этот режим работы, но все же повторюсь в рамках своего курса.
Вкратце, Широтно Импульсная Модуляция (в буржуйской нотации этот режим зовется PWM — Pulse Width Modulation) это способ задания аналогового сигнала цифровым методом, то есть из цифрового выхода, дающего только нули и единицы получить какие то плавно меняющиеся величины. Звучит как бред, но тем не менее работает. А суть в чем:
Представь себе тяжеленный маховик который ты можешь вращать двигателем. Причем двигатель ты можешь либо включить, либо выключить. Если включить его постоянно, то маховик раскрутится до максимального значения и так и будет крутиться. Если выключить, то остановится за счет сил трения.
А вот если двигатель включать на десять секунд каждую минуту, то маховик раскрутится, но далеко не на полную скорость — большая инерция сгладит рывки от включающегося двигателя, а сопротивление от трения не даст ему крутится бесконечно долго.
Чем больше продолжительность включения двигателя в минуту, тем быстрей будет крутится маховик.
При ШИМ мы гоним на выход сигнал состоящий из высоких и низких уровней (применимо к нашей аналогии — включаем и выключаем двигатель), то есть нулей и единицы. А затем это все пропускается через интегрирующую цепочку (в аналогии — маховик). В результате интегрирования на выходе будет величина напряжения, равная площади под импульсами.
Меня скважность (отношение длительности периода к длительности импульса) можно плавно менять эту площадь, а значит и напряжение на выходе. Таким образом если на выходе сплошные 1, то на выходе будет напряжение высокого уровня, в случае моего робота, на выходе из моста L293 это 12 вольт, если нули, то ноль. А если 50% времени будет высокий уровень, а 50% низкий то 6 вольт. Интегрирующей цепочкой тут будет служить масса якоря двигателя, обладающего довольно большой инерцией.
А что будет если взять и гнать ШИМ сигнал не от нуля до максимума, а от минуса до плюса. Скажем от +12 до -12. А можно задавать переменный сигнал! Когда на входе ноль, то на выходе -12В, когда один, то +12В. Если скважность 50% то на выходе 0В. Если скважность менять по синусоидальному закону от максимума к минимуму, то получим… правильно! Переменное напряжение. А если взять три таких ШИМ генератора и гнать через них синусоиды сдвинутые на 120 градусов между собой, то получим самое обычное трехфазное напряжение, а значит привет бесколлекторные асинхронные и синхронные двигатели — фетиш всех авиамоделистов. На этом принципе построены все современные промышленные привода переменного тока. Всякие Unidrive и Omron Jxx
В качестве сглаживающей интегрирующей цепи в ШИМ может быть применена обычная RC цепочка:
Так, принцип понятен, приступаем к реализации.
ШИМ сигнал можно сварганить и на операционных усилителях и на микроконтроллере. Причем последние умеют это делать просто мастерски, благо все у них для этого уже есть.
Аппаратный ШИМ
В случае ATMega16 проще всего сделать на его ШИМ генераторе, который встроен в таймеры. Причем в первом таймере у нас целых два канала. Так что без особого напряга ATmega16 может реализовать одновременно четыре канала ШИМ.
Как это реализовано
У таймера есть особый регистр сравнения OCR**. Когда значение в счётном регистре таймера достигнает значения находящегося в регистре сравнения, то могут возникнуть следующие аппаратные события:
Выходы сравнения выведены наружу, на выводы микроконтроллера
На демоплате Pinboard к этим выводам как раз подключены светодиоды. А если поставить джамперы вдоль, в сторону надписи RC то к выводу ШИМ будет подключена интегрирующая цепочка.
Для Pinboard II разница в подключении невелика. Джамперы тут сгруппированы в один блок. А светодиоды и RC цепочки сгруппированы в левом верхнем углу платы.
Предположим, что мы настроили наш ШИМ генератор так, чтобы когда значение в счетном регистре больше чем в регистре сравнения, то на выходе у нас 1, а когда меньше, то 0.
Что при этом произойдет? Таймер будет считать как ему и положено, от нуля до 256, с частотой которую мы настроим битами предделителя таймера. После переполнения сбрасывается в 0 и продолжает заново.
Как видишь, на выходе появляются импульсы. А если мы попробуем увеличить значение в регистре сравнения, то ширина импульсов станет уже.
Так что меняя значение в регистре сравнения можно менять скважность ШИМ сигнала. А если пропустить этот ШИМ сигнал через сглаживающую RC цепочку (интегратор) то получим аналоговый сигнал.
У таймера может быть сколько угодно регистров сравнения. Зависит от модели МК и типа таймера. Например, у Атмега16
Итого — четыре канала. В новых AVR бывает и по три регистра сравнения на таймер, что позволяет одним МК организовать просто прорву независимых ШИМ каналов.
Самих режимов ШИМ существует несколько:
Fast PWM
В этом режиме счетчик считает от нуля до 255, после достижения переполнения сбрасывается в нуль и счет начинается снова. Когда значение в счетчике достигает значения регистра сравнения, то соответствующий ему вывод ОСхх сбрасыватся в ноль. При обнулении счетчика этот вывод устанавливается в 1. И все!
Частота получившегося ШИМ сигнала определяется просто: Частота процесора 8Мгц, таймер тикает до 256 с тактовой частотой. Значит один период ШИМ будет равен 8000 000/256 = 31250Гц. Вполне недурно. Быстрей не получится — это максимальная скорость на внутреннем 8Мгц тактовом генераторе. Но если переключить FUSE биты на внешний кварц то можно раскачать МК на 16Мгц.
Еще есть возможность повысить разрешение, сделав счет 8, 9, 10 разрядным (если разрядность таймера позволяет), но надо учитывать, что повышение разрядности, вместе с повышением дискретности выходного аналогового сигнала, резко снижает частоту ШИМ.
Phase Correct PWM
ШИМ с точной фазой. Работает похоже, но тут счетчик считает несколько по другому. Сначала от 0 до 255, потом от 255 до 0. Вывод OCxx при первом совпадении сбрасывается, при втором устанавливается.
Но частота ШИМ при этом падает вдвое, изза большего периода. Основное его предназначение, делать многофазные ШИМ сигналы, например, трехфазную синусоиду. Чтобы при изменении скважности не сбивался угол фазового сдвига между двумя ШИМ сигналами. Т.е. центры импульсов в разных каналах и на разной скважности будут совпадать.
Еще одна тонкость:
Чтобы не было кривых импульсов, то в регистр сравнения любое значение попадает через буфферный регистр и заносится только тогда, когда значение в счетчике достигнет максимума. Т.е. к началу нового периода ШИМ импульса.
Clear Timer On Compare
Сброс при сравнении. Это уже скорей ЧИМ — частотно-импульсно моделированный сигнал. Тут работает несколько иначе, чем при других режимах. Тут счетный таймер тикает не от 0 до предела, а от 0 до регистра сравнения! А после чего сбрасывается.
В результате, на выходе получаются импульсы всегда одинаковой скважности, но разной частоты. А чаще всего этот режим применяется когда надо таймером отсчитывать периоды (и генерить прерывание) с заданной точностью.
Например, надо нам прерывание каждую миллисекунду. И чтобы вот точно. Как это реализовать проще? Через Режим СТС! Пусть у нас частота 8Мгц.
Прескалер будет равен 64, таким образом, частота тиков таймера составит 125000 Гц. А нам надо прерывание с частотой 1000Гц. Поэтому настраиваем прерывание по совпадению с числом 125.
Дотикал до 125 — дал прерывание, обнулился. Дотикал до 125 — дал прерывание, обнулился. И так бесконечно, пока не выключим.
Вот вам и точная тикалка.
Нет, конечно, можно и вручную. Через переполнение, т.е. дотикал до переполнения, загрузил в обработчике прерывания заново нужные значение TCNTх=255-125, сделал нужные полезные дела и снова тикать до переполнения. Но ведь через СТС красивей! 🙂
Аппаратура
А теперь контрольные регистры, которыми все это безобразие задается и программируется. Опишу на примере Двухканального FastPWM на таймере 1. В других все похоже. Даташит в зубы и вперед.
Итак, тут правят бал регистры TCCR1A и TCCR1B. Гы, кто бы сомневался %)
Распишу их по битам.
Регистр TCCR1A, биты COM1A1:COM1A0 и COM1B1:COM1B0. Эта братия определяет поведение вывода сравнения OC1A и OC1B соответственно.
COMxx1 | COMxx0 | Режим работы выхода |
0 | 0 | вывод отцеплен от регистра сравнения и не меняется никак. |
0 | 1 | Поведение вывода зависит от режима заданного в WGM, различается для разных режимов (FastPWM, FC PWM, Compar out) и разных МК, надо сверяться с даташитом. |
1 | 0 | прямой ШИМ (сброс при совпадении и установка при обнулении счета) |
1 | 1 | обратный ШИМ (сброс при обнулении и установка при совпадении) |
Регистр TCCR1A, биты WGM11 и WGM10 вместе с битами WGM12 и WGM13, находящимися в регистре TCCR1B задают режим работы генератора.
WGM13 | WGM12 | WGM11 | WGM10 | Режим работы |
0 | 1 | 0 | 1 | Fast PWM 8 бит |
0 | 1 | 1 | 0 | Fast PWM 9 бит |
0 | 1 | 1 | 1 | Fast PWM 10 бит |
Другие комбинации битов WGM задают режимы Phase Correct PWM и CTC (сброс OCxx при совпадении). Если интересно, то читай даташит, я для себя много интересного там не нашел, кроме Phase Correct PWM. И то мне сейчас важней скорость, а не точность фазы 🙂
После остается только запустить таймер, установив бит CS10 (подсчет тактовых импульсов с делителем 1:1)
Пример кода:
Попробуем поиграться яркостью светодиодов с помощью ШИМ сигналов. Подключи джамперы, чтобы запитать светодиоды LED1 и LED2
Для версии Pinboard II все аналогично, с поправкой на другое расположение джамперов:
Теперь все готово, можно писать код. Вначале в раздел инициализации устройств добавляю настройку таймера на запуск ШИМ и подготовку выводов.
1 2 3 4 5 6 7 8 9 10 11 12 | ;FastPWM Init SETB DDRD,4,R16 ; DDRD.4 = 1 Порты на выход SETB DDRD,5,R16 ; DDRD.5 = 1 ; Выставляем для обоих каналов ШИМ режим вывода ОС** сброс при совпадении. ; COM1A = 10 и COM1B = 10 ; Также ставим режим FAST PWM 8bit (таймер 16ти разрядный и допускает ; большую разрядность ШИМ сигнала. Вплоть до 10 бит. WGM = 0101 ; Осталось только запустить таймер на частоте МК CS = 001 OUTI TCCR1A,2<<COM1A0|2<<COM1B0|0<<WGM11|1<<WGM10 OUTI TCCR1B,0<<WGM13|1<<WGM12|1<<CS10 |
;FastPWM Init SETB DDRD,4,R16 ; DDRD.4 = 1 Порты на выход SETB DDRD,5,R16 ; DDRD.5 = 1 ; Выставляем для обоих каналов ШИМ режим вывода ОС** сброс при совпадении. ; COM1A = 10 и COM1B = 10 ; Также ставим режим FAST PWM 8bit (таймер 16ти разрядный и допускает ; большую разрядность ШИМ сигнала. Вплоть до 10 бит. WGM = 0101 ; Осталось только запустить таймер на частоте МК CS = 001 OUTI TCCR1A,2<<COM1A0|2<<COM1B0|0<<WGM11|1<<WGM10 OUTI TCCR1B,0<<WGM13|1<<WGM12|1<<CS10
Готово! Теперь ШИМ таймера1 генерит сигнал на выходаx OC1А и OC1B
Закинем в регистры сравнения первого и второго канала число 255/3=85 и 255/2 = 128
Так как ШИМ у нас 8ми разрядный, то заброс идет только в младший разряд. Старший же остается нулем. Но регистры сравнения тут у нас 16ти разрядные поэтому грузить надо оба байта сразу. Не забыв запретить прерывания (это важно!!! ибо атомарный доступ)
1 2 3 4 5 6 7 | CLI OUTI OCR1AH,0 OUTI OCR1AL,85 OUTI OCR1BH,0 OUTI OCR1BL,128 SEI |
CLI OUTI OCR1AH,0 OUTI OCR1AL,85 OUTI OCR1BH,0 OUTI OCR1BL,128 SEI
Поехали! 🙂
Прошиваем, тыкаемся в ноги микроконтроллера осциллографом — видим следующую картину по каналам:
Как мы и запланировали. С первого канала длительность импульса в 1/3 периода, а со второго в 1/2
Ну и светодиоды горят с разной яркостью. Один ярче, другой тусклей. Меняя значение в регистрах OCR*** мы можем менять скважность.
Давай сделаем так, чтобы светодиод плавно менял свою яркость от нуля до максимума. Как помнишь, у нас там была программа, с мигающем по таймеру0 светодиодом. Немного ее подправим, сделаем так, чтобы по таймеру не светодиод мигал, а менялось значение в регистрах сравнения OCR1A и OCR1B. Причем меняться оно будет в разные стороны 🙂
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | ; Main ========================================================= Main: LDS R16,TCNT ; Грузим числа в регистры LDS R17,TCNT+1 CPI R16,0x10 ; Сравниванем побайтно выдержку BRCS NoMatch CPI R17,0x01 ; Выдержку сделали поменьше = 0x0110 BRCS NoMatch ; Если совпало то делаем экшн Match: CLI ; Запрет прерываний, т.к. атомарный доступ ; Меняем первый канал ; Особенность 16ти разрядных регистров в том, что их надо правильно читать и записывать. ; Читают вначале младший, потом старший байты. Так надо, чтобы младший не успел измениться ; (он ведь может тикать по таймеру) пока читают первым старший. Укладывают их в обратном ; порядке. Сначала старший, потом младший. Правда для регистров OCR это не имеет большой ; разницы -- они статичные, а вот для TCNT очень даже! IN R16,OCR1AL ; Достали первый байт сравнения IN R17,OCR1AH ; он 16ти разрядный, но старший байт будет 0 INC R16 ; Увеличили OUT OCR1AH,R17 ; И сунули их обратно OUT OCR1AL,R16 ; Меняем второй канал IN R16,OCR1BL ; Достали второй байт сравнения IN R17,OCR1BH ; он 16ти разрядный, но старший байт будет 0 DEC R16 ; Уменьшили OUT OCR1BH,R17 ; И сунули их обратно OUT OCR1BL,R16 SEI ; Конец атомарного доступа ; Теперь надо обнулить счетчик, иначе за эту же итерацию главного цикла ; Мы сюда попадем еще не один раз -- таймер то не успеет натикать 255 значений ; чтобы число в первых двух байтах счетчика изменилось. CLR R16 ; Нам нужен ноль CLI ; Таймер меняется и в прерывании. Нужен ; атомарный доступ. Запрещаем прерывания OUT TCNT0,R16 ; Ноль в счетный регистр таймера STS TCNT,R16 ; Ноль в первый байт счетчика в RAM STS TCNT+1,R16 ; Ноль в второй байт счетчика в RAM STS TCNT+2,R16 ; Ноль в третий байт счетчика в RAM STS TCNT+3,R16 ; Ноль в первый байт счетчика в RAM SEI ; Разрешаем прерывания. ; Не совпало - не делаем :) NoMatch: NOP INCM CCNT ; Шарманка вращается дальше, вхолостую JMP Main |
; Main ========================================================= Main: LDS R16,TCNT ; Грузим числа в регистры LDS R17,TCNT+1 CPI R16,0x10 ; Сравниванем побайтно выдержку BRCS NoMatch CPI R17,0x01 ; Выдержку сделали поменьше = 0x0110 BRCS NoMatch ; Если совпало то делаем экшн Match: CLI ; Запрет прерываний, т.к. атомарный доступ ; Меняем первый канал ; Особенность 16ти разрядных регистров в том, что их надо правильно читать и записывать. ; Читают вначале младший, потом старший байты. Так надо, чтобы младший не успел измениться ; (он ведь может тикать по таймеру) пока читают первым старший. Укладывают их в обратном ; порядке. Сначала старший, потом младший. Правда для регистров OCR это не имеет большой ; разницы — они статичные, а вот для TCNT очень даже! IN R16,OCR1AL ; Достали первый байт сравнения IN R17,OCR1AH ; он 16ти разрядный, но старший байт будет 0 INC R16 ; Увеличили OUT OCR1AH,R17 ; И сунули их обратно OUT OCR1AL,R16 ; Меняем второй канал IN R16,OCR1BL ; Достали второй байт сравнения IN R17,OCR1BH ; он 16ти разрядный, но старший байт будет 0 DEC R16 ; Уменьшили OUT OCR1BH,R17 ; И сунули их обратно OUT OCR1BL,R16 SEI ; Конец атомарного доступа ; Теперь надо обнулить счетчик, иначе за эту же итерацию главного цикла ; Мы сюда попадем еще не один раз — таймер то не успеет натикать 255 значений ; чтобы число в первых двух байтах счетчика изменилось. CLR R16 ; Нам нужен ноль CLI ; Таймер меняется и в прерывании. Нужен ; атомарный доступ. Запрещаем прерывания OUT TCNT0,R16 ; Ноль в счетный регистр таймера STS TCNT,R16 ; Ноль в первый байт счетчика в RAM STS TCNT+1,R16 ; Ноль в второй байт счетчика в RAM STS TCNT+2,R16 ; Ноль в третий байт счетчика в RAM STS TCNT+3,R16 ; Ноль в первый байт счетчика в RAM SEI ; Разрешаем прерывания. ; Не совпало — не делаем 🙂 NoMatch: NOP INCM CCNT ; Шарманка вращается дальше, вхолостую JMP Main
А теперь давайте включим режим с точной фазой (WGM = 0001) и посмотрим на то как будет меняться скважность.
1 2 | OUTI TCCR1A,2<<COM1A0|2<<COM1B0|0<<WGM11|1<<WGM10 OUTI TCCR1B,0<<WGM13|0<<WGM12|1<<CS10 |
OUTI TCCR1A,2<<COM1A0|2<<COM1B0|0<<WGM11|1<<WGM10 OUTI TCCR1B,0<<WGM13|0<<WGM12|1<<CS10
ШИМ на прерываниях.
Но вот засада — плата уже разведена, захотелось ШИМ, а выводы OCxx уже задействованы под другие цели.
Ничего страшного, малой кровью можно это исправить. Также запускаем ШИМ, только:
Все просто 🙂
Пример:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | ;FastPWM Init на прерываниях ; ШИМ будет на выводах 3 и 6 порта D SETB DDRD,3,R16 ; DDRD.3 = 1 Порты на выход SETB DDRD,6,R16 ; DDRD.6 = 1 ; Выставляем для обоих каналов ШИМ режим вывода ОС** выключеным. ; COM1A = 00 и COM1B = 00 ; Также ставим режим FAST PWM 8bit (таймер 16ти разрядный и допускает ; большую разрядность ШИМ сигнала. Вплоть до 10 бит. WGM = 0101 ; Осталось только запустить таймер на частоте МК CS = 001 OUTI TCCR1A,0<<COM1A0|0<<COM1B0|0<<WGM11|1<<WGM10 OUTI TCCR1B,0<<WGM13|1<<WGM12|1<<CS10 SETB TIMSK,OCIE1A,R16 ; Включаем прерывание по сравнению А SETB TIMSK,OCIE1B,R16 ; Включаем прерывание по сравнению Б SETB TIMSK,TOIE1,R16 ; Включаем прерывание по переполнению Т1 ; Причем в режиме WGM=1010 переполнение ; будет на FF т.е. таймер работает как ; 8ми разрядный. |
;FastPWM Init на прерываниях ; ШИМ будет на выводах 3 и 6 порта D SETB DDRD,3,R16 ; DDRD.3 = 1 Порты на выход SETB DDRD,6,R16 ; DDRD.6 = 1 ; Выставляем для обоих каналов ШИМ режим вывода ОС** выключеным. ; COM1A = 00 и COM1B = 00 ; Также ставим режим FAST PWM 8bit (таймер 16ти разрядный и допускает ; большую разрядность ШИМ сигнала. Вплоть до 10 бит. WGM = 0101 ; Осталось только запустить таймер на частоте МК CS = 001 OUTI TCCR1A,0<<COM1A0|0<<COM1B0|0<<WGM11|1<<WGM10 OUTI TCCR1B,0<<WGM13|1<<WGM12|1<<CS10 SETB TIMSK,OCIE1A,R16 ; Включаем прерывание по сравнению А SETB TIMSK,OCIE1B,R16 ; Включаем прерывание по сравнению Б SETB TIMSK,TOIE1,R16 ; Включаем прерывание по переполнению Т1 ; Причем в режиме WGM=1010 переполнение ; будет на FF т.е. таймер работает как ; 8ми разрядный.
Осталось только прописать обработчики и вектора:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | .CSEG .ORG $000 ; (RESET) RJMP Reset .ORG $002 RETI ; (INT0) External Interrupt Request 0 .ORG $004 RETI ; (INT1) External Interrupt Request 1 .ORG $006 RETI ; (TIMER2 COMP) Timer/Counter2 Compare Match .ORG $008 RETI ; (TIMER2 OVF) Timer/Counter2 Overflow .ORG $00A RETI ; (TIMER1 CAPT) Timer/Counter1 Capture Event .ORG $00C RJMP Timer1_OCA ; (TIMER1 COMPA) Timer/Counter1 Compare Match A .ORG $00E RJMP Timer1_OCB ; (TIMER1 COMPB) Timer/Counter1 Compare Match B .ORG $010 RJMP Timer1_OVF ; (TIMER1 OVF) Timer/Counter1 Overflow .ORG $012 RJMP Timer0_OV ; (TIMER0 OVF) Timer/Counter0 Overflow .ORG $014 RETI ; (SPI,STC) Serial Transfer Complete .ORG $016 RETI ; (USART,RXC) USART, Rx Complete .ORG $018 RETI ; (USART,UDRE) USART Data Register Empty .ORG $01A RETI ; (USART,TXC) USART, Tx Complete .ORG $01C RETI ; (ADC) ADC Conversion Complete .ORG $01E RETI ; (EE_RDY) EEPROM Ready .ORG $020 RETI ; (ANA_COMP) Analog Comparator .ORG $022 RETI ; (TWI) 2-wire Serial Interface .ORG $024 RETI ; (INT2) External Interrupt Request 2 .ORG $026 RETI ; (TIMER0 COMP) Timer/Counter0 Compare Match .ORG $028 RETI ; (SPM_RDY) Store Program Memory Ready .ORG INT_VECTORS_SIZE ; Конец таблицы прерываний ; Interrupts ============================================== Timer0_OV: PUSHF PUSH R17 PUSH R18 PUSH R19 INCM TCNT POP R19 POP R18 POP R17 POPF RETI ; Вот наши обработчики на ШИМ Timer1_OCA: SBI PORTD,3 RETI Timer1_OCB: SBI PORTD,6 RETI Timer1_OVF: CBI PORTD,3 CBI PORTD,6 RETI ; End Interrupts ========================================== |
.CSEG .ORG $000 ; (RESET) RJMP Reset .ORG $002 RETI ; (INT0) External Interrupt Request 0 .ORG $004 RETI ; (INT1) External Interrupt Request 1 .ORG $006 RETI ; (TIMER2 COMP) Timer/Counter2 Compare Match .ORG $008 RETI ; (TIMER2 OVF) Timer/Counter2 Overflow .ORG $00A RETI ; (TIMER1 CAPT) Timer/Counter1 Capture Event .ORG $00C RJMP Timer1_OCA ; (TIMER1 COMPA) Timer/Counter1 Compare Match A .ORG $00E RJMP Timer1_OCB ; (TIMER1 COMPB) Timer/Counter1 Compare Match B .ORG $010 RJMP Timer1_OVF ; (TIMER1 OVF) Timer/Counter1 Overflow .ORG $012 RJMP Timer0_OV ; (TIMER0 OVF) Timer/Counter0 Overflow .ORG $014 RETI ; (SPI,STC) Serial Transfer Complete .ORG $016 RETI ; (USART,RXC) USART, Rx Complete .ORG $018 RETI ; (USART,UDRE) USART Data Register Empty .ORG $01A RETI ; (USART,TXC) USART, Tx Complete .ORG $01C RETI ; (ADC) ADC Conversion Complete .ORG $01E RETI ; (EE_RDY) EEPROM Ready .ORG $020 RETI ; (ANA_COMP) Analog Comparator .ORG $022 RETI ; (TWI) 2-wire Serial Interface .ORG $024 RETI ; (INT2) External Interrupt Request 2 .ORG $026 RETI ; (TIMER0 COMP) Timer/Counter0 Compare Match .ORG $028 RETI ; (SPM_RDY) Store Program Memory Ready .ORG INT_VECTORS_SIZE ; Конец таблицы прерываний ; Interrupts ============================================== Timer0_OV: PUSHF PUSH R17 PUSH R18 PUSH R19 INCM TCNT POP R19 POP R18 POP R17 POPF RETI ; Вот наши обработчики на ШИМ Timer1_OCA: SBI PORTD,3 RETI Timer1_OCB: SBI PORTD,6 RETI Timer1_OVF: CBI PORTD,3 CBI PORTD,6 RETI ; End Interrupts ==========================================
Почему я в этих обработчиках не сохраняю регистры и SREG? А незачем! Команды SBI меняют только конкретные биты (а больше нам и не надо), не влияя на флаги и другие регистры.
Запустили…
И получили полную херню. Т.е. ШИМ как бы есть, но почему то адово мерцает. А на осциллографе в этот момент полный треш. Кто виноват? Видимо конфликт прерываний. Осталось только выяснить где именно. Сейчас я вам дам практический пример реалтаймовой отладки 🙂
Итак, что мы имеем:
ШИМ, как таковой, работает. Скважность меняется. Значит наш алгоритм верен.
Но длительности скачут. Почему? Видимо потому, что что-то мешает им встать вовремя. Когда у нас возникают фронты? Правильно — по прерываниям. А прерывания по таймерам. Т.е. врать не должны. Однако так получается. Давайте узнаем каком месте у нас конфликт.
Первым делом надо добавить в код обработчика отладочную инфу. Будем в обработчике прерываний инвертировать бит. Пусть это будет PD7 — зашли в обработчик, инверснули. Зашли — инверснули. В результате, у нас на выходе этого бита будет прямоугольный сигнал, где каждый фронт — сработка прерываний. Послужит нам как линейка, отмеряющая время.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | ; Interrupts ============================================== Timer0_OV: PUSHF PUSH R17 PUSH R18 PUSH R19 INCM TCNT POP R19 POP R18 POP R17 POPF RETI ; Установка бита ШИМ канала А Timer1_OCA: SBI PORTD,3 RETI ; Установка бита ШИМ канала Б Timer1_OCB: SBI PORTD,6 RETI ;Сброс бита ШИМ канала А и Б Timer1_OVF: CBI PORTD,3 CBI PORTD,6 ;DEBUG PIN BEGIN --------------- PUSHF INVBM PORTD,7 POPF ;DEBUG PIN END ----------------- RETI |
; Interrupts ============================================== Timer0_OV: PUSHF PUSH R17 PUSH R18 PUSH R19 INCM TCNT POP R19 POP R18 POP R17 POPF RETI ; Установка бита ШИМ канала А Timer1_OCA: SBI PORTD,3 RETI ; Установка бита ШИМ канала Б Timer1_OCB: SBI PORTD,6 RETI ;Сброс бита ШИМ канала А и Б Timer1_OVF: CBI PORTD,3 CBI PORTD,6 ;DEBUG PIN BEGIN ————— PUSHF INVBM PORTD,7 POPF ;DEBUG PIN END —————— RETI
Инверсия бита невозможна без логических операций, поэтому надо сохранять флаги.
Из картинки стало понятно, что у нас накрывается прерывание по сравнению. Давайте попробуем посмотреть с какими прерыванием происходит конфликт. Особых вариантов у нас нет — прерываний у нас тут четрые. А наиболее очевиден конфликт Timer0_OV vs Timer1_OCA vs Timer1_OCB.
OCA и OCB конфликтуют только тогда, когда счетные регистры у них сравниваются — вызов происходит почти одновременно, но сами обработчики короткие — всего несколько тактов, поэтому дребезг не столь сильный.
А вот Timer0_OV делает довольно мощный прогруз стека и еще вычитает четырехбайтную переменную. Т.е. тактов на 20 может задержать обработчик установки бита Timer1_OC* от того и вылазят такие зверские дребезги.
Давайте проверим эту идею. Разрешим прерывания в обработчике Timer0_0V
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | ; Interrupts ============================================== Timer0_OV: SEI PUSHF PUSH R17 PUSH R18 PUSH R19 INCM TCNT POP R19 POP R18 POP R17 POPF RETI ; Установка бита ШИМ канала А Timer1_OCA: SBI PORTD,3 RETI ; Установка бита ШИМ канала Б Timer1_OCB: SBI PORTD,6 RETI ;Сброс бита ШИМ канала А и Б Timer1_OVF: CBI PORTD,3 CBI PORTD,6 RETI |
; Interrupts ============================================== Timer0_OV: SEI PUSHF PUSH R17 PUSH R18 PUSH R19 INCM TCNT POP R19 POP R18 POP R17 POPF RETI ; Установка бита ШИМ канала А Timer1_OCA: SBI PORTD,3 RETI ; Установка бита ШИМ канала Б Timer1_OCB: SBI PORTD,6 RETI ;Сброс бита ШИМ канала А и Б Timer1_OVF: CBI PORTD,3 CBI PORTD,6 RETI
Картина сразу исправилась. Теперь более важное (для нас важное) прерывание задвигает обработчик от Таймера 0. Но тут надо просекать возможные риски:
.
ШИМ на таймерах
Когда совсем все плохо, то можно сделать на любом таймере. В обработчик прерывания по переполнению таймера заносим конечный автомат, который сначала загрузит в таймер длительность низкого уровня, а при следующем заходе — длительность высокого. Ну и, само собой, ноги процессора подергает как надо. Таким образом, на один таймер можно повесить дофига ШИМ каналов, но задолбаешься все с кодовой реализацией всего этого. И процессорное время жрать будет некисло. Не говоря уже про дребезги, о которых только что было сказано. Это для эстетов извращенцев :)))))
Исходник к статье
easyelectronics.ru