- COUNTER/TIMER , apaan sih ?
Adalah fasilitas di microcontroller untuk melakukan counter/perhitungan tanpa perlu menambahkan code di looping main program ( auto), sehingga nilai dari counter ( BIASANYA register TCNT) dapat di olah/manfaatkan sewaktu2
- JENIS COUNTER APA AJA ?
Secara umum Counter /Timer terdiri dari:
- Timer Biasa (8 bit & 16 bit)
- Clear Timer on Compare (CTC)
- Overflow Timer
- Output Compare
- PWM timer ( bahasan tersendiri)
Kita bahas yang paling sering digunakan timer biasa dan timer CTC.
- Counter 8 bit & 16 Bit
Jadi ingat, 8 bit itu maximum nilai yg didapat 0 - 255, sedangkan 16 bit = 0 - 65535 , jadi berbeda di range nilai Counternya.
Semisal kita pakai IC attiny2313 dengan clock default 1MHZ, jadi jika kita dapat ambil matematika sederhana :
resolusi = 1/input clock = 1/1Mhz = 1 micro second
Jika kita inisialisasi counter dengan Full Speed , clock = input frek oscillator (1 Mhz), dan digunakan 16 bit / counter 1 TCCR1B|=(1<<CS10), maka jika kita ingin menghidupkan suatu led di PortD dalam selang 1 detik, kita tunggu nilai Counter(TCNT1) = 1000000;
wah....kelebihan ! Ingat..nilai TCNT1 max= 65535, jadi kita perlu membagi counter dengan variabel yg lain, semisal kita pake variable a; Jadi ketika TCTN1 = 10000; Lalu reset TCTN1=0 ; a++; (ditambah), berulang seterusnya sampe nilai a= 100; maka LED di PORTD dihidupkan/toogle. Berikut scriptnya :
Code:
#include <avr/io.h> int main (void) { DDRD |= (1 << PD0); // Set LED di portD0 TCCR1B |= (1 << CS10); // Set up counter dengan full speed int a; variable a=0; //nilai awal dari variable while (1) { if(TCNT1 == 10000) { a++; TCNT1=0; } if(a == 100) { PORTD ^= (1 << PD0); // Toggle the LED a=0; } } }
- PRESCALER
Jika di pembahasan sebelumnya, kita menggunakan variabel sebagai pembagi counter yg berlebih, AVR memberikan suatu solusi dengan melakukan pembagian clock menjadi faktor 1/8, 1/64, 1/256, dan 1/1024
Dengan Prescaler ada pembagian resolusi ( timer penambahan counter) yang akan menjadi berkurang :
1(full speed) = 1 micro second
1/8 = 8 micro second
1/64 = 64 us
1/256= 256 us
1/1024=1024us
Nah...kita sekarang bisa membagi clock sesuai keinginan, dan menyederhanakan perhitungan
Semisal kita ingin mendelay LED 1 detik, dengan clock 1Mhz maka kita coba dengan prescale 1/8, untuk mencari 1 detik nilai TCNT1 = 125000, masih lewat, prescale 1/64 maka nilai TCNT1 = 15625 ...nahh nilainya ga lewat dari batas 16 bit (65535) ....ketemu dehh....jadi kita sederhanakan script sebelumnya menjadi :
Code:
#define F_CPU 1000000UL //clock dari avr #include <avr/io.h> int main (void) { DDRD |= (1 << PD0); // Set LED di portD0 TCCR1B |= (1 << CS11); // Set up counter dengan prescale 64 //Baca datasheet untuk mencari konfigurasi prescaler yg laen while (1) { if(TCNT1 == 15624) // nilai max 1 detik, perhitungan mulai 0 maka nilai dikurangi 1 dari 15625 { PORTD ^= (1 << PD0); // Toggle the LED TCNT1=0; } } }
- CLEAR TIME ON COMPARE + INTERUPT
selanjutnya AVR memberikan failitas CTC, yaitu kita menentukan nilai maximum dari TCNT1 dan secara otomatis akan mengclear nilai TCNT1. Nilai max dari TCNT1 diberikan melalui register OCR1A
setiap kali TCNT1 = OCR1A akan terjadi trigger interupt CTC, sehingga dapat dimanfaatkan untuk mentriger suatu output. codenya akan menjadi seperti ini
Code:
#define F_CPU 1000000UL //clock dari avr
#include <avr/io.h>
#include <avr/interrupt.h>
ISR(TIMER1_COMPA_vect) //vector interupt compare
{
PORTD ^= (1 << PD0); // Toggle the LED
}
int main (void)
{
DDRD |= (1 << PD0); // Set LED di portD0
TCCR1B |= (1 << CS11); // Set up counter dengan prescale 64
//Baca datasheet untuk mencari konfigurasi prescaler yg laen
TCCR1B |= (1 << WGM12); // Configure timer 1 for CTC mode
TIMSK |= (1 << OCIE1A); // Enable CTC interrupt
OCR1A = 15624; // nilai atas dari TCNT1, untuk perhitungan 1 detik
sei(); //hidupkan interupt
while (1)
{
}
}
Untuk counter dengan nilai frekuensi clock / XTAL lainnya dapat menggunakan rumus matematika sederhana untuk menetukan OCR1A
OCR1A = [(Frekuensi AVR / Prescale) / frekuensi yg diinginkan ] - 1
atau
OCR1A = [(Frekuensi AVR / Prescale) * Periode yg di inginkan ] - 1
*) catatan : nilai prescale = 1,8,64,256,1024 bukan 1/prescale , untuk mempermudah saja
SELAMAT MENCOBA
0 komentar:
Posting Komentar