Sabtu, 02 November 2013

Akurasi Timer/Counter pada AVR


Beberapa waktu yang lalu ada seorang kawan yang minta diajari membuat timer 1 detik menggunakan mikrokontroler. Kebetulan uC yang dia pakai Atmega8 dengan clock intenal.
Langsung aja tek bikinin pake CodeVision AVR  dengan memanfaatkan interrupt overflow pada timer0.
Pada CodeVision AVR terdapat fasilitas CodeWizard yang mempermudah kita dalam membuat program. Untuk mengaktifkan interrupt overflow timer0 kita tinggal memilih clock source, clock value, Overflow interrupt, dan timer value pada tab timer0.
Untuk membuat timer 1 detik dengan frekuensi clock uC 8MHz internal saya menggunakan parameter timer0 sebagai berikut.
  • Clock source = system clock
  • Clock value = 1000,000 kHz
  • Timer value = 0x9B
  •  Memberi centang pada kotak Overflow interrupt.
Pada proses diatas sebenarnya kita mengubah nilai pada register TCCR0, TCNT0 dan TIMSK. Tiga bit LSB dari register TCCR0 merupakan bit CS0 (Clock select) yang digunakan untuk menentukan frekuensi clock dari timer0.
Nilai bit CS02 s/d CS00 sesuai tabel 1 dibawah.
Tabel.1 Timer/Counter0 Prescaler

Karena menggunakan clock value 1000,000kHz (1MHz) yang berarti 1/8 dari frekuensi clock uC, maka register TCCR0 bernilai 0x02.
TCNT0 merupakan register yang bertugas untuk menghitung pulsa yang masuk kedalam timer0/counter0. Setelah program berjalan maka niai register ini akan bertambah satu setiap clock timernya dan akan mengalami overflow setelah mencapai nilai 0xFF. Ketika register TCNT0 mengalami overflow maka bit TOV0(Timer/Counter0 Overflow Flag) pada register TIFR (Timer/Counter Interrupt Flag Register) akan bernilai 1 dan akan kembali ke-0 jika rutin interrupsi dijalankan. Akan tetapi jika rutin interrupsi tidak diaktifkan maka nilai TOV0 akan tetap set(1) dan harus di clear (0) secara manual.
Nilai TCNT0 dapat diisi dengan nilai 0x00 s/d 0xFF. Nilai ini sebagai inisialisasi nilai timercounter yang kita buat. Pada proses menggunakan codeWizard diatas, saya memasukan nilai timer value 0x9B atau senilai dengan 155 desimal. Ini dimaksudkan untuk mempermudah perhitungan. Jika inisialisasi TCNT0 = 155 dan maksimal nilainya 255 maka nilai TCNT0 hanya akan menghitung sebanyak 100 pulsa. Setiap 100 pulsa timer/counter0 terjadi Overflow pada TOV0.
Memberi tanda centang pada Overflow interrup di CodeWizard dialog akan mengubah nilai register TIMSK(Timer/Counter Interrupt Mask Register). Timer/counter0 hanya memiliki fasilitas interrupt overflow. Jika ini diaktifkan maka Bit TOIE0(Timer/Counter Interrupt Enable) akan bernilai 1 (set). Bit TOIE0 ini berada pada bit ke-0 register TIMSK sehingga jika kita akan mengaktifkan timer0 Overflow interrupt maka nilai register TIMSK adalah 0x01.
Sedangkan untuk mengaktifkan fungsi interrupt global dengan menambahkan #asm(“sei”) yang artinya men-set enable interrupt. Dengan menambahkan perintah ini maka nilai bit I pada register SREG akan bernilai 1. Untuk meng-clear kan bit-I digunakan code #asm(“cli”).
Setelah di-generate maka akan dibuatkan template program sesuai kebutuhan kita. Untuk seting parameter timer0 dan interupsi terdapat pada subrutin void main(void) berikut.