Керуйте апаратною частотою ШІМ


21

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

Чи можна це змінити?


1
Я роблю тестування на апаратному PWM, і, схоже, це не частота fiexd. Він змінювався залежно від заданої ширини імпульсу pwmWrite(). Не те, що я б очікував, що трапиться
TheMeaningfulEngineer

Відповіді:


25

Нещодавно у мене були певні причини почати експериментувати з ШІМ, і я виявив, що (як вказував один із коментарів) частота, здається, змінюється в залежності від робочого циклу - Bizzare, правда? Виявляється, Broadcom реалізував "врівноважену" ШІМ, щоб зробити включені та вимкнені ШІМ імпульси максимально рівномірно розподіленими. Вони дають опис алгоритму та ще кілька обговорень на стор. 139 своєї таблиці даних: http://www.element14.com/community/servlet/JiveServlet/downloadBody/43016-102-1-231518/Broadcom.Datasheet.pdf

Тож, що ви дійсно хочете, це перевести ШІМ у режим пробілу знаків, що дасть вам традиційну (і легко передбачувану) ШІМ, яку ви шукаєте:

pwmSetMode(PWM_MODE_MS);

Решта відповіді передбачає, що ми перебуваємо в режимі пробілу розмітки.

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

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

Тактова частота PWM Raspberry Pi має базову частоту 19,2 МГц. Ця частота, поділена на аргумент до pwmSetClock(), є частотою, з якою збільшується лічильник ШІМ. Коли лічильник досягає значення, рівного вказаному діапазону, він скидається до нуля. Хоча лічильник менший за заданий робочий цикл, вихід високий, інакше вихід низький.

Це означає, що якщо ви хочете встановити ШІМ на певну частоту, ви можете використовувати таке співвідношення:

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

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


Що стосується нижньої межі pwmRange: я успішно встановив її 2 (щоб отримати робочий цикл 50%).
Тед Пудлік

з якого джерела вам відомо, що тактовий годинник має частоту 19,2 МГц?
th gg

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,334 кГц

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

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

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

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.802kHz

pwmSetClock (4000); -> 2.401kHz

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

З того, що я перевірив, здається, дільник переходить від 2 до деякого числа менше 5000. Я б здогадався, що це має щось спільне з двійковим поданням тих чисел, які прямо встановлюються в реєстрі. Після того, як двійкове представлення чисел має більше бітів, ніж реєстр, він може взяти перші біти та інтерпретувати числа таким чином. Ось чому дивна поведінка виникає при переході від 4000 до 5000.


1
Як би я змінив робочий цикл?
noufal

Як ви вимірювали частоти?
Seanny123
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.