Привет Хабру и всем его многочисленным обитателям! Сразу оговорюсь, то, о чем мы здесь поговорим, на самом деле не предназначено для новичков, однако, если у вас есть интерес и желание учиться, наоборот, прошу вас разобраться.
И на этот раз речь пойдет о реализации гибридного ШИМ, которых уже немало в сети.
Так что я думаю еще один, или два, или три (бонусом), лишним не будет или не будет лишним.
Итак, ну, во-первых, почему он гибридный: в первую очередь потому, что это не 100% аппаратное обеспечение, но и не 100% программное обеспечение.
Что бы это значило: для реализации используется аппаратный счетчик, но вывод формируется не в один канал порта ввода-вывода, а сразу в три, с использованием маски конфигурации, которая маскирует каналы порта в прерывании таймера.
Чем он отличается от аппаратного? Да все просто — количество каналов для микроконтроллера Attiny13a. Теперь более подробно.
Кому это нужно и зачем?! Ну а основная область применения таких задач - управление двигателями - асинхронными, биполярными и униполярно - шаговыми, контроллерами световых и звуковых эффектов, ультразвуковыми устройствами (ультразвуковые ванны, граверы, миксеры и т.д.) и т.д. конечно для таких целей созданы специализированные контроллеры, но зачем искать, тратить деньги и копать ДС, если под рукой есть маленький питомец.
На первом вопросе я остановился, когда вдруг появился к нему интерес, читая один из форумов, где один разработчик (назовём его «Опечаленный») был опечален тем фактом, что микроконтроллер Attiny13a, не имея достаточного количества аппаратных ШИМ-каналов , не может похвастаться необходимой производительностью для программной реализации задуманного.
«Опечаленный» перепробовал множество вариантов, менял константы, оптимизировал C-код, даже использовал прерывания, но всё тщетно.
А поднятая им на форуме тема в какой-то лохматый год скисла, оставшись нерешённой и без ответа.
Меня интересовало, насколько медленным является программный режим ШИМ у упомянутого микроконтроллера, работающего на частоте 9,6 МГц.
И я, набросав небольшой исходник, используя по возможности все аспекты, описанные в "Опечаленном" и реализовав их, потихоньку встал на три лапы Тиника 13-го программного ШИМ, на частоте.
около 4 кГц, с программной эмуляцией в Proteus. Мало.
Слишком мало! И как-то это все странно.
но невероятно интересно, ведь если не одолеть такую простую задачу, то это действительно одно из первых, маленьких разочарований, и прямая дорога к более производительным и навороченным чипам, стоимость которых соответственно.
С другой стороны, это скорее плюс, но мы еще разберемся.
И тогда я подумал: «А почему, собственно, синхронизация происходит по переполнению таймера, когда задача реализуется через сравнения?!» Действительно, в режиме переполнения таймер просто должен вызвать прерывание только один раз, при его переполнении, после прохождения полного цикла.
Немного модифицировав исходник, я получил около 40 кГц.
«Лучше, но все равно здесь что-то не так!» В общем, больше не буду вас утомлять: все переменные объявлены в регистрах, код оптимизирован по производительности, и размера (почти все исчезло), а при дальнейших играх получилось еще два режима с относительными сдвигами импульсов.
А потом последовали новые оптимизации, в результате которых самый медленный из режимов (6 фаз) был переписан на встроенный ассемблер.
И сделано это случайно, когда я обратил внимание на код, полученный после компиляции, что меня, мягко говоря, сильно удивило! Даже при объявлении переменных в регистрах компилятор решил все операции делать через временные пары, поэтому размер кода увеличился почти вдвое, и это при включенной оптимизации размера! Несколько дополнительных ходов и выигрыш в 40 байт от первого варианта, и прирост частоты почти на 10 кГц.
В результате получилось три режима:
1. Сдвинутые по фазе импульсы, максимально доступная частота 75,500 кГц при CLK=9,6 МГц (При CLK=20 МГц частота близка к 160 кГц), коэффициент заполнения ШИМ=33,3% периода - три фазы:
2. Импульсы сдвинуты на треть, максимальная частота 37,400 кГц (75 кГц при CLK=20 МГц), скважность=50%, период - шесть фаз (без использования ассемблера преодолеть предел в 28 кГц не удалось, подробнее см.
исходный код):
3. Импульсы сдвинуты вдвое, максимальная частота такая же, как и в первом режиме, скважность = 66,6%, период - три фазы:
Под частотой здесь подразумевается полная последовательность импульсов по трем каналам до повторения за период (или период одного импульса).
Да, должен заметить, что изменение скважности не входило в объем данной задачи, хотя это очень легко сделать с помощью второго регистра сравнения таймеров (правда, это справедливо только для первого режима).
В данном случае изменение частоты реализовано, и осуществляется за счет изменения ширины фазы (подробнее в тексте исходника).
Зачем так много режимов? Это еще не все, и все их множество обусловлено особенностями тех или иных устройств.
Так, например, асинхронные двигатели управляются по первому режиму, а униполярные шаговые – по второму (правда, каналов для них нужно или меньше, или больше, но если у вас есть пример, то расширение или уменьшение количества каналов – это мелочь).
Чтобы получить более низкую частоту программным путем, необходимо изменить регистр делителя таймера.
Если это слишком много (например для шаговых двигателей), нужно снизить частоту микроконтроллера.
Так, при частоте чипа 128 кГц, с установленным делителем CLK, без таймерного делителя и минимальной шириной импульса (максимальной частотой) при использовании второго режима частота импульсов составляет 62 Гц.
Если говорить об управлении асинхронным двигателем, то при использовании двигателя с 12 полями мы получаем максимальную частоту следования импульсов при использовании первого режима около 20 кГц (~78/4), что, несомненно, столько же, поскольку отсутствие двигателей, способных вращаться на таких оборотах (в секунду).
:о) Конечно, приведенные выше расчеты не отражают накладных затрат, которые требует полноценное управление, таких как считывание с датчиков Холла или обратной ЭДС, регулировка длительности фаз и т.п.
Но при таком запасе по частотам эти проблемы решаются легко, прямо в Основной цикл программы.
Отдельно прошу прощения у гуру, нервничающих по поводу однострочных условий, но здесь это сделано намеренно для удобства быстрого комментирования.
Вторая, более прозаичная причина: я ненавижу /*комментарии со звездочками*/, хотя при переключении на встроенный другой вариант не предоставляется.
Если вы собираетесь использовать мой код в своем проекте, то когда он начнет раздуваться и обрастать вашими обработчиками, вам необходимо снабдить все объявления используемых переменных в регистрах ключевым словом «летучий», в результате чего компилятор будет щелкать что ему плевать на ваши запросы, и что если он захочет, то будет использовать эти регистры по своему усмотрению (если их будет недостаточно).
Более подробную информацию я постарался максимально полно отразить в комментариях, при этом стараясь быть максимально кратким при кодировании:
Буду рад ответить на ваши вопросы и помочь с изменением конфигурации сигнала, если конечно это потребуется.
При всем вышесказанном хочу отметить: я не позиционирую себя как супероптимизатор, суперпрограммист и суперэлектронщик.
Все сказанное я написал для того, чтобы новички поверили, что непобедимых задач не существует, а профессионалы обратили внимание на фишки, которые рано списывать со счетов, и они могут найти достойное применение во многих классах задач.
PS: Для новичков: ИМХО, проект недостаточно интересен новичкам, из-за использования высоких частот. Однако контроллер прошит прошивкой с незакомментированной строкой в основном контуре для изменения ширины фазы, на частоте 4,8 МГц с включенным делителем частоты (4,8/8) (только не помню до оптимизации кода или после ), а с подключенными светодиодами по линиям PB0, PB1, PB2 выглядит забавно, как настольная мигалка.
Хотя некоторые особо нервные личности утверждают, что «эта чушь меня раздражает до глубины души».
:) PPS: Для НЕ новичков: дополнительно хотелось бы сказать про оптимизацию и использование (без холивара, друзья!) такого кода:
Теги: #attiny13a #Atmel #Программирование микроконтроллеров #C++byte
-
Продажи Нового Ipad Начнутся В России 25 Мая
19 Oct, 24 -
Навигатор Проекта Для Visual Studio
19 Oct, 24 -
9 Сентября День Тестировщика
19 Oct, 24 -
Kbtrainer: Chrome, Firefox, Hta
19 Oct, 24 -
Как Я Запускал Афишу Еврейских Мероприятий
19 Oct, 24