Mengapa beberapa pin memiliki frekuensi PWM yang berbeda?

20

Menurut referensi Arduino untukanalogWrite() , frekuensi PWM pada kebanyakan pin adalah ~ 490 Hz. Namun, ~ 980 Hz untuk pin 5 dan 6 di Uno, dan untuk pin 3 dan 11 di Leonardo.

Mengapa ini berbeda? Apakah ini fitur desain yang disengaja, atau entah bagaimana ditentukan oleh perangkat keras?

Peter Bloomfield
sumber

Jawaban:

23

Itu bukan satu-satunya frekuensi yang tersedia untuk sinyal PWM. Namun, mereka adalah frekuensi yang ditentukan oleh prescaler yang diterapkan (yang Anda dapat dengan mudah berubah seperti yang dijelaskan di bawah ini).

Masing-masing dari 3 pasang pin PWM diikat ke satu timer, masing-masing memiliki frekuensi basis sendiri, sebagai berikut:

  • Pin 5 dan 6 dipasangkan pada timer0, dengan frekuensi dasar 62500Hz
  • Pin 9 dan 10 dipasangkan pada timer1, dengan frekuensi dasar 31250Hz
  • Pin 3 dan 11 dipasangkan pada timer2, dengan frekuensi dasar 31250Hz

Kemudian setiap set pin memiliki sejumlah nilai prescaler yang dapat dipilih, yang akan membagi frekuensi dasar dari sepasang pin tersebut. Nilai prescaler yang tersedia adalah:

  • Pin 5 dan 6 memiliki nilai prescaler 1, 8, 64, 256, dan 1024
  • Pin 9 dan 10 memiliki nilai prescaler 1, 8, 64, 256, dan 1024
  • Pin 3 dan 11 memiliki nilai prescaler 1, 8, 32, 64, 128, 256, dan 1024

Kombinasi yang berbeda menghasilkan frekuensi yang berbeda dalam pin PWM yang diberikan. Perhatikan bahwa pengatur waktu 2 (terikat pada pin 3 dan 11) memiliki nilai prescaler yang lebih banyak, yang menghasilkan frekuensi yang lebih banyak.

Sekarang, mengapa timer 2 berbeda, itu pertanyaan terpisah.

Sunting: Berikut daftar kemungkinan frekuensi PWM per pin (dari artikel ini ):

Untuk pin 6 dan 5 (OC0A dan OC0B):

  • Jika TCCR0B = xxxxx001, frekuensi adalah 64kHz
  • Jika TCCR0B = xxxxx010, frekuensi adalah 8 kHz
  • Jika TCCR0B = xxxxx011, frekuensi adalah 1 kHz (ini adalah default dari bootloader Diecimila)
  • Jika TCCR0B = xxxxx100, frekuensinya adalah 250Hz
  • Jika TCCR0B = xxxxx101, frekuensi adalah 62,5 Hz

Untuk pin 9, 10, 11 dan 3 (OC1A, OC1B, OC2A, OC2B):

  • Jika TCCRnB = xxxxx001, frekuensi adalah 32kHz
  • Jika TCCRnB = xxxxx010, frekuensi adalah 4 kHz
  • Jika TCCRnB = xxxxx011, frekuensi adalah 500Hz (ini adalah default dari bootloader Diecimila)
  • Jika TCCRnB = xxxxx100, frekuensi adalah 125Hz
  • Jika TCCRnB = xxxxx101, frekuensi adalah 31,25 Hz

TCCRnBadalah tempat Anda mengatur bit prescaler untuk timer n, menggantikan ndengan 0, 1 atau 2, tergantung pada timer yang ingin Anda atur. Jika Anda masih tidak yakin tentang operasi bitwise, baca tutorial matematika bit ini .

Sumber saya:

Perhatikan bahwa tampaknya ada perbedaan dalam sumber-sumber tersebut tentang apakah pin 9 dan 10 memiliki perilaku yang sama dengan 5 dan 6 atau 3 dan 11, tetapi Anda tetap mendapatkan idenya. Saya membaca lembar data untuk mencoba dan mencari tahu mana yang benar, atau apakah ini perbedaan antara papan.

Ricardo
sumber
1
ATmega apa yang dirujuk jawaban ini? Saya tidak memeriksa, tapi saya yakin itu sedikit berbeda per controller.
jippie
@ jippie Poin bagus! Sumber merujuk pada ATmega168 dan 328.
Ricardo
@ jippie Hanya untuk memperjelas, dalam jawaban saya, nomor pin merujuk pada bagaimana mereka ditetapkan pada papan Uno (pin 1 berarti Digital Pin 1, atau D1, misalnya), bukan IC (ATmega328 pin 1 diatur ulang).
Ricardo
1
Saya percaya detail-detail itu juga berubah dengan papan, Uno, Duemilanove, Mega, ...
jippie
@ jippie Jelas, ya.
Ricardo
8

Saya tidak mengetahui pertimbangan desain, tetapi jika Anda memeriksa lembar data untuk mikrokontroler di Arduino Anda, Anda akan melihat bahwa pin PWM dikelompokkan bersama dan per grup terhubung ke penghitung waktu. Kecepatan peningkatan timer ini bervariasi tergantung pada prescaler yang dikonfigurasi. Jika Anda mengubah prescaler untuk penghitung waktu tertentu, Anda mengubah frekuensi PWM untuk pin PWM terkait. Saya percaya beberapa timer berfungsi ganda untuk keperluan lain seperti millis();fungsi. Jika Anda mengubah prescaler untuk penghitung waktu itu, nilai yang dikembalikan oleh millis()akan dimatikan oleh faktor yang sama.

Anda dapat menghitung pengaturan untuk prescaler sebagai berikut:

$$ \ text {prescaler} = \ dfrac {f_ {CPU}} {PWMresolution × f_ {PWM}} = \ dfrac {16 \ text {MHz}} {256 × 490} \ kira-kira 128 $$

prescaler = f [CPU] / (PWMresolution × f [PWM]) = 16000000 / (256 × 490) = sekitar 128.

Periksa lembar data dan Anda akan menemukan bahwa 128 memang salah satu dari nilai pra-pilih yang dapat Anda pilih.

jippie
sumber
2
Wah, apakah kita merindukan MathJax atau apa? Saya harap kami mengaktifkannya setelah versi beta.
Ricardo
1
@ Ricardo Saya memiliki tombol MathJax di browser saya; o) meta.arduino.stackexchange.com/questions/13/…
jippie