![]() |
![]() |
|||||||||||||||
Автомат световых эффектов на AtTiny2313.
Автор: GARMIN Так получилось, что до последнего времени я занимался «не микропроцессорной» электроникой. Но на нынешнем месте работы мне, к счастью, пришлось заниматься процессорами плотно. С программами, написанными на различных языках программирования, с различными структурами: AVR, ARM и т.д. Вполне возможно. Причём остаются ресурсы для дополнительных задач. Такой автомат понадобился для управления рекламными световыми табло, и было необходимо легко изменять как количество каналов, так и сами световые эффекты. Вначале это была простая программа с ШИМ модуляцией, но по мере увеличения количества каналов процессор просто не успевал отработать программу за период одного прерывания с требуемой частотой (32 кГц). Тогда я вместо ШИМ применил BAM модуляцию. Это упростило требования к процессору и теперь затраты времени на формирование ШИМ не зависят от количества каналов управления. Но я столкнулся с известным эффектом моргания при переходе уровня с 7F на 80, а также при переходе уровня менее значащих бит (3F – 40, 1F-20). Этот эффект устранён модификацией BAM. Из особенностей проекта отмечу следующее: Проект выполнен в среде CodeVisionAVR 2.05 и написан на С. Для того, чтобы можно было написать управляющую микропрограмму, использован интерпретатор команд. Причём возможно очень легко изменить его код при переходе с управления восемью каналами на шестнадцать или восемнадцать каналов, не изменяя остального кода программы. Интерпретатор короткий и понятный. Таким нехитрым способом возможно запрограммировать довольно сложную программу управления каналами, где могут одновременно использоваться как плавно зажигающиеся каналы, так и каналы с мгновенным включением – выключением. А также возможно оперативное управление скоростью изменения яркости каналов. flash unsigned char Rules [] = { Например, приведённая выше программка сначала 10 раз моргнёт каналом номер 1 с периодом в 1 секунду, затем 20 раз моргнет резко третьим каналом и плавно первым (первый канал разгорается и гаснет за 1 секунду), с периодом в 2 секунды. Затем каналы 1-4 плавно разгораются и гаснут в течение 5 секунд. После этого процесс повторяется сначала. Сам процесс программирования мне показался забавным, вот, например, команды управления бегущими огнями на три канала: flash unsigned char Rules [] = { Значение байта скорости изменения яркости можно вычислить следующим образом. Максимальная яркость канала 255. Изменение яркости 50 раз в секунду. Нам нужно полностью засветить канал например, за 2 секунды. Требуемое изменение яркости будет равно 255 / (50 * 2) = 2,55. Ближайшее большее целое будет 3. Яркость канала изменится от минимума до максимума за 255 / 3 = 85 тиков, или за 1,7 секунды. Теперь о BAM модуляции. Известный неприятный эффект перехода 7F-80 состоит в том, что при передаче уровня 7F светодиоды зажигаются весь первый полупериод модуляции, а при передаче уровня 80 – второй. Последовательная передача уровней 7F-80-7F-80 приводит к слиянию пауз и свечения, воспринимаемые глазом как кратковременные погасания и вспышки светодиода. Устранить этот эффект очень просто. Достаточно разбить период свечения старшего бита на несколько частей и воспроизводить его вперемешку с другими битами. У меня применена модификация BAM модуляции с четырнадцатью периодами вместо исходных девяти. Номера используемых битов следующие: 0, 1, 2, 3, 4, 6, 8, 7, 8, 5, 6, 8, 7, 8 Соответствующие им длительности интервалов BAM модуляции: 1, 1, 2, 4, 8, 16, 32, 32, 32, 16, 16, 32, 32, 32 Кстати, многие забывают о передаче паузы в 1 такт перед началом цикла модуляции. Без этого такта яркость свечения светодиодов не соответствуют весу битов. Для примера рассмотрим модуляцию всего двумя битами. Старший бит светится 2 такта, а младший – 1 такт. При передаче четырёх уровней без паузы уровни свечения будут: 0 0 = 0% Получается, что половина шкалы (10) соответствует 2/3 яркости, а это неправильно. А если добавить один пустой такт, то уровни свечения получатся правильными: 0 0 (0) = 0% Однако, при передаче максимального уровня светодиод светится только ¾ периода, а не весь. Это дилемма всех способов ШИМ модуляции. Дело в том, что 256 тактов ШИМ модуляции передают 257 возможных комбинаций с учётом всех погашенных и всех зажжённых тактов. Обычно не используют максимальный уровень яркости, так как не заметна разница между яркостью 255/256 и 256/256. Однако, для ключа управления такой режим не слишком хорош. Ведь он всё равно переключается с частотой ШИМ, и на ключе теряется энергия динамических потерь переключения, нагревая его. В данной программе уровень 255 подменяется на уровень 256, позволяя уменьшить потери на переключение при полностью зажженном светодиоде и уменьшая уровень излучаемых электромагнитных помех. Программа управления светодиодами работает по прерыванию и занимает всего 54 байта: interrupt [TIM0_COMPA] void timer0_compa_isr(void) Промежуточной программой между массивами уровней каналов и массивами битовых масок является программа преобразования. В массиве pPorts[] хранятся адреса переменных, выводимых в три порта процессора, а в массиве BitPorts[] хранятся битовые маски, соответствующие номерам выводов в нужном порту. Таким способом можно расписать произвольное количество ножек процессора под управление светодиодами. void MakeArrayPorts (void) Вот, собственно, и все премудрости. Весь архив проекта выкладываю в приложении. В проекте есть закомментированные остатки переменных для работы с большим количеством каналов, а также с кнопками изменения скорости работы. Ознакомьтесь и используйте. Если кому захочется запрограммировать интересный эффект, присылайте управляющий код и (или) видео работы.
Файлы: Все вопросы в Форум.
|
|
|||||||||||||||
![]() |
![]() |


![]() |
![]() |
|||
|
||||
![]() |
![]() |