Выходная частота ШИМ

8

После многих часов бесполезного поиска и чтения у меня все еще не было полного понимания того, как и зачем выводить конкретные частоты из аппаратного ШИМ-контакта на RPi, не используя чужой «черный ящик».

Кажется, что есть довольно много неточной или неполной информации о специфике, а также о различных используемых терминах - «делитель тактового сигнала», «рабочий цикл», «диапазон ШИМ» и сами данные ШИМ, и как они все связаны вместе, чтобы вывести определенную частоту - в моем случае, чтобы вывести определенные звуковые частоты из пьезоанализатора.

Нил
источник

Ответы:

14

Я наконец получил полное (ish) понимание из заголовочного файла драйвера bcm2835.h, поэтому подумал, что я опубликую и отвечу на свой вопрос для других.

Соответствующие биты из заголовка:

PWM

BCM2835 поддерживает аппаратный ШИМ для ограниченного набора выводов GPIO. Эта библиотека bcm2835 предоставляет функции для настройки и управления выходом ШИМ на этих выводах.

BCM2835 содержит 2 независимых канала ШИМ (0 и 1), каждый из которых должен быть подключен к ограниченному подмножеству выводов GPIO. Следующие выводы GPIO могут быть подключены к следующим каналам ШИМ:

  GPIO PIN    RPi pin  PWM Channel    ALT FUN
  12                    0             0
  13                    1             0
  18          1-12      0             5
  19                    1             5
  40                    0             0
  41                    1             0
  45                    1             0
  52                    0             1
  53                    1             1

Чтобы вывод GPIO испускал выход из своего канала ШИМ, он должен быть настроен на функцию Alt, указанную выше. Обратите внимание, что в текущих версиях Raspberry Pi имеется только один из этих контактов (GPIO 18 = RPi Pin 1-12) на заголовках ввода-вывода, и, следовательно, это единственный вывод ввода-вывода на RPi, который можно использовать для ШИМ. Кроме того, он должен быть установлен на ALT FUN 5 для получения выхода ШИМ.

Оба канала ШИМ управляются одним и тем же тактовым сигналом ШИМ, чей регулятор частоты может быть изменен с помощью bcm2835_pwm_set_clock(). Каждый канал может быть включен отдельно bcm2835_pwm_set_mode(). Средний выходной сигнал канала ШИМ определяется отношением DATA / RANGE для этого канала. Используйте, bcm2835_pwm_set_range()чтобы установить диапазон и bcm2835_pwm_set_data()установить данные в этом соотношении

Каждый канал ШИМ может работать в сбалансированном режиме или в режиме Mark-Space. В сбалансированном режиме аппаратное обеспечение отправляет комбинацию тактовых импульсов, что приводит к общим импульсам DATA на импульсы RANGE. В режиме Mark-Space аппаратное обеспечение устанавливает выход ВЫСОКИЙ для широких тактовых импульсов DATA, а затем LOW для тактовых импульсов RANGE-DATA.

Часы PWM могут быть установлены для управления длительностью импульсов PWM. Часы PWM получены из тактовой частоты 19,2 МГц. Вы можете установить любой разделитель, но некоторые общиеbcm2835PWMClockDivider

Например, предположим, что вы хотите управлять двигателем постоянного тока с ШИМ на частоте около 1 кГц и управлять скоростью с шагом 1/1024 от 0/1024 (остановлено) до 1024/1024 (полное включение). В этом случае вы можете установить делитель тактовой частоты равным 16, а ДИАПАЗОН - 1024. Частота повторения импульсов будет 1,2 МГц / 1024 = 1171,875 Гц.

bcm2835PWMClockDividerОпределяет делитель, используемый для генерации тактового сигнала ШИМ из системных тактовых импульсов. На рисунках ниже приведены делитель, такт и тактовая частота. Разделение тактовых импульсов основано на номинальной тактовой частоте ШИМ 19,2 МГц. Показанные частоты для каждого делителя были подтверждены измерениями

typedef enum
{
    BCM2835_PWM_CLOCK_DIVIDER_2048  = 2048,    /*!< 2048 = 9.375kHz */
    BCM2835_PWM_CLOCK_DIVIDER_1024  = 1024,    /*!< 1024 = 18.75kHz */
    BCM2835_PWM_CLOCK_DIVIDER_512   = 512,     /*!< 512 = 37.5kHz */
    BCM2835_PWM_CLOCK_DIVIDER_256   = 256,     /*!< 256 = 75kHz */
    BCM2835_PWM_CLOCK_DIVIDER_128   = 128,     /*!< 128 = 150kHz */
    BCM2835_PWM_CLOCK_DIVIDER_64    = 64,      /*!< 64 = 300kHz */
    BCM2835_PWM_CLOCK_DIVIDER_32    = 32,      /*!< 32 = 600.0kHz */
    BCM2835_PWM_CLOCK_DIVIDER_16    = 16,      /*!< 16 = 1.2MHz */
    BCM2835_PWM_CLOCK_DIVIDER_8     = 8,       /*!< 8 = 2.4MHz */
    BCM2835_PWM_CLOCK_DIVIDER_4     = 4,       /*!< 4 = 4.8MHz */
    BCM2835_PWM_CLOCK_DIVIDER_2     = 2,       /*!< 2 = 9.6MHz, fastest you can get */
    BCM2835_PWM_CLOCK_DIVIDER_1     = 1        /*!< 1 = 4.6875kHz, same as divider 4096 */
} bcm2835PWMClockDivider;

В итоге:

  1. Если вам нужен аппаратный ШИМ - вы застряли с контактом 12 (BCM18), другие контакты GPIO будут использовать программный ШИМ.

  2. Вам, вероятно, потребуется установить режим ШИМ в режим «Mark-Space» для большинства случаев использования и соображений здравого смысла, как описано выше.

  3. В этом режиме длительность каждого «импульса» HIGH vs LOW определяется отношением данных ШИМ к диапазону ШИМ - это не зависит от тактовой частоты ШИМ.

  4. Диапазон ШИМ - это фактически «разрешение» или число возможных «делений» каждого импульса. Чем больше делений, тем выше разрешение и, следовательно, больше состояний, кодируемых для данной ширины импульса.

  5. «Рабочий цикл» - это отношение данных ШИМ к диапазону ШИМ, выраженное в процентах. Диапазон ШИМ 10 с данными ШИМ 8 является рабочим циклом 80%.

  6. Тактовая частота ШИМ - это степень двух делителей. Таким образом, выбранная вами тактовая частота для ШИМ должна быть равной divisor & (divisor -1) == 0Хотя 12 действительных значений перечислены выше.

  7. Деление тактовой частоты ШИМ на требуемую выходную частоту дает значение диапазона импульсов.

  8. Поскольку я кодировал звук и использовал пьезоэхолот, мне требовался рабочий цикл 50%, чтобы максимизировать пьезо-колебания и, следовательно, громкость. Поэтому значение данных ШИМ всегда равно половине значения диапазона ШИМ - 50% ВЫСОКИЙ 50% НИЗКИЙ.

Чтобы рассчитать требуемую частоту, выберите делитель тактовых импульсов, который имеет смысл для вашего приложения - я выбрал 16, что соответствует 1,2 МГц. Так:

Нота A составляет 440 Гц, F # - 370 Гц, C # - 277 Гц

PWMClock = 16; // 1.2Mhz

const A4_RANGE = 1.2e6 / 440;  // 1.2Mhz/440Hz
A4Data = A4_RANGE / 2;

const F4S_RANGE = 1.2e6 / 370;  // 1.2Mhz/370Hz
F4SData = F4S_RANGE / 2;

const C4S_RANGE = 1.2e6 / 277;  // 1.2Mhz/277Hz
C4SData = C4S_RANGE / 2;

Вы можете легко сместить диапазон ШИМ вверх и вниз на октаву кратно - диапазон * 2 опустит его на октаву, диапазон * 0.5 возьмет на единицу.

Если вы хотите управлять сервоприводом, скажем, с частотой 50 Гц, то же самое вычисление диапазона справедливо:

PWM Range = PWM frequency / Desired Output Frequency

(Максимальное значение диапазона ШИМ согласно некоторым постам в отдельных случаях равно 4096 - по моему опыту, это не так, поскольку игра на C #, как указано выше, дает диапазон ШИМ 4332, который работает, как и ожидалось.)

Как и большинство вещей - это легко, когда ты умеешь.

~ N

Нил
источник
3
Обратите внимание, что бит «только 12-контактный» относится к 26-контактным моделям. В 40-контактных моделях есть еще три (13, 18 и 19), но все еще есть только 2 канала синхронизации, и контакты имеют аппаратную связь с одним или другим (контакты 12 и 18 - это канал 0, 13 и 19 - это канал 1); согласно документам, приведенным выше, libbcm2835 позволит вам настроить оба канала и все четыре контакта. Функции ALT для этого отличаются для каждого контакта; здесь есть таблица, большая часть которой взята непосредственно из таблицы Broadcom SoC. Вычеркнутые записи только на 40-контактных моделях.
Златовласка
7

На последних Pis (те, которые имеют 40-контактный расширенный заголовок и вычислительный модуль), GPIO 12/13/18/19 может использоваться для обеспечения аппаратных сигналов ШИМ.

Источником тактовой частоты ШИМ не обязательно должен быть кристалл 19,2 МГц, а PigPio использует 500 МГц PLLD.

Для простого метода командной строки установки аппаратной частоты ШИМ см. Http://abyz.me.uk/rpi/pigpio/pigs.html#HP

Джоан
источник