Saya mencoba memeriksa frekuensi Timer3 menggunakan penghitung. Nilai penghitung, dinyatakan sebagai volatile, bertambah dalam ISR dan setiap detik jumlahnya ditampilkan dalam loop utama dan nilai reset ke nol.
Timer telah diatur dengan benar. (Jika saya memilih timer 3Hz saya bisa melihat led berkedip)
Masalah
Penghitung tidak bertambah. Berikut hasilnya:
Setup Completed
tick: 1
tick: 0
tick: 0
tick: 0
KODE
volatile int cont = 0;
void setup()
{
Serial.begin(9600);
pinMode(13, OUTPUT);
// Initialize Timer
cli(); // disable global interrupts
TCCR3A = 0; // set entire TCCR3A register to 0
TCCR3B = 0; // same for TCCR3B
// set compare match register to desired timer count: 800 Hz
OCR3B = 20; // 800Hz 5; // 3 Hz
// turn on CTC mode:
TCCR3B |= (1 << WGM12);
// Set CS10 and CS12 bits for 1024 prescaler:
TCCR3B |= (1 << CS30) | (1 << CS32);
// enable timer compare interrupt:
TIMSK3 |= (1 << OCIE3B);
// enable global interrupts:
sei();
Serial.println("Setup completed");
}
void loop()
{
if (millis() % 1000 == 0)
{
Serial.print(" tick: ");
Serial.println(cont);
cont = 0;
}
}
ISR(TIMER3_COMPB_vect)
{
//digitalWrite(13, digitalRead(13) ^ 1);
cont++;
}
EDIT Timer ini digunakan untuk membaca nilai anlog dari accelerometer dan menyimpannya dalam array float. Tetapi pada saat ini saya terjebak pada masalah pembaruan ini.
SOLUSI 1 Terima kasih untuk Gerben
volatile int cont = 0;
void setup()
{
Serial.begin(9600);
pinMode(13, OUTPUT);
// Initialize Timer
cli(); // disable global interrupts
TCCR3A = 0; // set entire TCCR3A register to 0
TCCR3B = 0; // same for TCCR3B
// set compare match register to desired timer count: 800 Hz
OCR3A = 20; // 20; //800Hz 5; // 3 Hz
// turn on CTC mode:
TCCR3B |= (1 << WGM32);
// Set CS10 and CS12 bits for 1024 prescaler:
TCCR3B |= (1 << CS30) | (1 << CS32);
// enable timer compare interrupt:
TIMSK3 |= (1 << OCIE3B);
// enable global interrupts:
sei();
Serial.println("Setup completed");
}
void loop()
{
delay(1000);
Serial.println(cont);
cont = 0;
}
ISR(TIMER3_COMPB_vect)
{
cont++;
}
SOLUSI 2 Terima kasih kepada BrettM
volatile int cont = 0;
void setup()
{
Serial.begin(9600);
pinMode(13, OUTPUT);
// Initialize Timer
cli(); // disable global interrupts
TCCR3A = 0; // set entire TCCR3A register to 0
TCCR3B = 0; // same for TCCR3B
// set compare match register to desired timer count: 800 Hz
OCR3B = 20; //800Hz 5; // 3 Hz
// turn on CTC mode:
//TCCR3B |= (1 << WGM32);
// Set CS10 and CS12 bits for 1024 prescaler:
TCCR3B |= (1 << CS30) | (1 << CS32);
// enable timer compare interrupt:
TIMSK3 |= (1 << OCIE3B);
// enable global interrupts:
sei();
Serial.println("Setup completed");
}
void loop()
{
Serial.println(cont);
cont = 0;
delay(1000);
}
ISR(TIMER3_COMPB_vect)
{
TCNT3 = 0;
cont++;
}
digitalWrite
baris Anda melihat LED berkedip sekali per detik (setiap 0,66)?digitalWrite
dan aturOCR3B = 5;
led berkedip kira-kira pada frekuensi itu.cont = 0;
dalam loop? Lalu apa yang terjadi?Jawaban:
Dalam mode CTC bagian atas adalah
OCR3A
, bukanOCR3B
!Setelah itu
TIMSK3 |= (1 << OCIE3B);
juga harus diubah menjadiTIMSK3 |= (1 << OCIE3A);
, danISR(TIMER3_COMPB_vect)
menjadiISR(TIMER3_COMPA_vect)
Untuk 3Hz,
OCR3A
harus 5208, bukan 20.Secara teknis
TCCR3B |= (1 << WGM12);
seharusnyaTCCR3B |= (1 << WGM32);
sumber
TIMSK3 |= (1 << OCIE3B);
. Gerben terima kasih! Harap modifikasi jawaban Anda dan saya akan menerimanya sebagai solusi.ISR(TIMER3_COMPB_vect)
seharusnyaISR(TIMER3_COMPA_vect)
. Jika ISR tidak ditentukan, AVR akan mereset sendiri, seperti yang Anda alami. Senang Anda berhasil.Tampaknya jawaban saya untuk pertanyaan ini sebelumnya tidak lengkap, terima kasih telah menunjukkan bahwa mode CTC hanya berfungsi dengan OCR3A Gerben. Saya minta maaf karena tidak menguji jawaban sebelum mengirimnya.
Mengingat informasi hanya dalam pertanyaan ini, jawaban Gerben lengkap, tetapi karena pertanyaan Anda yang lain menyiratkan bahwa Anda tidak dapat menggunakan OCR3A karena perpustakaan Servo saya akan menambahkan sedikit. (Saya juga mengedit jawaban itu)
Anda dapat meniru perilaku mode CTC dengan mengatur TCNT3 ke 0 dalam rutinitas interupsi Anda. Ingatlah untuk menghapus baris yang mengaktifkan mode CTC dalam kode Anda.
Saya telah menguji kode Anda dengan ISR ini:
dan konfigurasi pengatur waktu ini
Ini mungkin sedikit kurang akurat pada frekuensi tinggi daripada CTC, saya tidak yakin, tetapi pada 3Hz itu bekerja dengan sempurna. Perhatikan bahwa 5208 adalah nilai OCR yang benar, bukan 20 (sekali lagi terima kasih kepada Gerben).
sumber
TCNT3=0;
di ISR () dan menghapus//TCCR3B |= (1 << WGM32);
di setup () seperti yang Anda katakan. Saya juga sudah mencoba berkomentarcont=0;
tapi tidak ada yang berubahprintln(cont); delay(1000);
. Anda juga masih termasuk bit dengan cli () dan TCCR3A dll yang benar?