Почему некоторые выводы имеют другую частоту ШИМ?

20

Согласно эталону ArduinoanalogWrite() , частота ШИМ на большинстве контактов составляет ~ 490 Гц. Тем не менее, это ~ 980 Гц для контактов 5 и 6 на Uno, и для контактов 3 и 11 на Leonardo.

Почему они разные? Это преднамеренная конструктивная особенность или это как-то продиктовано аппаратным обеспечением?

Питер Блумфилд
источник

Ответы:

23

Это не единственные частоты, доступные для сигналов ШИМ. Тем не менее, они являются частотами, определяемыми применяемым прескалером (который вы можете легко изменить, как описано ниже).

Каждая из 3 пар выводов ШИМ связана с одним таймером, каждый из которых имеет свою собственную базовую частоту, следующим образом:

  • Контакты 5 и 6 спарены на таймере 0 с базовой частотой 62500 Гц
  • Контакты 9 и 10 спарены на таймере 1, с базовой частотой 31250 Гц
  • Контакты 3 и 11 подключены к таймеру 2 с базовой частотой 31250 Гц

Затем каждый набор выводов имеет ряд значений предварительного масштабирования, которые можно выбрать, которые будут делить базовую частоту этой пары выводов. Доступны следующие значения прескалера:

  • Выводы 5 и 6 имеют значения предварительного масштабирования 1, 8, 64, 256 и 1024
  • Контакты 9 и 10 имеют предварительные значения 1, 8, 64, 256 и 1024.
  • Выводы 3 и 11 имеют значения предварительного масштабирования 1, 8, 32, 64, 128, 256 и 1024

Разные комбинации дают разные частоты в данном выводе ШИМ. Обратите внимание, что таймер 2 (привязанный к контактам 3 и 11) имеет больше доступных значений предварительного масштабирования, в результате чего доступно больше частот.

Теперь, почему таймер 2 отличается, это отдельный вопрос.

Изменить: Вот список возможных частот ШИМ на контакт (из этой статьи ):

Для контактов 6 и 5 (OC0A и OC0B):

  • Если TCCR0B = xxxxx001, частота равна 64 кГц.
  • Если TCCR0B = xxxxx010, частота равна 8 кГц.
  • Если TCCR0B = xxxxx011, частота составляет 1 кГц (это значение по умолчанию из загрузчика Diecimila)
  • Если TCCR0B = xxxxx100, частота 250 Гц
  • Если TCCR0B = xxxxx101, частота составляет 62,5 Гц

Для контактов 9, 10, 11 и 3 (OC1A, OC1B, OC2A, OC2B):

  • Если TCCRnB = xxxxx001, частота составляет 32 кГц
  • Если TCCRnB = xxxxx010, частота равна 4 кГц
  • Если TCCRnB = xxxxx011, частота равна 500 Гц (это значение по умолчанию из загрузчика Diecimila)
  • Если TCCRnB = xxxxx100, частота равна 125 Гц
  • Если TCCRnB = xxxxx101, частота составляет 31,25 Гц

TCCRnBгде вы устанавливаете биты предварительного масштабирования для таймера n, заменяя его nна 0, 1 или 2, в зависимости от таймера, который вы хотите установить. Если вы все еще не уверены в побитовых операциях, прочтите этот учебник по математике .

Мои источники:

Обратите внимание, что в этих источниках существует расхождение в отношении того, ведут ли контакты 9 и 10 то же поведение, что и 5 и 6 или 3 и 11, но вы все равно поймете это. Я читаю даташет, чтобы попытаться выяснить, что правильно, или это разница между досками.

Рикардо
источник
1
На что ATmega относится этот ответ? Я не проверял, но держу пари, он немного отличается для каждого контроллера.
Джиппи
@jippie Хорошая мысль! Источники ссылаются на ATmega168 и 328.
Рикардо
@jippie Просто чтобы уточнить, в моем ответе номера выводов относятся к тому, как они являются присваивающими на плате Uno (например, вывод 1 означает цифровой вывод 1 или D1), а не IC (вывод 1 ATmega328 сбрасывается).
Рикардо
1
Я верю, что эти детали тоже меняются с досками, Uno, Duemilanove, Mega, ...
Jippie
@jippie Определенно да.
Рикардо
8

Я не знаю о конструктивных соображениях, но если вы проверите таблицу данных для микроконтроллера на вашем Arduino, вы заметите, что выводы PWM сгруппированы и по каждой группе подключены к таймеру. Скорость, с которой увеличивается этот таймер, зависит от настроенного прескалера. Если вы меняете прескалер для определенного таймера, вы меняете частоту ШИМ для соответствующих выводов ШИМ. Я считаю, что некоторые таймеры удваиваются для других целей, таких как millis();функция. Если вы измените прескалер для этого таймера, значения, возвращаемые при millis()этом, будут отключены с тем же коэффициентом.

Вы можете рассчитать настройку прескалера следующим образом:

$$ \ text {prescaler} = \ dfrac {f_ {CPU}} {PWMresolution × f_ {PWM}} = \ dfrac {16 \ text {MHz}} {256 × 490} \ приблизительно 128 $$

prescaler = f [CPU] / (PWMresolution × f [PWM]) = 16000000 / (256 × 490) = около 128.

Проверьте таблицу данных, и вы увидите, что 128 действительно является одним из значений прескалера, которые вы можете выбрать.

jippie
источник
2
Мальчик, мы скучаем по MathJax или как? Надеюсь, мы включим его после бета-тестирования.
Рикардо
1
@Ricardo У меня в браузере есть кнопка MathJax; o) meta.arduino.stackexchange.com/questions/13/…
jippie