Membuat stopwatch menggunakan mikrokontroler ATmega16 by muhammad kennedy ginting.
Dini akan diberikan penjelasan tentang timer0, timer1, counter0, counter1, skematik stopwatch dan list programnya.
Membuat Stopwatch Menggunakan Mikrokontroler ATMega16
1. Membuat Stopwatch Menggunakan Mikrokontroler ATMega16 by
Muhammad Kennedy Ginting
A. Deskripsi Umum
Bicara tentang stopwatch, benda ini adalah benda yang lumayan terkenal
dibidang olahraga pada umumnya. Kali ini saya ingin berbagi bagaimana
membuat stopwatch sederhana. Lebih tepatnya bisa di jadikan widget buatan
kita sendiri atau bisa Anda jadikan sebagai bahan untuk belajar serta refrensi.
Saya akan menggunakan LCD 16x2 dengan 3 switch button (Start, Stop,
Reset) dengan mikrokontroller Atmega16. Compiler yang digunakan yakni
Codevision AVR.
B. Spesifikasi Teknis dan Karakteristik
Aplikasi ini merupakan sebuah stopwatch sederhana yang dapat menghitung
sampai satuan waktu terkecil yaitu 1/100 detik atau 10 ms. Untuk
membangkitkan timer 10 ms saya menggunakan fitur timer0 mikrokontroller.
C. Daftar Komponen
1. Sistem Minimum Atmega16
ATmega16
IC 7805
Crystal 12MHz
Kapasitor 22pF (2), 100nF (4), 100uF(2)
2 Resistor 1KΩ
4 Switch Button
1x40 Female Header
1x40 Male Header
1N4002
2. LCD 16x2
3. Potensiometer 1KΩ
4. Battery 9V
5. Downloader AVR
D. Prinsip Kerja dan Rangkaian
Pada aplikasi ini terdapat 3 buah tombol (push button) yang terdiri dari
tombol START, STOP dan RESET. Tombol START digunakan untuk
memulai stopwatch, STOP digunakan untuk memberhentikan stowatch dan
tombol RESET untuk me-reset (menset ulang kembali nilai stopwatch).
Untuk counter (pencacah/penghitung) berbeda dengan timer, perbedaan yang
mendasar adalah pada sumber clocknya. Jika timer, sumber clocknya berasal
dari internal mikrokontroler dalam hal ini berasal dari kristal.
2. Sedangkan untuk counter sumber clocknya berasal dari luar mikrokontroler
(eksternal). Sebagai contoh counter, jika kita ingin menghitung banyaknya
barang yang lewat pada konveyor, maka sumber clocknya berasal dari sensor
yang mendeteksi barang saat melewatinya.
Pada Atmega16 terdapat 3 buah timer, yaitu Timer0 (8 bit), Timer1 (16 bit)
dan Timer2 (8 bit). Untuk perbedaan dan cara kerja masing-masing timer,
teman-teman dapat membacanya pada datasheet. Disini saya akan coba
membahas Timer0 dan Timer1 saja. Untuk lebih jelasnya silakan download
datasheet ATmega8535 disini.
Perhitungan untuk Timero dan Timer1 adalah sebagai berikut:
Ttimer0 = Tosc*(256-TCNT0)*N → (8 bit = 256)
Ttimer1 = Tosc*(65536-TCNT1)*N → (16 bit = 65536)
Tosc = 1/Fosc → pada aplikasi ini saya menggunakan kristal 12 MHz,
sehingga:
Tosc = 1/12Mhz = 0,0000000833 detik
Dimana:
Ttimer0 = lamanya periode Timer0
Ttimer1 = lamanya periode Timer1
TCNT0 = Register Timer0
TCNT1 = Register Timer1
N = Skala clock (mempunyai nilai 1, 8, 64, 256 dan 1024)
Tosc = periode clock
Fosc = frekuensi clock kristal
Timer
Sekarang saya akan membuat aplikasi timer yang ditampilkan pada LCD,
cara kerjanya pada LCD akan menampilkan nilai awal yaitu 0 kemudian
setelah 1 detik (menggunakan timer) nilai tersebut akan naik menjadi 1,
kemudian 2 dan seterusnya, jika sudah sampai 100 maka akan diset kembali
menjadi 0.
Berikut adalah skematiknya:
3. Gambar 1. Skematik Untuk Timer1 dan Timer0
Menggunakan Timer1:
Ttimer1 = Tosc*(65536-TCNT1)*N
Pada aplikasi diatas diinginkan lamanya timer adalah 1 detik (Ttimer1 = 1
detik) dan jika saya menggunakan kristal 12 MHz dan menggunakan skala
clock N = 1024, maka didapat:
1 = 0,0000000833*(65536-TCNT1)*1024
TCNT1= 53818 = D23A (dalam hexa)
Dari perhitungan diatas didapat nilai 53818 atau dalam hexa D23A, nilai
tersebut harus diisikan pada register TCNT1 agar Timer 1 bernilai 1 detik.
Berikut adalah gambar untuk mensetting pada CodeVision CodeWizard
AVR:
Gambar 2. Setting Pada Timer1
5. interrupt [TIM1_OVF] void timer1_ovf_isr(void)
{
// Reinitialize Timer1 value
TCNT1H=0xD23A >> 8;
TCNT1L=0xD23A & 0xff;
// Place your code here
data++;
}
// Declare your global variables here
void main(void)
{
// Declare your local variables here
// Input/Output Ports initialization
// Port A initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In
Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T
State0=T
PORTA=0x00;
DDRA=0x00;
// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In
Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T
State0=T
PORTB=0x00;
DDRB=0x00;
// Port C initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In
Func0=In
6. // State7=T State6=T State5=T State4=T State3=T State2=T State1=T
State0=T
PORTC=0x00;
DDRC=0x00;
// Port D initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In
Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T
State0=T
PORTD=0x00;
DDRD=0x00;
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
// Mode: Normal top=0xFF
// OC0 output: Disconnected
TCCR0=0x00;
TCNT0=0x00;
OCR0=0x00;
// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 11,719 kHz
// Mode: Normal top=0xFFFF
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer1 Overflow Interrupt: On
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x05;
7. TCNT1H=0xD2;
TCNT1L=0x3A;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer2 Stopped
// Mode: Normal top=0xFF
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;
// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// INT2: Off
MCUCR=0x00;
MCUCSR=0x00;
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x04;
// USART initialization
// USART disabled
UCSRB=0x00;
// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
8. ACSR=0x80;
SFIOR=0x00;
// ADC initialization
// ADC disabled
ADCSRA=0x00;
// SPI initialization
// SPI disabled
SPCR=0x00;
// TWI initialization
// TWI disabled
TWCR=0x00;
// Alphanumeric LCD initialization
// Connections are specified in the
// Project|Configure|C Compiler|Libraries|Alphanumeric LCD menu:
// RS - PORTC Bit 0
// RD - PORTC Bit 1
// EN - PORTC Bit 2
// D4 - PORTC Bit 4
// D5 - PORTC Bit 5
// D6 - PORTC Bit 6
// D7 - PORTC Bit 7
// Characters/line: 16
lcd_init(16);
// Global enable interrupts
#asm("sei")
while (1)
{
// Place your code here
if (data==100)
{
9. lcd_clear();
data=0;
}
lcd_gotoxy(0,0);
lcd_putsf("Uji Coba Timer1");
itoa(data,temp); //menampilkan di LCD
lcd_gotoxy(0,1);
lcd_puts(temp);
}
}
Menggunakan Timer0:
Ttimer0 = Tosc*(256-TCNT0)*N
Dengan menggunakan Timer0, untuk aplikasi yang sama seperti diatas,
sebenarnya timer0 ini tidak dapat menghasilkan periode timer selama 1 detik
dikarenakan keterbatasan jumlah bit yaitu hanya 8 bit (256) saja. Tetapi kita
masih dapat memanupulasi program agar dapat menghasilkan timer selama 1
detik, caranya dengan membuat timer selama 10 ms kemudian dilakukan
pengulangan sebanyak 100 kali, maka akan dihasilkan timer selama 1 detik.
10 ms * 100= 1 detik
Pada aplikasi ini diinginkan lamanya timer adalah 10 ms (Ttimer0=10
ms=0.01 s) dan jika saya menggunakan kristal 12 MHz dan menggunakan
skala clock N = 1024, maka didapat:
0.01 = 0,0000000833*(256-TCNT0)*1024
TCNT0= 138 = 8A (dalam hexa)
Dari perhitungan diatas didapat nilai 138 atau dalam hexa 8A, nilai tersebut
harus diisikan pada register TCNT0 agar Timer 0 bernilai 10 mili detik.
Berikut adalah gambar untuk mensetting pada CodeVision CodeWizard
AVR:
13. OCR0=0x00;
// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer1 Stopped
// Mode: Normal top=0xFFFF
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer2 Stopped
// Mode: Normal top=0xFF
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;
// External Interrupt(s) initialization
14. // INT0: Off
// INT1: Off
// INT2: Off
MCUCR=0x00;
MCUCSR=0x00;
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x01;
// USART initialization
// USART disabled
UCSRB=0x00;
// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;
// ADC initialization
// ADC disabled
ADCSRA=0x00;
// SPI initialization
// SPI disabled
SPCR=0x00;
// TWI initialization
// TWI disabled
TWCR=0x00;
// Alphanumeric LCD initialization
// Connections are specified in the
// Project|Configure|C Compiler|Libraries|Alphanumeric LCD menu:
// RS - PORTC Bit 0
// RD - PORTC Bit 1
15. // EN - PORTC Bit 2
// D4 - PORTC Bit 4
// D5 - PORTC Bit 5
// D6 - PORTC Bit 6
// D7 - PORTC Bit 7
// Characters/line: 16
lcd_init(16);
// Global enable interrupts
#asm("sei")
while (1)
{
// Place your code here
if (data==100)
{
lcd_clear();
data=0;
}
lcd_gotoxy(0,0);
lcd_putsf("Uji Coba Timer0");
itoa(data,temp); //menampilkan di LCD
lcd_gotoxy(0,1);
lcd_puts(temp);
}
}
Counter
Untuk aplikasi counter lebih mudah dibandingkan dengan timer, karena kita
tidak harus lagi menghitung untuk mendapatkan nilai dari register TCNT,
tetapi secara otomatis register TCNT yang akan mencacah jika ada input yang
masuk.
16. Berikut adalah aplikasi counter untuk menghitung dan ditampilkan pada
LCD, input yang digunakan berasal dari pushbutton. Berikut adalah
schematicnya:
Gambar 4. Skematik Untuk Counter0 dan Counter1
Counter0
Input untuk counter0 berasal dari pin T0 atau PB0. Counter0 hanya mampu
mencacah sampai dengan nilai 256 dikarenakan counter 8 bit. Berikut adalah
setting pada CodeVision CodeWizard AVR:
Gamabar 5. Setting Pada Counter0
Berikut adalah listing program lengkap:
/*****************************************************
This program was produced by the
CodeWizardAVR V2.05.3 Standard
19. // OC0 output: Disconnected
TCCR0=0x06;
TCNT0=0x00;
OCR0=0x00;
// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer1 Stopped
// Mode: Normal top=0xFFFF
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer2 Stopped
// Mode: Normal top=0xFF
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
20. OCR2=0x00;
// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// INT2: Off
MCUCR=0x00;
MCUCSR=0x00;
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x00;
// USART initialization
// USART disabled
UCSRB=0x00;
// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;
// ADC initialization
// ADC disabled
ADCSRA=0x00;
// SPI initialization
// SPI disabled
SPCR=0x00;
// TWI initialization
// TWI disabled
TWCR=0x00;
// Alphanumeric LCD initialization
// Connections are specified in the
21. // Project|Configure|C Compiler|Libraries|Alphanumeric LCD menu:
// RS - PORTC Bit 0
// RD - PORTC Bit 1
// EN - PORTC Bit 2
// D4 - PORTC Bit 4
// D5 - PORTC Bit 5
// D6 - PORTC Bit 6
// D7 - PORTC Bit 7
// Characters/line: 16
lcd_init(16);
while (1)
{
// Place your code here
data=TCNT0;//hasil counter (TCNT0) dipindah ke data
if (data>=256)
{
lcd_clear();
}
lcd_gotoxy(0,0);
lcd_putsf("Uji Coba Counter0");
itoa(data,temp); //menampilkan di LCD
lcd_gotoxy(0,1);
lcd_puts(temp);
}
}
Counter1
Counter1 tidak jauh berbeda dengan counter0, hanya saja maksimum
pencacahan counter1 sampai 65536 dikarenakan counter 16 bit, dan input
untuk counter1 berasal dari pin T1 atau PB1. Untuk settingan dan program
pada CodeVision AVR hampir sama dengan counter0, jadi tidak akan saya
jelaskan lagi disini.
Langsung saja ke skematik rangkaian stopwatch.
25. void tampil_lcd()
{
lcd_gotoxy(0,0);
sprintf(temp,"Timer %d:%d:%d:%d",jam,menit,detik,count);
lcd_puts(temp);//tampilkan waktu di LCD baris pertama
if (indeks==0)
{
lcd_gotoxy(0,1);
lcd_putsf("START");
}
if (indeks==1)
{
lcd_gotoxy(0,1);
lcd_putsf("STOP");
}
if (indeks==2)
{
lcd_gotoxy(0,1);
lcd_putsf("START RESET");
}
}
// Declare your global variables here
void main(void)
{
// Declare your local variables here
// Input/Output Ports initialization
// Port A initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In
Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T
State0=T
PORTA=0x0f;