Kontrol frekuensi PWM Perangkat Keras

21

Saya menggunakan output PWM perangkat keras dengan wiringpi. Ini menyediakan fungsi pwmSetClock yang seharusnya memungkinkan untuk mengubah frekuensi. ( https://projects.drogon.net/raspberry-pi/wiringpi/functions/ ). Saya percaya karena defaultnya adalah 200 Mhz pengaturan pembagi ke 200000000 harus membuat LED terhubung ke output flash terlihat, tetapi itu tidak terjadi.

Bisakah ini diubah?

pengguna1217949
sumber
1
Saya melakukan beberapa pengujian dengan PWM perangkat keras, dan sepertinya tidak memiliki frekuensi fiexd. Ini bervariasi berdasarkan lebar pulsa yang ditetapkan pwmWrite(). Bukan sesuatu yang saya harapkan akan terjadi
TheMeaningfulEngineer

Jawaban:

25

Saya baru-baru ini memiliki beberapa alasan untuk mulai bereksperimen dengan PWM sendiri, dan menemukan bahwa (sebagaimana ditunjukkan oleh salah satu komentar) frekuensinya tampaknya berbeda dengan siklus tugas - aneh, bukan? Ternyata Broadcom menerapkan PWM "seimbang" agar pulsa PWM hidup dan mati didistribusikan secara merata. Mereka memberikan deskripsi algoritma dan beberapa diskusi lebih lanjut di halaman 139 dari lembar data mereka: http://www.element14.com/community/servlet/JiveServlet/downloadBody/43016-102-1-231518/Broadcom.Datasheet.pdf

Jadi yang Anda inginkan adalah menempatkan PWM dalam mode mark-space, yang akan memberi Anda PWM tradisional (dan mudah diprediksi) yang Anda cari:

pwmSetMode(PWM_MODE_MS);

Sisa dari jawaban mengasumsikan kita berada dalam mode mark-space.

Saya juga melakukan beberapa percobaan dengan rentang nilai yang diijinkan untuk pwmSetClock()dan pwmSetRange(). Seperti disebutkan dalam salah satu jawaban lain, rentang yang valid untuk pwmSetClock()tampaknya beralih dari 2 menjadi 4095, sedangkan rentang yang valid untuk pwmSetRange()hingga 4096 (saya tidak berusaha menemukan batas bawah).

Rentang dan jam (nama yang lebih baik mungkin adalah pembagi) keduanya mempengaruhi frekuensi. Rentang ini juga memengaruhi resolusi, jadi meskipun dimungkinkan untuk menggunakan nilai yang sangat rendah, ada batas praktis seberapa rendah Anda mungkin ingin pergi. Misalnya, jika Anda menggunakan rentang 4, Anda bisa mencapai frekuensi yang lebih tinggi, tetapi Anda hanya akan dapat mengatur siklus tugas ke 0/4, 1/4, 2/4, 3/4 atau 4/4.

Jam Raspberry Pi PWM memiliki frekuensi dasar 19,2 MHz. Frekuensi ini, dibagi dengan argumen pwmSetClock(), adalah frekuensi di mana penghitung PWM bertambah. Ketika penghitung mencapai nilai yang sama dengan rentang yang ditentukan, penghitung ulang ke nol. Sementara penghitung kurang dari siklus tugas yang ditentukan, output tinggi, jika tidak output rendah.

Ini berarti, jika Anda ingin mengatur PWM untuk memiliki frekuensi tertentu, Anda dapat menggunakan hubungan berikut:

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

Jika Anda menggunakan nilai maksimum yang diizinkan untuk pwmSetClock()dan pwmSetRange(), Anda akan berakhir dengan frekuensi PWM perangkat keras minimum yang dapat dicapai ~ 1,14 Hz. Ini tentu akan memberikan kedipan yang terlihat (lebih banyak flash, sebenarnya) ke LED. Saya memang mengkonfirmasi persamaan di atas dengan osiloskop, dan tampaknya tahan. Batas frekuensi atas akan dipengaruhi oleh resolusi yang Anda butuhkan, seperti dijelaskan di atas.

Kerry
sumber
Mengenai batas bawah pada pwmRange: Saya berhasil mengaturnya ke 2 (untuk mendapatkan siklus tugas 50%).
Ted Pudlik
dari sumber apa Anda tahu bahwa jam PWM memiliki frekuensi 19,2 mhz?
thi gg
10

Menurut rumus ini:

pwmFrequency in Hz = 19.2e6 Hz / pwmClock / pwmRange

Kita dapat mengatur pwmClock=1920dan pwmRange=200mendapatkan pwmFrequency=50Hz:

50 Hz = 19.2e6 Hz / 1920 / 200

Saya mengujinya di 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º)

Catatan: Servo saya mengharapkan sinyal 50Hz .

kev
sumber
bagaimana Anda datang ke: 'gpio pwmr 200 # 0,1 ms per unit'
mxlian
50Hz ---> 20 ms per siklus. 20ms / 200 unit = 0,1ms per unit
mxlian
5

Ini adalah kode yang saya gunakan. Saya mencoba melihat apa yang akan berubah ketika saya mengubah pengaturan.

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

pwmSetClock (2); -> 4,81MHz

pwmSetClock (3); -> 3,19MHz

pwmSetClock (4); -> 2,398MHz

pwmSetClock (5); -> 1,919MHz

pwmSetClock (6); -> 1,6MHz

pwmSetClock (7); -> 1,3MHz

pwmSetClock (8); -> 1.2MHz

pwmSetClock (9); -> 1,067MHz

pwmSetClock (10); -> 959kHz

pwmSetClock (11); -> 871kHz

pwmSetClock (20); -> 480kHz

pwmSetClock (200); -> 48kHz

pwmSetClock (500); -> 19kHz

pwmSetClock (1000); -> 9,59kHz

pwmSetClock (2000); -> 4.802kHz

pwmSetClock (4000); -> 2.401kHz

pwmSetClock (5000); -> 10,58kHz

Dari apa yang saya uji, tampaknya pembagi beralih dari 2 ke beberapa nomor kurang dari 5.000. Saya kira itu ada hubungannya dengan representasi biner dari angka-angka yang sedang diatur secara langsung dalam register. Setelah representasi angka biner memiliki lebih banyak bit daripada yang bisa diambil register, hanya perlu bit pertama dan menafsirkan angka dengan cara itu. Itulah mengapa perilaku aneh itu muncul ketika pergi dari 4000 ke 5000.

TheMeaningfulEngineer
sumber
1
Bagaimana saya mengubah siklus tugas?
noufal
Bagaimana Anda mengukur frekuensi?
Seanny123