Jawaban yang diterima dari jfpoilpret ditulis dengan sangat baik, sangat valid dan dalam 99% kasus saya akan melakukan persis apa yang dia jelaskan. Solusi-solusinya berada dalam parameter yang Anda tentukan, sehingga harus bekerja dengan sangat baik. Tapi apa yang lebih baik daripada " sangat baik "? Kesempurnaan! Bagaimanapun, pertanyaannya adalah tentang menghasilkan nilai yang tepat. Seperti yang dikatakan cukup dekat adalah baik dalam banyak kasus (bisa dibilang semua), dan bahkan ketika berurusan dengan sesuatu sebagai jam ketika 1 detik harus 1 detik, Anda masih harus menderita ketidaksempurnaan bagian yang diwariskan.
Apa yang akan saya sarankan tidak selalu mungkin. Dalam beberapa kasus, itu mungkin, tetapi dengan kerumitan dan usaha yang jauh lebih banyak daripada kasus ini. Apakah itu layak bergantung pada kasus per kasus. Tujuan saya sebagian besar untuk menunjukkan alternatif untuk referensi di masa depan yang lebih baik dalam kasus-kasus agak pinggiran. Ini ditulis dengan pemikiran pengguna Arduino pemula yang tidak memiliki pengalaman luas dalam bidang elektronik.
Bagi orang yang lebih lanjut ini mungkin akan terlihat terlalu verbose dan dumbed. Tetapi saya percaya bahwa orang-orang yang sama itu mungkin sudah mengetahuinya dan tidak membutuhkan jawaban ini. Ini juga berlaku untuk setiap mikrokontroler dan setiap pabrikan dan arsitektur. Tetapi untuk mikrokontroler lain, Anda perlu berkonsultasi dengan lembar data yang benar untuk mengetahui register yang tepat dan nama dan nilai yang sudah ditentukan sebelumnya.
Dalam kasus Anda, Anda memerlukan frekuensi tertentu dan hal yang menyenangkan tentang itu, adalah bahwa sebenarnya 56 kHz sebenarnya dapat dicapai dengan sangat mudah (tidak termasuk ketidaksempurnaan praktis dari bagian-bagian). Jadi ini juga contoh kasus yang sempurna.
Menghasilkan sinyal tergantung pada sumber waktu dan jam dari mikrokontroler, seperti yang dijelaskan dengan baik oleh jfpoilpret. Jawabannya berkaitan dengan masalah satu sudut pandang saja dan itu mengutak-atik timer. Tetapi Anda juga bisa mengutak-atik sumber jam, atau bahkan lebih baik dengan keduanya untuk hasil yang sinergis dan mengagumkan. Dengan mengubah parameter lingkungan, dalam hal ini meretas sistem dan mengganti sumber jam, kita dapat menangani masalah khusus dengan lebih banyak, lebih mudah dan lebih sederhana.
Pertama yang mengingatkan, karena mengubah status pin, Anda perlu menjalankan ISR dua kali lebih banyak daripada frekuensi sinyal. Ini adalah 112.000 kali per detik. 56.000 dan 16.000.000 tidak bertambah dengan sangat baik seperti yang telah ditunjukkan. Kita perlu mengubah frekuensi sinyal atau frekuensi kebijaksanaan. Mari kita hadapi sekarang dengan frekuensi sinyal yang tidak berubah dan temukan kecepatan clock yang lebih baik.
Akan lebih mudah untuk memilih jam dengan urutan besarnya lebih besar dari 56 kHz (atau 112 kHz, tetapi secara praktis sama), karena Anda hanya menambahkan nol dan matematika seperti ini paling sederhana bagi kebanyakan orang. Sayangnya segala sesuatu di dunia ini adalah semacam kompromi dengan sesuatu. Tidak setiap nilai akan berfungsi.
Contoh pertama adalah dengan kecepatan generator kebijaksanaan yang terlalu rendah.
Jika Anda memilih jam 56.000 Hz, Anda tidak akan dapat melakukan apa pun karena Anda perlu memanggil ISR setiap siklus dan tidak dapat melakukan hal lain. Ini sama sekali tidak berguna. Jika Anda memilih kecepatan 10 kali lebih cepat (560 kHz), Anda akan memiliki 9 (10 siklus untuk timer untuk mencapai nilai maksimal - satu siklus untuk memanggil fungsi ISR) siklus mikrokontroler untuk melakukan pekerjaan Anda dan ini sangat mungkin tidak cukup. Anda cukup sering membutuhkan lebih banyak daya komputasi.
Jika Anda memilih nilai yang terlalu bagus di sisi lain, karena 56 MHz mikrokontroler tidak dapat bekerja dengannya. Itu terlalu cepat. Jadi, hanya memilih nilai terbesar di toko tidak akan memotongnya juga.
Original Arduino Uno R3 memiliki stock clock pada 16 MHz, jadi apa pun yang lebih lambat itu dijamin bekerja. Nilai selanjutnya yang merupakan urutan besarnya lebih besar dari 56 dan lebih rendah dari 16 MHz adalah 5,6 MHz. Ini akan menyebabkan Anda dapat memanggil ISR setiap 50 siklus dan akan menciptakan frekuensi timer 112.000 Hz yang sempurna. Dan sinyal Anda akan persis 56 kHz. Anda akan memiliki 49 siklus MCU untuk menjalankan program Anda di antara panggilan ISR, tetapi masih sekitar 1/3 dari kecepatan jam asli. Seseorang dapat menggunakan 112 sebagai basis dan menggunakan clock 11,2 MHz dan ini akan memberikan sekitar 2/3 dari resonator 16 MHz stok. Fungsi ISR akan dipanggil setiap 100 siklus dan masih menghasilkan sinyal 56 kHz yang sempurna.
Namun ada dua masalah utama dengan nilai-nilai ini.
Masalah pertama sangat tergantung pada kebutuhan Anda: Anda mengorbankan sekitar 1/3 (dengan 11,2 MHz) daya komputasi maksimum Anda untuk mendapatkan frekuensi sinyal yang tepat yang menggunakan nilai register yang mudah ditemukan (OCR iirc ). Anda mungkin baik-baik saja dengan itu atau tidak.
Masalah kedua adalah showstopper yang sulit : Sangat mudah untuk menemukan nilai, tetapi sangat sering mereka tidak ada sebagai sumber jam yang diproduksi. Ini adalah halaman web resonator Farnell yang hanya kekurangan 5,6 MHz dan 11,2 MHz.
Untuk menghindari hal ini, kita dapat melihat nilai-nilai resonator yang tersedia dan mencari tahu hal lain yang dapat digunakan untuk menghasilkan nilai-nilai yang tepat diinginkan. Jika kita membagi 56 dengan 4 kita mendapatkan 14 dan untungnya ada resonator 14 MHz. Ini memberi kami kecepatan yang jauh lebih tinggi dan lebih banyak daya dan sama mudahnya untuk menemukan nilai register. Untuk memanggil ISR 112.000 kali per detik, kita perlu memasukkan nilai desimal 124 atau heksadesimal 0x7C dalam register OCR, jadi dengan menghitung 124 siklus + 1 untuk memanggil ISR, kita mendapatkan nilai sempurna yang kita inginkan.
NB
- ISR - interupsi layanan rutin (ini adalah kode yang dieksekusi hanya pada interupsi yang dihasilkan)
- Seberapa besar program Anda tergantung pada ukuran memori! Ini tidak ada hubungannya dengan kecepatan jam dan tidak ada hubungannya dengan seberapa sering Anda memanggil ISR.
Ketika mikrokontroler mulai dengan perintah program penghitung bertambah. Jika interupsi dihasilkan, ISR dipanggil dan nilai ini disimpan dalam register khusus. Ketika kode ISR selesai, nilai penghitung program dipulihkan dari register khusus ini dan program berlanjut dari tempat kode itu terputus seolah-olah tidak pernah terjadi.
Saya akan memberikan contoh yang sangat bodoh. Jika Anda seorang purist, saya peringatkan Anda: Hidung dan perdarahan mata bisa terjadi.
Bayangkan Anda harus berjalan dari suatu tempat ke tempat lain. Petunjuk rute langkah demi langkah adalah program utama Anda dan perintahnya. Seberapa cepat Anda berjalan atau berlari, tergantung pada "kecepatan clock" Anda, tetapi tidak pada instruksi rute (30 langkah maju, 1 belokan 90 grad. Kiri, 10 langkah maju, 45 grad. Kanan, dll.) Mereka selalu sama . Sekarang bayangkan seorang anak kecil atau politisi lokal yang serakah melepaskan ikatan sepatu Anda sesekali. Ini adalah acara yang menghasilkan interupsi. Kemudian Anda berhenti setelah langkah terakhir Anda, berlutut dan ikat sepatu Anda lagi. Ini adalah program ISR Anda.
Kemudian Anda melanjutkan dari tempat Anda berhenti; Anda tidak memulai dari awal. Ketika Anda berjalan tanpa peduli di dunia dan sepanjang waktu, Anda tidak peduli bahkan jika Anda harus mengikat sepatu Anda setiap langkah lainnya. Namun, jika Anda melakukannya dengan batasan waktu, seperti berlari 100 meter di Olimpiade (atau berlari dari pemangsa pemakan daging yang lapar), berhenti dan mengikat sepatu Anda dapat memiliki konsekuensi yang mengerikan. Hal yang sama terjadi pada mikrokontroler. Bahkan jika Anda hanya mengeksekusi satu baris kode, program Anda akan terus berjalan, walaupun lambat. Jika Anda tidak peduli dengan kecepatan sama sekali, itu tidak akan menjadi masalah. Jika Anda harus melakukan beberapa waktu terkait, seperti menggunakan tindakan tergantung waktu lainnya, gangguan dapat sangat tidak diinginkan dan bermasalah.
Kurang itu lebih! Jam yang lebih cepat tidak selalu lebih baik. Perangkat yang lebih lambat menggunakan daya yang jauh lebih sedikit. Ini bisa menjadi titik penting dalam perangkat yang dioperasikan dengan baterai.
Siklus yang diperlukan berasal dari rumus ini:
(kecepatan clock / (nilai prescaler * frekuensi panggilan ISR yang diperlukan)) - 1