Di recente ho avuto qualche motivo per iniziare a sperimentare PWM da solo, e ho scoperto che (come sottolineato da uno dei commenti) la frequenza sembra variare con il ciclo di lavoro - bizzare, giusto? Si scopre che Broadcom ha implementato PWM "bilanciato" al fine di rendere gli impulsi PWM on e off il più uniformemente distribuiti possibile. Forniscono una descrizione dell'algoritmo e qualche altra discussione a pagina 139 del loro foglio dati:
http://www.element14.com/community/servlet/JiveServlet/downloadBody/43016-102-1-231518/Broadcom.Datasheet.pdf
Quindi quello che vuoi davvero è mettere PWM in modalità mark-space, che ti darà il PWM tradizionale (e facilmente prevedibile) che stai cercando:
pwmSetMode(PWM_MODE_MS);
Il resto della risposta presuppone che siamo in modalità mark-space.
Ho anche fatto qualche esperimento con l'intervallo di valori consentito per pwmSetClock()
e pwmSetRange()
. Come notato in una delle altre risposte, l'intervallo valido per pwmSetClock()
sembra andare da 2 a 4095, mentre l'intervallo valido per pwmSetRange()
è fino a 4096 (non ho tentato di trovare un limite inferiore).
Il range e il clock (un nome migliore è probabilmente divisore) influenzano entrambi la frequenza. L'intervallo influisce anche sulla risoluzione, quindi sebbene sia possibile utilizzare valori molto bassi, esiste un limite pratico a quanto probabilmente vorrai andare basso. Ad esempio, se si utilizza un intervallo di 4, è possibile ottenere frequenze più elevate, ma sarà possibile impostare il duty cycle solo su 0/4, 1/4, 2/4, 3/4 o 4/4.
L'orologio PWM Raspberry Pi ha una frequenza di base di 19,2 MHz. Questa frequenza, divisa per l'argomento a pwmSetClock()
, è la frequenza alla quale viene incrementato il contatore PWM. Quando il contatore raggiunge un valore uguale all'intervallo specificato, si azzera. Mentre il contatore è inferiore al ciclo di lavoro specificato, l'uscita è alta, altrimenti l'uscita è bassa.
Ciò significa che se si desidera impostare PWM su una frequenza specifica, è possibile utilizzare la relazione seguente:
pwmFrequency in Hz = 19.2e6 Hz / pwmClock / pwmRange.
Se si utilizzano i valori massimi consentiti per pwmSetClock()
e pwmSetRange()
, si otterrà la frequenza PWM hardware minima raggiungibile di ~ 1,14 Hz. Questo darà sicuramente uno sfarfallio visibile (più di un flash, davvero) a un LED. Ho confermato l'equazione di cui sopra con un oscilloscopio e sembra reggere. Il limite di frequenza superiore sarà influenzato dalla risoluzione necessaria, come descritto sopra.
pwmWrite()
. Non qualcosa che mi aspetterei che accada