Subscribe via email

Enter your email address:

Delivered by FeedBurner

Bermain dengan Timer 1 AVR


Yang namanya timer sering kali kita gunakan. Misal saat mau nampilin rpm, kita butuh timer sebagai acuan. Atau untuk menghidupkan device dengan interval tertentu.
AVR yang saya pakai sebagai contoh adalah ATmega 8535. AVR ini memilki 3 timer. Yaitu:

  1. TIMER 0 (8 bit)
  2. TIMER 1 (16 bit)
  3. TIMER 2 (8 bit)
Apa yang dimaksud timer 8 bit dan 16 bit?
timer 8 bit adalah timer yg bisa mencacah/menghitung sampai maksimal nilai 0xFF heksa (dalam biner = 1111 1111). Pada ATmega 8535 ada 2 timer jenis ini yaitu TIMER 0 dan 2
Klo yg 16 bit nilai maksimalnya 0xFFFF. Pada ATmega8535 timer jenis 16 bit adalah TIMER 1. Artikel kali ini akan membahas TIMER 1.
Dulu ak disaranin klo timer mau presisi harus memakai bahasa assembly. Hitung jumlah instruksi yg kita tulis. lalu hitung lama waktunya. Hmmmm.. ribet bener...
Untung aja nemu artikel tentang interrupt timer. Dengan Interrupt kita gak perlu susah2 menghitung berapa waktu yang di perlukan untuk meng eksekusi seluruh program kita. Karena saat program dijalanin, timer juga jalan sendiri (digerakkan XTAL). Trus saat nilai tercapai terjadilah interrupt timer.
Register yg biasa saya gunakan untuk menset nilai Timer1 adalah register TCNT, register TCNT sendiri dibagi dua: TCNT 1 H dan TCNT 1 L.
rumus yang digunakan adalah :
TCNT = (1+0xFFFF) - (waktu *( XTAL / prescaler) )
waktu --> waktu yg kita inginkan
XTAL --> frekuensi xtal yg dipakai
prescaler --> nilai prescaler
Apa nilai prescaler itu?
Timer membutuhkan clock source. Biasanya clock source yg saya pakai adalah clock sistem (XTAL). Dan kita bisa menset besarnya nilai ini. Maximum sama dengan XTAL, minimum XTAL/1024. Nah nilai pembagi (1024) ini yg disebur nilai prescaler.
Macam2 nilai prescaler yg diijinkan: 1, 8 , 64 , 256 , 1024
Untuk mengubah nilai prescaler timer 1, kita harus merubah nilai register TCCR1B bit 0...2
image
gambar diatas di ambil dari data sheet ATmega 8535 hal.113
Contoh Program:
Mengakses Timer 1 dengan interval waktu 1 detik.
#include <mega8535.h>
#include <stdio.h>
// LCD di PORT B
#asm
.equ __lcd_port=0x18
#endasm
#include <lcd.h>

unsigned char buff[30];
unsigned long detik;

// sub rutin saat terjadi interrupt Timer 1
interrupt [TIM1_OVF] void timer1_ovf_isr(void)
{
TCNT1H=0xC2;
TCNT1L=0xF7;
detik++;
lcd_clear();
sprintf(buff,"detik %d",detik);
lcd_puts(buff);
}
void main(void)
{

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: kHz
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
TCCR1A=0x00;
TCCR1B=0x04;
TCNT1H=0xC2;
TCNT1L=0xF7;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x04;
// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
// Analog Comparator Output: Off
ACSR=0x80;
SFIOR=0x00;
// LCD module initialization
lcd_init(16);
// Global enable interrupts
#asm("sei")
lcd_putsf("wait...");
while (1)
{

};
}
Program di atas menggunakan timer 1 untuk menambah nilai variabel "detik" setiap 1 detik sekali. Kemudian menampilkan hasilnya ke LCD.
ayo kita mutilasi code program di atas:
yang akan kita bahas dari program diatas adalah code yang kliatan ruwet aja. Klo yg biasa silahkan lihat di artikel2 sebelumnya .. ^_^
**************
// LCD di PORT B
#asm
.equ __lcd_port=0x18 -------------->> mendefinisakan bahwa LCD di hubungkan ke PORT B
#endasm
#include <lcd.h> --------------->> library untuk fungsi2 akses LCD
**************
// sub rutin saat terjadi interrupt Timer 1
interrupt [TIM1_OVF] void timer1_ovf_isr(void)
{
TCNT1H=0xC2; ----------------------> nilai didapat dari rumus ......
TCNT1L=0xF7; ----------------------> ....agar Timer 1 bernilai 1 detik
detik++;
lcd_clear();
sprintf(buff,"detik %d",detik); --------------> memasukkan karakter-karakter ke variabel buff
lcd_puts(buff); --------------------------->menampilkan karakter-karakter variabel buff ke LCD
}
Saat kita ingin menampilkan sederet tulisan ke LCD maka kita harus memasukkan karakter-karakter tulisan itu ke suatu variabel array (dalam program di atas adalah variabel "buff"). Baru kemudian data yg ada di variabel array kita tampilkan ke LCD
***************

void main(void)
{

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: kHz
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
TCCR1A=0x00;
TCCR1B=0x04; ------------------> prescaler 256
TCNT1H=0xC2; ------------------> nilai didapat dari rumus ......
TCNT1L=0xF7; ------------------> ....agar Timer 1 bernilai 1 detik

inget rumus: TCNT = (1+0xFFFF) - (waktu *( XTAL / prescaler) )
waktu yg dinginkan adalah 1 detik , XTAL yg saya pakai adl 4 Mhz dan nilai prescaler=256
Jadi,...............
TCNT= (1+65535)-(1detik * (4.000.000/256))
=65536 - (1detik*15625)
=65536-15625
= 49911 (desimal)
= C2F7 (heksadesimal)
Nilai untuk TCNT yang di dapat dari rumus bernilai 16bit (4 angka Heksadesimal), 2 angka yg di depan kita masukkan ke TCNT1H dan 2 angka yg dibelakang kita masukkan ke TCNT1L
****************
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x04; ----------------->Timer/Counter1, Overflow Interrupt Enable
code di atas hanya men set "Overflow Interrupt Timer 1". Interrupt baru aktif saat ada perintah: #asm("sei")


pada contoh ini saya pake ATmega 8535, ketika saya coba untuk ATmega 162 nilai TIMSK diubah menjadi TIMSK=0x80;
****************
// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
// Analog Comparator Output: Off
ACSR=0x80; ------------> me OFF kan analog comparator
SFIOR=0x00;
jika tidak dipakai, sebaiknya analog comparator di OFF. Untuk menghemat pemakaian daya. Hal ini sangat penting jika sumber daya yg digunakan memakai baterai.
*******************
// LCD module initialization
lcd_init(16); ----------------------> inisialisasi LCD 16*2
*******************
// Global enable interrupts
#asm("sei") ----------------------> meng aktifkan Interrupt-interrupt yg sudah di set sebelumnya
Nah... pada saat ini interrupt Timer 1 aktif
*******************
lcd_putsf("wait..."); --------------> menampilkan tulisan wait.. ke LCD
*********************
while (1)
{

};
Program ini yg dijalankan oleh microcontroller... mikro hanya muter disini di dalam while(1){...};
(inget !!! infinite looping di artikel BASIC I/O ).. Jadi mikro sama sekali tidak mengeksekusi perintah.
lha kok bisa????? bingungg.... ~_~ !
Disinilah bedanya pake Interrupt!!.
saat terjadi Interrupt Timer1, alur program mikro akan meloncat ke:
// sub rutin saat terjadi interrupt Timer 1
interrupt [TIM1_OVF] void timer1_ovf_isr(void)

{
......................................
......yoww..... program yg ada disini yg dijalanin...
......................................
}
setelah program yg ada di sub rutin INTERRUPT dijalankan, maka alur program mikro akan muter2 lagi di infinite looping
******************
jika ada yg kurang dari program di atas mohon kritik dan sarannya
any questions?? post comment on this blog: http:\\avrku.blogspot.com
or send email to: [email protected]
CodeVisionAVR C Compiler is copyright by Pavel Haiduc, HP InfoTech s.r.l.
AVR is a registered trademark of Atmel Corporation.

<

Comments :

13 comments to “Bermain dengan Timer 1 AVR”

keren

kiddieez mengatakan...
on 

mas, kalo program yang ngga pake interrupt gmn mas?
apa emang harus pake interrupt?
masalahnya kan timer per detik mau saya gunakan sebagai counter per detik dalam perulangan....

contohnya kaya tek masukin dalam while (i < 10 /*detik*/) /*10 detik ini diperoleh dari perhitungan timer tadi gitu mas*/
{
................
i++;
}kalo kaya gitu gmn mas?
bales y mas,,, tulung pisan....
masalahnya kalo pake pake perulangan biasa, angka 10 itu hukan detik tapi g tau (1/berapa) kali detiknya mas, cepet pisan

Anonim mengatakan...
on 

@anonim:
klo memang butuh presisi setauku yg paling enak pake timer(gk tau lagi sich klo ada referensi yg lebih oke... :P)


definisi nilai yg mo dihitung:
unsigned int freq,cacah;

masukin nilai yang mau dihitung dalam
looping program utama
while(1)
{
if(PINB.0==0)cacah++;
while(PINB.0==0);
}

nilai cacah akan bertambah setiap PINB.0 berubah dari High ke Low.

masukkan nilai cacah ke freq melalui interupsi timer.

// sub rutin saat terjadi interrupt Timer 1
interrupt [TIM1_OVF] void timer1_ovf_isr(void)
{
TCNT1H=0xC2;
TCNT1L=0xF7;
freq=cacah;
cacah=0;
lcd_clear();
sprintf(buff,"freq %d",freq);
lcd_puts(buff);
}

nah nilai frequensi akan di update setiap 1 detik...

zigan
[email protected]
mengatakan...
on 
Komentar ini telah dihapus oleh pengarang.
prezst mengatakan...
on 

mas, mau tanya apakah ada perbedaan, saat kita menggunakan nilai prescaler yg gede ama yg kecil pada sistem yang akan kita kontrol?pengaruhnya pada AVR apa?suwun...

prezst mengatakan...
on 

itu hanya berpengaruh pada seberapa cepat clock timer yang akan kita gunakan..
jadi sumber clock timer untuk contoh di program diatas kan dari xtal yang digunakan oleh microcontroller dibagi dengan nilai prescaler

zigan mengatakan...
on 

bisa tidak timernya se jam ataw lebih..?

oon mengatakan...
on 

bisa aja,
timernya kan di set tiap satu detik.. jadi tinggal masukin varibel trus setiap timer aktif, nilai variabel tersebut di increment..
pas nilai nya = 3600 maka itu dah satu jam ^_^

zigan mengatakan...
on 

Mantap TImer avr. kalo mau belajar lebih jauh dengan CVAVR kunjungi blog saya
http://iswanto.staff.umy.ac.id/ dan http://blog.umy.ac.id/iswanto

iswanto mengatakan...
on 

om program parallax ping yang buat ngukur jarak gmn ya?????mohon bantuanya om......tapi pake codevisionavr ya om.....makasih..

Anonim mengatakan...
on 

bang saya mau tanya klo timer saya gunakan buat ngitung lebar pulsa nya gmana , ?? jadi bisa dilihat waktu T high nya sama T low nya makasih

coky_coky11.blogspot.com mengatakan...
on 

infonya membantu sekali, biar lebih mudah bisa pke wizard dari codevision. salam avr mania,,

Kiki 'Kaye' mengatakan...
on 

maturnuwun infonya, ikut belajar disini ya

anotherorion mengatakan...
on