Steuerungshardware PWM-Frequenz


21

Ich verwende den Hardware-PWM-Ausgang mit Wiringpi. Es bietet die Funktion pwmSetClock, die es ermöglichen soll, die Frequenz zu ändern. ( https://projects.drogon.net/raspberry-pi/wiringpi/functions/ ). Ich glaube, da die Standardeinstellung 200 Mhz ist, sollte der Divisor auf 200000000 eingestellt werden, damit eine an den Ausgang angeschlossene LED sichtbar blinkt, aber das ist nicht der Fall.

Kann das geändert werden?


1
Ich mache einige Tests mit der Hardware-PWM, und es scheint keine feste Frequenz zu haben. Sie variierte je nach eingestellter Impulsbreite pwmWrite(). Nichts, was ich erwarten würde
TheMeaningfulEngineer

Antworten:


25

Ich hatte kürzlich einen Grund, selbst mit PWM zu experimentieren, und stellte fest, dass (wie in einem der Kommentare hervorgehoben) die Häufigkeit mit dem Arbeitszyklus zu variieren scheint - bizzare, richtig? Es hat sich herausgestellt, dass Broadcom "symmetrisches" PWM implementiert hat, um die Ein- und Ausschalt-PWM-Impulse so gleichmäßig wie möglich zu verteilen. Sie geben eine Beschreibung des Algorithmus und weitere Informationen auf Seite 139 ihres Datenblattes: http://www.element14.com/community/servlet/JiveServlet/downloadBody/43016-102-1-231518/Broadcom.Datasheet.pdf

Was Sie also wirklich wollen, ist, PWM in den Mark-Space-Modus zu versetzen, wodurch Sie das traditionelle (und leicht vorhersehbare) PWM erhalten, das Sie suchen:

pwmSetMode(PWM_MODE_MS);

In der restlichen Antwort wird davon ausgegangen, dass wir uns im Leerzeichenmodus befinden.

Ich habe auch einige Experimente mit dem zulässigen Wertebereich für pwmSetClock()und durchgeführt pwmSetRange(). Wie in einer der anderen Antworten angegeben, reicht der gültige Bereich für pwmSetClock()anscheinend von 2 bis 4095, während der gültige Bereich für pwmSetRange()bis 4096 reicht (ich habe nicht versucht, eine Untergrenze zu finden).

Der Bereich und die Uhr (ein besserer Name ist wahrscheinlich ein Teiler) beeinflussen beide die Frequenz. Der Bereich wirkt sich auch auf die Auflösung aus. Obwohl möglicherweise sehr niedrige Werte verwendet werden können, gibt es eine praktische Grenze dafür, wie niedrig Sie wahrscheinlich sein möchten. Wenn Sie beispielsweise einen Bereich von 4 verwenden, können Sie höhere Frequenzen erzielen, das Tastverhältnis kann jedoch nur auf 0/4, 1/4, 2/4, 3/4 oder 4/4 eingestellt werden.

Der Raspberry Pi PWM-Takt hat eine Grundfrequenz von 19,2 MHz. Diese Frequenz, geteilt durch das Argument bis pwmSetClock(), ist die Frequenz, mit der der PWM-Zähler inkrementiert wird. Wenn der Zähler einen Wert erreicht, der dem angegebenen Bereich entspricht, wird er auf Null zurückgesetzt. Während der Zähler kleiner als der angegebene Arbeitszyklus ist, ist die Ausgabe hoch, andernfalls ist die Ausgabe niedrig.

Das heißt, wenn Sie die PWM auf eine bestimmte Frequenz einstellen möchten, können Sie die folgende Beziehung verwenden:

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

Wenn Sie die maximal zulässigen Werte für pwmSetClock()und verwenden pwmSetRange(), erhalten Sie die minimal erreichbare Hardware-PWM-Frequenz von ~ 1,14 Hz. Dies verleiht einer LED mit Sicherheit ein sichtbares Flackern (eigentlich eher ein Blitz). Ich habe die obige Gleichung mit einem Oszilloskop bestätigt, und es scheint zu gelten. Die obere Frequenzgrenze hängt von der Auflösung ab, die Sie wie oben beschrieben benötigen.


Bezüglich der Untergrenze für pwmRange: Ich habe es erfolgreich auf 2 gesetzt (um einen Arbeitszyklus von 50% zu erhalten).
Ted Pudlik

aus welcher quelle weißt du, dass die pwm uhr eine frequenz von 19,2 mhz hat?
thi gg

10

Nach dieser Formel:

pwmFrequency in Hz = 19.2e6 Hz / pwmClock / pwmRange

Wir können einstellen pwmClock=1920und pwmRange=200bekommen pwmFrequency=50Hz:

50 Hz = 19.2e6 Hz / 1920 / 200

Ich teste es auf 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º)

Hinweis: Mein Servo erwartet ein 50Hz- Signal.


wie kommst du zu: 'gpio pwmr 200 # 0.1 ms per unit'
mxlian

50 Hz -> 20 ms pro Zyklus. 20 ms / 200 Einheiten = 0,1 ms pro Einheit
mxlian

5

Dies ist der Code, den ich verwende. Ich versuche zu sehen, was sich ändern wird, wenn ich die Einstellungen ändere.

#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 kHz

pwmSetClock (2); -> 4,81 MHz

pwmSetClock (3); -> 3,19 MHz

pwmSetClock (4); -> 2,398 MHz

pwmSetClock (5); -> 1,919 MHz

pwmSetClock (6); -> 1,6 MHz

pwmSetClock (7); -> 1,3 MHz

pwmSetClock (8); -> 1,2 MHz

pwmSetClock (9); -> 1,067 MHz

pwmSetClock (10); -> 959 kHz

pwmSetClock (11); -> 871 kHz

pwmSetClock (20); -> 480 kHz

pwmSetClock (200); -> 48 kHz

pwmSetClock (500); -> 19 kHz

pwmSetClock (1000); -> 9,59 kHz

pwmSetClock (2000); -> 4,802 kHz

pwmSetClock (4000); -> 2,401 kHz

pwmSetClock (5000); -> 10,58 kHz

Nach dem, was ich getestet habe, scheint der Divisor von 2 auf eine Zahl kleiner als 5000 zu gehen. Ich würde vermuten, dass dies etwas mit der binären Darstellung dieser Zahlen zu tun hat, die direkt im Register eingestellt werden. Sobald die Zahlen-Binärdarstellung mehr Bits enthält, als das Register aufnehmen kann, werden nur die ersten Bits verwendet und die Zahlen auf diese Weise interpretiert. Das ist der Grund, warum das seltsame Verhalten auftritt, wenn von 4000 auf 5000 gewechselt wird.


1
Wie würde ich den Arbeitszyklus ändern?
Noufal

Wie haben Sie die Frequenzen gemessen?
Seanny123
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.