Mengapa Anda bersikeras memulai judul Anda dengan tag ketika saya membuatnya menjadi pertanyaan bahasa Inggris yang sempurna?
stevenvh
4
Maaf Steven, saya dengan tulus berpikir (dan berpikir) itu adalah cara yang baik untuk mengungkapkan pertanyaan secara ringkas dan jelas. Ada banyak diskusi tentang ini, dan dalam beberapa kasus Jeff setuju bahwa itu adalah cara bertanya yang baik. Diskusi ada di sini; heatmaps adalah apa yang meyakinkan saya bahwa untuk gaya pertanyaan ini perlu untuk menekankan lingkungan operasi. meta.stackexchange.com/questions/10647/writing-good-titles/... Tapi, untuk menghormati jawaban Anda yang sangat baik, saya akan dengan senang hati mengubahnya kembali jika Anda pikir itu yang terbaik.
Mark Harrison
Apakah mungkin menggunakannya untuk fungsi pulsein ()? Saya perlu mengukur panjang pulsa di le resolusi dari 1 usec.
Ruang ini disediakan untuk jawaban atas pertanyaan di atas. Jika Anda memiliki sesuatu untuk ditanyakan, mulailah pertanyaan Anda sendiri.
Olin Lathrop
Jawaban:
9
Ya, tergantung laju jam dasar Arduino Anda. Sebagai contoh di sini adalah frekuensi input penghitung waktu dan periode setelah pra-penskalaan, untuk penghitung waktu pencacah ATMega2560 2, dan kecepatan clock dasar 16MHz. Timer memiliki opsi nilai "prescaler" yang menentukan frekuensi / periode, ditunjukkan pada tabel ini:
TCCR2B bits 2-0PrescalerFreq[KHz],Period[usec] after prescale0x0(TC stopped)----0x1116000.0.06250x282000.0.5000x332500.2.0000x464250.4.0000x5128125.8.0000x625662.516.0000x7102415.62564.000
Untuk resolusi pengaturan waktu yang lebih baik, Anda menggunakan nilai yang disebut TCNT2. Ada build in counter yang beroperasi dari 0 hingga 255 karena timernya 8 bit. Ketika penghitung mencapai nilai yang diberikan oleh TCNT2 itu memicu interupsi. Gangguan ini disebut TIMER2_OVF_vect.
diberikan informasi ini, tingkat interupsi yang dihasilkan adalah: 16MHz / (prescaler * (255 - TCNT2))
Anda bisa menjalankan timer dengan kecepatan 16MHz (62.5nSec) penuh meskipun itu jauh lebih cepat dari yang Anda butuhkan; 2MHz dengan hitungan awal (255-2) akan memberi Anda tingkat interupsi 1MHz. Bagilah dengan 2 di ISR Anda:
externuint32_tMicroSecClock=0;
ISR(TIMER2_OVF_vect){// this is a built in function that gets called when the timer gets to the overflow counter numberstatic uint_8 count;// interrupt counterif((++count &0x01)==0)// bump the interrupt counter++MicroSecClock;// & count uSec every other time.
digitalWrite(53,toggle);// pin 53 is arbitrary
TCNT2 =253;// this tells the timer when to trigger the interrupt. when the counter gets to 253 out of 255(because the timer is 8 bit) the timmer will trigger an interrupt
TIFR2 =0x00;// clear timer overflow flag};
Lembar data untuk MCU Anda adalah sumber daya dasar; artikel ini akan memberi Anda (dan memberi saya!) awal yang baik.
Mark, saya memutuskan untuk menulis satu set fungsi baru, berdasarkan Arduino Atmega328 Timer2, dan menggunakan overflow interupsi, untuk mendapatkan presisi hingga 0,5 us. Kode saya tersedia untuk diunduh dan digunakan di sini:
Berikut adalah deskripsi singkat: "Saya menulis" perpustakaan "untuk mendapatkan presisi 0,5us pada fungsi penggantian" micros () ", sehingga saya bisa mendapatkan hasil yang berulang dengan membaca sinyal PWM atau PPM, hingga dalam 1us. Saya mencari di sekitar internet dan tidak dapat menemukan sesuatu yang sebanding (atau yang mudah digunakan, dan mempertahankan kemampuan Arduino untuk menulis sinyal PWM melalui Servo Libary), jadi saya pikir ini adalah kontribusi utama pertama saya ke dunia Arduino dan Kontrol Radio. "
Jika jatuh ke Level AVR dapat diterima (seperti yang Anda sebutkan dalam pertanyaan Anda), Anda dapat mengatur timer dan bahkan mendapatkan detak jam AVR.
Anda perlu merujuk ke lembar data AVR Anda karena berbeda dalam ATMegas dan ATTinys yang berbeda. Tetapi prosedurnya selalu sama. Yang perlu Anda lakukan adalah:
tentukan prescaler mana yang akan digunakan (misalnya set ke 1, yaitu tanpa prescaling jika Anda menginginkan kecepatan clock CPU yang sebenarnya), lihat dokumentasi TCCR
mengatur timer overflow interrupt, handler interrupt dan mengaktifkan interupsi secara global
aktifkan timer di Timer / Counter Control Register TCCR
Dengan begitu bisa mendapatkan kutu yang tepat dari register penghitung waktu, namun Anda harus menghitung luapan secara manual. Ini setepat mungkin oleh teknologi.
Berikut adalah beberapa contoh kode untuk AT90S2313 yang sudah usang, tetapi ini memberi Anda petunjuk yang baik tentang apa yang harus dilakukan pada dasarnya:
/* uC: AT90S2313 */#include<avr/io.h>#include<avr/interrupt.h>int main(void){// set up timer 0
TCCR0 =(1<<CS01);// Prescaler 8// enable overflow interrupt
TIMSK |=(1<<TOIE0);// activate interrupts
sei();while(1){/* Do whatever you like */}}
ISR (TIMER0_OVF_vect){/*
This gets called everytime there in an overflow in the timer register
*/}
Terima kasih FeeJai. Bisakah saya mengatur interupsi ini dalam konteks sketsa Arduino?
Mark Harrison
1
Saya tidak terbiasa dengan kerangka Arduino. Tetapi jika itu tidak mengatur semua timer secara internal, Anda pasti bisa. Kalau tidak, Anda masih bisa membaca register penghitung waktu dan menghitung sendiri.
FeeJai
Ya, Anda sedang memprogram dalam C ++ lengkap di Arduino dan dapat menggunakan semua register dan simbol seperti TIMSK, TOIE0dll. (Menyalin penyetelan timer dari atmega328p datasheet). Sepertinya Anda tidak dapat menggunakan makro ISR (), alih-alih gunakan arduino.cc/en/Reference/AttachInterrupt .
Jawaban:
Ya, tergantung laju jam dasar Arduino Anda. Sebagai contoh di sini adalah frekuensi input penghitung waktu dan periode setelah pra-penskalaan, untuk penghitung waktu pencacah ATMega2560 2, dan kecepatan clock dasar 16MHz. Timer memiliki opsi nilai "prescaler" yang menentukan frekuensi / periode, ditunjukkan pada tabel ini:
Untuk resolusi pengaturan waktu yang lebih baik, Anda menggunakan nilai yang disebut TCNT2. Ada build in counter yang beroperasi dari 0 hingga 255 karena timernya 8 bit. Ketika penghitung mencapai nilai yang diberikan oleh TCNT2 itu memicu interupsi. Gangguan ini disebut TIMER2_OVF_vect.
diberikan informasi ini, tingkat interupsi yang dihasilkan adalah: 16MHz / (prescaler * (255 - TCNT2))
Anda bisa menjalankan timer dengan kecepatan 16MHz (62.5nSec) penuh meskipun itu jauh lebih cepat dari yang Anda butuhkan; 2MHz dengan hitungan awal (255-2) akan memberi Anda tingkat interupsi 1MHz. Bagilah dengan 2 di ISR Anda:
Lembar data untuk MCU Anda adalah sumber daya dasar; artikel ini akan memberi Anda (dan memberi saya!) awal yang baik.
sumber
Mark, saya memutuskan untuk menulis satu set fungsi baru, berdasarkan Arduino Atmega328 Timer2, dan menggunakan overflow interupsi, untuk mendapatkan presisi hingga 0,5 us. Kode saya tersedia untuk diunduh dan digunakan di sini:
http://electricrcaircraftguy.blogspot.com/2014/02/Timer2Counter-more-precise-Arduino-micros-function.html
Berikut adalah deskripsi singkat: "Saya menulis" perpustakaan "untuk mendapatkan presisi 0,5us pada fungsi penggantian" micros () ", sehingga saya bisa mendapatkan hasil yang berulang dengan membaca sinyal PWM atau PPM, hingga dalam 1us. Saya mencari di sekitar internet dan tidak dapat menemukan sesuatu yang sebanding (atau yang mudah digunakan, dan mempertahankan kemampuan Arduino untuk menulis sinyal PWM melalui Servo Libary), jadi saya pikir ini adalah kontribusi utama pertama saya ke dunia Arduino dan Kontrol Radio. "
sumber
Jika jatuh ke Level AVR dapat diterima (seperti yang Anda sebutkan dalam pertanyaan Anda), Anda dapat mengatur timer dan bahkan mendapatkan detak jam AVR.
Anda perlu merujuk ke lembar data AVR Anda karena berbeda dalam ATMegas dan ATTinys yang berbeda. Tetapi prosedurnya selalu sama. Yang perlu Anda lakukan adalah:
TCCR
Dengan begitu bisa mendapatkan kutu yang tepat dari register penghitung waktu, namun Anda harus menghitung luapan secara manual. Ini setepat mungkin oleh teknologi.
Berikut adalah beberapa contoh kode untuk AT90S2313 yang sudah usang, tetapi ini memberi Anda petunjuk yang baik tentang apa yang harus dilakukan pada dasarnya:
sumber
TIMSK
,TOIE0
dll. (Menyalin penyetelan timer dari atmega328p datasheet). Sepertinya Anda tidak dapat menggunakan makro ISR (), alih-alih gunakan arduino.cc/en/Reference/AttachInterrupt .