Аппаратное управление частотой ШИМ

21

Я использую аппаратный выход ШИМ с Wiringpi. Он предоставляет функцию pwmSetClock, которая должна позволять изменять частоту. ( https://projects.drogon.net/raspberry-pi/wiringpi/functions/ ). Я полагаю, поскольку по умолчанию 200 МГц, установка делителя на 200000000 должна сделать видимое подключение светодиода к выходной вспышке, но это не так.

Можно ли это изменить?

user1217949
источник
1
Я провожу некоторые тесты с аппаратным ШИМ, и у него, похоже, нет частоты fiexd. Он варьировался в зависимости от ширины импульса, установленной в pwmWrite(). Не то, что я ожидал бы случиться
TheMeaningfulEngineer

Ответы:

25

Недавно у меня была причина начать эксперименты с ШИМ, и я обнаружил, что (как указано в одном из комментариев) частота, похоже, меняется в зависимости от рабочего цикла - bizzare, верно? Оказывается, Broadcom внедрил «сбалансированный» ШИМ для того, чтобы импульсы включения и выключения были максимально равномерно распределены. Они дают описание алгоритма и некоторые другие обсуждения на странице 139 их таблицы данных: http://www.element14.com/community/servlet/JiveServlet/downloadBody/43016-102-1-231518/Broadcom.Datasheet.pdf

Так что вы действительно хотите перевести ШИМ в режим mark-space, что даст вам традиционный (и легко предсказуемый) PWM, который вы ищете:

pwmSetMode(PWM_MODE_MS);

Остальная часть ответа предполагает, что мы находимся в режиме пробела.

Я также провел некоторые эксперименты с допустимым диапазоном значений для pwmSetClock() и pwmSetRange(). Как отмечалось в одном из других ответов, допустимый диапазон значений составляет pwmSetClock()от 2 до 4095, а допустимый диапазон pwmSetRange()- до 4096 (я не пытался найти нижний предел).

Диапазон и тактовая частота (лучшее название, вероятно, делитель) влияют на частоту. Диапазон также влияет на разрешение, поэтому, хотя возможно использование очень низких значений, существует практический предел того, насколько низким вы, вероятно, захотите пойти. Например, если вы используете диапазон 4, вы можете достичь более высоких частот, но вы сможете установить только коэффициент заполнения 0/4, 1/4, 2/4, 3/4 или 4/4.

Часы Raspberry Pi PWM имеют базовую частоту 19,2 МГц. Эта частота делится на аргументpwmSetClock() , является частотой, на которой увеличивается счетчик ШИМ. Когда счетчик достигает значения, равного указанному диапазону, он сбрасывается в ноль. Пока счетчик меньше указанного рабочего цикла, выходной сигнал высокий, в противном случае выходной сигнал низкий.

Это означает, что если вы хотите настроить ШИМ на определенную частоту, вы можете использовать следующее соотношение:

pwmFrequency in Hz = 19.2e6 Hz / pwmClock / pwmRange.

Если вы используете максимально допустимые значения для pwmSetClock()и pwmSetRange(), вы получите минимально достижимую аппаратную частоту ШИМ ~ 1,14 Гц. Это, безусловно, даст видимое мерцание (на самом деле больше вспышки) светодиода. Я подтвердил вышеупомянутое уравнение с помощью осциллографа, и, похоже, оно верно. На верхний предел частоты будет влиять необходимое разрешение, как описано выше.

Керри
источник
Что касается нижней границы pwmRange: я успешно установил ее на 2 (чтобы получить коэффициент заполнения 50%).
Тед Пудлик
Из какого источника вы знаете, что частота на часах ШИМ равна 19,2 МГц?
Thi
10

По этой формуле:

pwmFrequency in Hz = 19.2e6 Hz / pwmClock / pwmRange

Мы можем установить pwmClock=1920и pwmRange=200получить pwmFrequency=50Hz:

50 Hz = 19.2e6 Hz / 1920 / 200

Я проверяю это на Alarmpi:

$ pacman -S wiringpi
$ gpio mode 1 pwm
$ gpio pwm-ms
$ gpio pwmc 1920
$ gpio pwmr 200     # 0.1 ms per unit
$ gpio pwm 1 15     # 1.5 ms (0º)
$ gpio pwm 1 20     # 2.0 ms (+90º)
$ gpio pwm 1 10     # 1.0 ms (-90º)

Примечание. Мой сервопривод ожидает сигнал 50 Гц .

кэв
источник
как вы пришли к: «gpio pwmr 200 # 0,1 мс на единицу»
mxlian
50 Гц ---> 20 мс за цикл. 20 мс / 200 единиц = 0,1 мс на единицу
mxlian
5

Это код, который я использую. Я пытаюсь увидеть, что изменится при изменении настроек.

#include <wiringPi.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

int main (void)
{
  printf ("Raspberry Pi wiringPi test program\n") ;

  if (wiringPiSetupGpio() == -1)
    exit (1) ;

  pinMode(18,PWM_OUTPUT);
  pwmSetClock(2);
  pwmSetRange (10) ;
  pwmWrite (18, 5);

for (;;) delay (1000) ;
}

pwmSetClock (1); -> 2,342 кГц

pwmSetClock (2); -> 4,81 МГц

pwmSetClock (3); -> 3,19 МГц

pwmSetClock (4); -> 2,398 МГц

pwmSetClock (5); -> 1,919 МГц

pwmSetClock (6); -> 1,6 МГц

pwmSetClock (7); -> 1,3 МГц

pwmSetClock (8); -> 1,2 МГц

pwmSetClock (9); -> 1,067 МГц

pwmSetClock (10); -> 959 кГц

pwmSetClock (11); -> 871 кГц

pwmSetClock (20); -> 480 кГц

pwmSetClock (200); -> 48 кГц

pwmSetClock (500); -> 19 кГц

pwmSetClock (1000); -> 9,59 кГц

pwmSetClock (2000); -> 4.802 кГц

pwmSetClock (4000); -> 2,401 кГц

pwmSetClock (5000); -> 10,58 кГц

Из того, что я проверил, кажется, что делитель идет от 2 до некоторого числа меньше 5000. Я думаю, что это как-то связано с двоичным представлением тех чисел, которые прямо устанавливаются в регистре. Как только двоичное представление чисел имеет больше битов, чем может принять регистр, оно просто берет первые биты и интерпретирует числа таким образом. Вот почему странное поведение происходит при переходе от 4000 до 5000.

TheMeaningfulEngineer
источник
1
Как бы я изменил рабочий цикл?
Ноуфал
Как вы измерили частоты?
Seanny123