Почему у некоторых штырей разная частота PWM?

В соответствии с ссылкой Arduino для analogWrite() , частота ШИМ на большинстве контактов ~ 490 Гц. Тем не менее, он составляет ~ 980 Гц для контактов 5 и 6 на Uno, а для контактов 3 и 11 на Leonardo.

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

17 голосов | спросил Peter Bloomfield 14 FebruaryEurope/MoscowbFri, 14 Feb 2014 19:08:09 +0400000000pmFri, 14 Feb 2014 19:08:09 +040014 2014, 19:08:09

2 ответа


22

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

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

  • Штыри 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, но вы все равно получаете идею. Я читаю данные, чтобы попытаться выяснить, что правильно, или это разница между советами.

ответил Ricardo 14 FebruaryEurope/MoscowbFri, 14 Feb 2014 20:00:19 +0400000000pmFri, 14 Feb 2014 20:00:19 +040014 2014, 20:00:19
8

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

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

$$ \ text {prescaler} = \ dfrac {f_ {CPU}} {PWMresolution Ã-f_ {PWM}} = \ dfrac {16 \ text {MHz}} {256Ã-490} \ approx 128 $$

  

prescaler = f [CPU] /(PWMresolutionÃ-f [PWM]) = 16000000 /(256Ã-490) = приблизительно 128.

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

ответил jippie 14 FebruaryEurope/MoscowbFri, 14 Feb 2014 19:57:57 +0400000000pmFri, 14 Feb 2014 19:57:57 +040014 2014, 19:57:57

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132