Всем привет решил сделать статью про ШИМ. А точнее как я вижу эту особенность плат ардуино. Оригинал статьи я выложил здесь: http://vk.com/topic-110073626_33287380 . ШИМ, представляет собой получения аналогового значения, посредством цифровых комманд(0 или 1). Как это работает? Всем известно, что мы можем подавать на цифровые пины Arduino 1 или 0. Если мы подключим светодиод к 13 пину и введем известную команду: digitalWrite(13, 1); то мы отправим на пин логическую единицу(5v), и светодиод сразу-же загорится. А если мы введем другую команду: digitalWrite(13, 0); то мы отправим на 13 пин логический 0(все что меньше ~2v), то светодиод перестанет гореть. А теперь давайте побезумствуем, я приведу код, а вы попробуйте поэкспериментировать со временем timeshim и timeshim2: int timeshim = 1; int timeshim2 = 10; void setup() { pinMode(13, OUTPUT); } void loop() { digitalWrite(13, 1); delay(timeshim); digitalWrite(13, 0); delay(timeshim2); } В данном эксперименте мы видим, как меняется яркость светодиода, в зависимости от времени включенного и выключенного состояния. Если вы экспериментировали с кодом, то возможно поняли, что что-бы точно управлять яркостью светодиода, миллисекунд недостаточно. А это значит, что для управления яркостью нужны микросекунды. В общем не влезая в дебри - замучеешся подбирать время для яркости. Тут нужно что-то полегче. Для того что-бы не запариваться со временем, вспомним информатику: В 1-м байте 8 бит, а если перебирать каждый бит, то это получиться 256 различных комбинаций(0-255). По сути отправляя по одному байту, мы задаем нужный шим сигнал на пине. Делается это с помощью функции: analogWrite(13, 0); 0, в данном случае - это такой байт(00000000). А если мы заместо 0 поставим 1, то это будет не логическая 1, а вторая комбинация байта(00000001). Если мы введем: analogWrite(13, 128); то вы правильно поняли - это 128-я комбинация байта(10000000), равная 50% мощности. Ну а если напишем: analogWrite(13, 255); , то получим байт(11111111) и 100% мощности. Вот как-бы и все, что хотел рассказать. Если я что-то не правильно преподнес, то скажите где я ошибся. Исправлю. Заранее спасибо! С Уважением, Mestniy
отнюдь. Скважность - независимое от шим понятие и появилось задолго до шим. Счастье ознакомиться с определением термина "скважность" я оставляю вам самим. как-то нечетко. Миллисекунд достаточно, если речь о периоде шим. Вы же неявно подразумевали не период шим (а именно это время первым приходит в голову), а период тика таймера? Ну и резюме?
Согласен я плохо умею формулировать мысли. Можете подсказать что именно и на что изменить? Если дело, только в формулировках, то все лучше чем я думал)
как контролер контролирует шим? он что постоянно дергает ногу, если так, то теряется мощность контроллера.
для этого контроллер и нужен. На самом деле, если не заставлять контроллер выполнять FFT, то ему мощности на все хватит. "дернуть ногу"- это такт, плюс поп-пуш пятка регистров при выполнении прерывания по таймеру- меньше микросекунды. А микросекунд в секунде - миллион.
ШИМ реализован на аппаратном уровне. Могу ошибаться (на практике не пробовал, только в теории), но если правильно всё настроить, то ресурсы контроллера -- его производительность -- для генерации ШИМ использоваться не будут. Т.е. прошивка будет работать без каких-либо задержек. Или под "мощностью" что-то другое подразумевалось?
для одного таймера определена только одна нога, которая может управляться функцией таймера как периферии. Все остальные ноги pwm ардуины (а может и та) управляются программно, т.е. задействуя мощность контроллера. Но это уходит целая одна миллионная мощности контроллера* частоту шим. Т.е. реально в ардуине 0.05% мощности мк уходин на дерганье ноги.
У ATmega328 три таймера по две ноги на каждом -- итого 6 аппаратных ШИМ, но опять же всё зависит от конкретной конфигурации (настройки соответствующих регистров). Можно сделать так, что у каждой пары период будет один (т.к. у каждого таймера один источник тактов и период у пары пинов всегда будет одинаковый), а скважность будет разная -- у каждого таймера два регистра "сравнения" (по регистру на ногу). И в теории, если замаскировать прерывания типа 'TIMERx COMPn', то микроконтроллер не должен "отвлекаться" на генерацию ШИМ на этих 6ти пинах. Вполне возможно, что дополнительно придётся маскировать прерывания, которые отслеживают изменения состояния пинов (PCINTx).
но matchA и matchB в мк не независимы, так как при matchx регистр таймера сбрасывается в прерывании. Я использую оба прерывания, по A и B, но не одновременно же! Проще сделать так, как сделано в самой ардуине- повесить сколько угодно шимов на один таймер, у меня так сделаны 8 канальные (можно и больше каналов делать, но пока не было ситуации когда нужно) led и симисторные диммеры - по прерыванию лишь инкрементируется счетчик и значение счетчика сравнивается со значением "яркости" (0-255) каждого выхода, и выставляется соответсвующая нога в 0 или 1. И обработка такого прерывания занимает пару- тройку микросекунд, что вкупе составляет десятые доли % машинного времени. Есть о чем говорить? Не о чем говорить!
Не знаю про какой тип Arduino Вы говорите, но те Arduino что на базе ATmega328 используют все три таймера (наверно заметили значёк ~ на шести пинах -- это и есть те самые пины, которые управляются таймерами и заодно взгляните на код функции 'ananlogWrite()' из комплекта Arduino IDE). Я понимаю, что производительность затрачивается минимальная -- можно в большинстве случаев пренебречь. Но здесь вопрос, как бы правильно сказать, "профессианализма" что-ли -- знаете ли Вы тонкости таймеров в контроллерах ATmega или нет?
И да, как уже говорил ранее -- ATmega328 может аппаратно генерировать 6 ШИМов -- прерывания не нужны. Особого влияния они не окажут, но я бы их замаскировал, так сказать в рамках "правил хорошего тона программирования".
Не претендую на знание тонкостей- сколько мне надо, столько и знаю. Я и в русском языке многих тонкостей не знаю, но думаю что знаю достаточно. А вот тонкостей ардуины я точно не знаю. Поскольку, например, The PWM outputs generated on pins 5 and 6 will have higher-than-expected duty cycles. This is because of interactions with the millis() and delay() functions, which share the same internal timer used to generate those PWM outputs. очень похоже, что вы правы. Значит я делаю не как в ардуине.
А вот на это стоит обратить особое внимание. Неоднократно сталкивался с вопросом (на этом форуме и других) -- как увеличить частоту ШИМ, а то писк нервирует -- и в ответах предлагают увеличить частоту тактовых импульсов для таймера №0. Что соответственно приведет к нарушению работы стандартной функции 'millis()' и других, зависящих от неё (та же 'delay()'). Тут надо с умом подходить...
Ничего более несуразного я не читал! Вы даже не удосужились почитать определение, что есть ШИМ. А пытаетесь статьи писать. Дальнейшую дискуссию считаю бесполезной, а потому отвечать в этой теме не стану.