11. Timer & Counter Pada ATMEGA 16/32/8535
11. Timer & Counter Pada ATMEGA 16/32/8535

Pengantar

Tujuan Pembahasan timer dan counter AVR :

  1. Melaksanakan tugas tertentu secara berulang  (mode normal).
  2. Menghitung panjang pulsa (input capture)
  3. Menghitung banyaknya event (sebagai counter)
  4. Mengendalikan kecepatan motor DC (Pulsa Wide Modulation /PWM)
  5. Membuat penundaan waktu (delay)
  6. Sinyal generator

Register yang digunakan untuk mendukung operasi Timer Counter pada AVR :

  • Register TCNT --> Register pencacah dari 0 sampai nilai maximum yg kita tentukan.
  • Register TCCR --> Untuk pengaturan mode  operasi Timer/Counter
  • Register TIMSK --> Untuk  memilih Timer/Counter mana yg aktif.
  • Register TIFR --> Untuk mengetahui adanya interupsi akibat operasi Timer/Counter .
  • Register OC (Output Compare) -->Untuk menyimpan nilai pembanding dengan nilai pada register  TCNT.

Komponen utama Timer/Counter adalah sebuah register yg tugasnya hanya berhitung dari 0 sampai batas maximumnya, register ini pada AVR disebut register TCNT. Misal: register TCNT0    8 bit (nilai maksimunya = 255).

Timer pada dasarnya hanya menghitung pulsa clock. Frekuensi pulsa clock yang dihitung tersebut bisa = frekuensi kristal terpasang atau dapat diperlambat menggunakan prescaler.

Saat akan menghitung suatu event, hubungkan sumber event eksternal ke pin clock register counter. Ketika terjadi suatu event eksternal, maka isi counter akan dicacah naik (increment). Dengan cara ini, isi counter merepresentasikan banyaknya event yang terjadi.

Saat akan membangkitkan waktu tunda, hubungkan osilator ke pin clock counter. Jika osilator memicu, maka isi counter akan mencacah naik. Isi register counter menunjukkan berapa banyak pemicuan yang telah terjadi sejak dilakukan clear pada counter. Karena kecepatan osilator dalam mikrokontroler diketahui, maka anda dapat menghitung periode pemicuan. Dari isi register counter anda dapat mengetahui berapa lama waktu yang telah berlalu.

Contoh: (Untuk membangkitkan waktu tunda)

Metode Pertama, bersihkan (clear) isi counter dan tunggu hingga counter mencapai bilangan tertentu. Misal, mikrokontroler AVR dengan osilator 8 MHz; berarti isi register counter di increment setiap sekali dalam 125 ns (1/8 MHz). Jadi, jika kita menghendaki waktu tunda 1000 ns maka kita harus meng-clear counter terlebih dahulu kemudian menunggu register counter hingga mencapai angka 8 (8 x 125 ns = 1000 ns = 1 us).

Setiap counter mempunyai Flag (di-set ketika terjadi oveflow pada counter bersangkutan dan di-clear menggunakan software). Metode kedua, isi (load) register counter dan tunggu hingga terjadi overflow (flag di-set). Misal, mikrokontroler dengan frekuensi 8 MHz dengan register counter 8-bit, jika kita menghendaki waktu tunda sebesar 500 ns, isi (load) register counter dengan 0xFC dan menunggu hingga flag di-set (sesudah pemicuan keempat). Setelah pemicuan pertama terjadi, register counter berisi 0xFD; kemudian setelah pemicuan kedua terjadi, register counter berisi 0xFE; kemudian setelah pemicuan ketiga terjadi, register counter berisi 0xFF; dan terakhir setelah pemicuan keempat terjadi, maka akan terjadi overflow (register counter = 0x00) dan flag akan di-set.

Semua kanal timer AVR ATmega16/32 dapat dioperasikan pada salah satu dari 4 mode berikut:

  1. Normal (Mode 0)
  2. Clear Timer on Compare Match (CTC) (Mode 1)
  3. Fast PWM (Mode 2), dan
  4. Phase Correct PWM (Mode 3).

Timer berhubungan erat dengan kata frekuensi, perioda dan duty cycle. Frekuensi adalah jumlah pulsa yang terjadi dalam satu satuan waktu. Perioda merupakan kebalikan dari frekuensi. Duty cycle (DC) adalah perbandingan antara pulsa (tH) dan perioda yang dinyatakan dalam persen.


Timer/Counter 0

Pada bagian ini kita akan membahas fitur-fitur, aristektur, mode register-register, dan pemrograman Timer 0. Fitur-fitur timer/counter 0 adalah:

  • Timer 8-bit
  • Sebagai pencacah (counter) 1 kanal
  • Timer dinolkan ketika match compare (auto reload)
  • Sebagai pembangkit gelombang PWM dengan glitch-free
  • Pencacah (counter) dipicu dari luar
  • Sebagai pembangkit frekuensi
  • Prescaler 10 bit untuk timer
  • Sumber interupsi timer saat overflow (TOV0) dan compare match (OCF0)

Sumber clock untuk Timer0 disediakan melalui sumber clock eksternal pada pin T0 (PB0) mikrokontroler. Timer 0 juga dapat di-clock secara internal melalui clock utama mikrokontroler (fclk_I/O). Frekuensi clock ini dapat juga dipercepat untuk sejumlah aplikasi. Karena itu, sistem pewaktuan dilengkapi dengan sebuah prescaler untuk membagi frekuensi clock utama menjadi frekuensi sistem timer (clkTn). Sumber clock untuk Timer0 dipilih menggunakan bit-bit CS0[2:0] yang berada dalam TCCR0. Register TCCR0 juga berisi bit-bit WGM0[1:0) dan bit-bit COM0[1:0) yang digunakan untuk memilih mode operasi Timer0 serta membuat pembangkitan gelombang untuk suatu aplikasi khusus.

Sumber clock timer (clkTn) diumpankan ke register 8-bit Timer/Counter (TCNT0). Register ini di-increment (atau di-decrement) pada setiap pulsa clock clkTn. Timer0 juga dilengkapi dengan sebuah pembanding (comparator) 8-bit yang secara konstan membandingkan cacahan TCNT0 ke Output Compare Register (OCR0). Sinyal yang dibandingkan dari comparator 8-bit diumpankan ke pembangkit gelombang (waveform generator). Pembangkit gelombang mempunyai sejumlah input (top, bottom, WGM0[1:0], dan COM0[1:0]) untuk melakukan operasi-operasi dengan sistem timer.

Sinyal BOTTOM untuk pembangkitan gelombang control logic dinyatakan ketika timer/counter TCNT0 bernilai 0 ($00). Sinyal MAX untuk control logic unit yang dinyatakan ketika timer/counter TCNT0 bernilai 255 ($FF). Sinyal TOP untuk pembangkitan gelombang yang dinyatakan oleh pencapaian nilai cacah maksimum $FF pada register TCNT0 atau mencapai set nilai pada OCR0. Setting untuk sinyal TOP akan ditentukan oleh mode operasi timer.

Timer 0 juga menggunakan bit-bit tertentu dalam Register Timer/Counter Interrupt Mask (TIMSK) dan Register Timer/counter Interrupt Flag (TIFR) untuk sinyal kejadian-kejadian/event  yang berkenaan dengan interupsi. Timer0 men-share (menggunakan bersama) register-register ini dengan dua kanal timer lainnya.

Mode Operasi Timer 0

Setiap kanal timer dapat di-set untuk bekerja pada mode operasi tertentu: Normal, CTC, Fast PWM dan Phase Correct PWM. Perancang sistem dapat memilih mode yang cocok untuk aplikasinya. Mode operasi dipilih menggunakan Waveform Generation Mode, WGM00 dan WGM01 pada register TCCR0.

Mode Normal. Pada mode normal, timer akan secara kontinu menghitung dari $00 (BOTTOM) sampai $FF (TOP). Bila TCNT0 kembali kepada setiap siklus counter, maka Timer/Counter Overflow Flag (TOV0) akan di set. Mode normal berguna untuk membangkitkan 'clock tick' à untuk menghitung waktu nyata atau menyediakan tunda (delay) dalam suatu sistem.

Mode Clear Timer on Compare Match. Pada mode CTC, timer TCNT0 di-reset ke 0 setiap saat pencacah TCNT0 mencapai set nilai pada OCR0. Output Compare Flag 0 (OCF0) di-set jika event ini terjadi. OCF0 flag di-enable oleh subrutin interupsi Timer/Counter 0 Output Compare Match Interrupt Enable (OCIE0) flag dalam TIMSK dan bila bit I dalam Status Register di-set ke 1?. Mode CTC digunakan untuk membangkitkan gelombang digital presisi seperti sinyal periodik atau sebuah pulsa tunggal.

Mode Phase Correct PWM. Pada mode ini, register TCNT0 mencacah dari $00 sampai $FF dan kembali ke $00 secara kontinu. Setiap saat nilai TCNT0 cocok dengan nilai yang di-set dalam register OCR0, maka OCF0 flag di-set dan terjadi suatu perubahan dalam sinyal PWM.

Mode Fast PWM. Mode ini digunakan untuk membangkitkan sinyal PWM presisi dari suatu frekuensi dan duty cycle yang dikehendaki. Disebut dengan Fast PWM karena frekuensi maksimum dua kali mode Phase Correct PWM. Bila nilai register TCNT0 mencapai set nilai dalam register OCR0, maka akan menyebabkan perubahan pada output PWM seperti yang dinyatakan sebelumnya oleh perancang. Hal ini secara kontinu dicacah naik sampai nilai TOP, pada saat ini Timer/Counter 0 mencapai overflow di mana overflow flag (TOV0) di-set.

REGISTER TIMER 0

Timer/Counter Control Register – TCCR0

Register TCCR0 digunakan untuk:

  • Memilih mode operasional Timer0 menggunakan bit-bit Waveform Mode Generation (WGMO[1:0])
  • Menentukan operasi timer dalam mode khusus dengan bit-bit Compare Match Output Mode (COM0[1:0]), dan
  • Memilih sumber clock Timer0 menggunakan bit-bit CSO[2:0]

Setting bit untuk register TCCR0 dapat dilihat pada Gambar

.

  • Bit 7 – FOC0: Force Output Compare. Bit FOC0 hanya aktif jika bit WGM00 ditetapkan sebagai mode non-PWM. Namun untuk menjamin kompatibilitas dengan piranti-piranti baru, bit ini harus di-nolkan ketika beroperasi pada mode PWM. . Jika logika ‘1’ ditulis pada bit FOC0,  maka mengakibatkan pembangkit gelombang bertindak seakan-akan telah terjadi Compare Match.
  • Bit 6 dan bit 3 - WGM00 dan WGM01: Waveform Generation Unit. Bit ini mengontrol kenaikan counter, sumber bagi nilai maksimum counter (TOP), dan jenis pembangkitan bentuk gelombang yang akan digunakan. Mode operasi yang didukung oleh unit timer/counter adalah: mode Normal, mode Clear Timer on Compare Match (CTC), dan dua jenis mode PWM (pulse width modulation).
  • Bit 5, 4 – COM01, COM00: Compare Match Output Mode. Bit-bit ini mengendalikan kerja pin OC0 (Output Compare). Jika satu atau kedua bit ini (COM01, COM00) dalam keadaan set, maka output OC0 mengesampingkan fungsinya sebagai pin I/O. Namun, perhatikan  bahwa bit DDR (data direction register) pada pin OC0 harus di-set untuk mengaktifkan driver output.

Bila OC0 disambung ke pin, fungsi bit-bit COM01, COM00 tergantung pada setting bit WGM01, WGM00. Tabel ini menunjukkan fungsional bit COM01, COM00 bila bit-bit WGM01, WGM00 di-set ke mode normal atau mode CTC (non-PWM).

COM01, COM00

Tabel ini menunjukkan fungsional bit COM01, COM00 bila bit WGM01, WGM00 di-set ke Fast PWM mode.

.

Tabel ini menunjukkan fungsional bit COM01, COM00 bila bit-bit WGM01, WGM00 di-set ke Phase Correct PWM Mode.

  • Bit 2, 1, 0 - CS02, CS01, CS00: Clock Select. Tiga bit Clock Select memilih sumber clock yang akan digunakan oleh Timer/Counter. Berikut ini Konfigurasi bit-bit Clock Select:

Jika mode pin eksternal digunakan untuk Timer/Counter0, transisi pada pin T0 akan memberikan clock pada counter walaupun pin dikonfigurasikan sebagai output. Fitur ini memungkinkan kontrol perangkat lunak untuk mencacah.

.

Timer/Counter Register 0 (TCNT0). Register TCNT0 adalah counter 8-bit untuk Timer 0

Output Compare Register 0 (OCR0).

Register OCR0 menyimpan nilai yang ditetapkan oleh user (8-bit) yang secara kontinu dibandingkan dengan register TCNT0. Kondisi match dapat digunakan untuk membangkitkan output compare interrupt, atau untuk membangkitkan gelombang  output pada pin OC0. Register ini bertugas mencacah/menghitung pulsa yang masuk ke dalam timer/counter. Lebar register ini 8-bit atau 255 cacahan. Setelah mencapai cacahan maksimal maka akan kembali ke nol (overflow).

.

Timer/Counter Interrupt Mask Register (TIMSK)

Register TIMSK digunakan oleh semua ketiga kanal timer. Timer0 menggunakan bit Timer/Counter0 Output Compare Match Interrupt Enable (OCIE0) dan bit Timer/Counter0 Overflow Interrupt Enable (TOIE0). Jika bit OCIE0 dan bit-I pada Status Register keduanya di-set ke 1, maka Timer/Counter0 Output Compare Match Interrupt di-enable. Jika bit TOIE0  dan bit I pada Status Register keduanya di-set ke 1, maka Timer/Counter0 Overflow Interrupt di-enable.

.

Timer/Counter Interrupt Flag Register (TIFR)

Register TIFR digunakan oleh ketiga kanal timer. Timer0 menggunakan OCF0 yang di-set saat terjadi compare match. Timer0 juga menggunakan TOV0 yang di-set jika terjadi overflow pada Timer/Counter 0.

  • Bit 1 - Output Compare Flag 0 (OCF0): Flag OCF0 ini akan di-set sebagai indikator terjadinya compare match, dan akan clear secara otomatis bersamaan dengan eksekusi vektor interupsi timer0 compare match.
  • Bit 0 – Timer/Counter0 Overflow 0 (TOV0):Flag ini akan di-set secara otomatis ketika terjadi overflow pada counter (kejadian dari 0xFF ke 0x00) dan akan tetap set hingga di-clear saat terjadi interupsi Timer/Counter0 Overflow Interrupt. Alternatifnya, flag ini akan di-clear dengan mengatur nilainya = ‘1’. Saat bit I pada SREG, TOIE0 (Timer/Counter0 Overflow Interrupt Enable), dan TOV0 semuanya diset ‘1’ maka Timer/Counter0 Overflow interrupt dijalankan. Pada mode phase correct PWM, bit ini diset ‘1’ saat  Register Timer/Counter0 mengubah arah perhitungannya (counting up/down) pada $00.

OPERASI TIMER 0 MODE NORMAL

Pada mode ini, isi dari timer/counter dicacah naik (increment) pada setiap clock. Timer/counter dicacah naik hingga mencapai maksimum 0xFF. Ketika terjadi roll over (dari 0xFF ke 0x00), sebuah flag di-set high yang disebut TOV0 (timer overflow). Flag dari timer ini dapat dimonitor.

LANGKAH-LANGKAH PEMROGRAMAN TIMER0 MODE NORMAL:

Untuk membangkitkan waktu tunda dengan Timer 0 mode normal, ikuti diagram alir langkah-langkah pengaktifan pada Gambar.

Untuk menghitung waktu tunda yang dibangkitkan oleh Timer0 mode normal tanpa prescaler, gunakan persamaan berikut:

Dimana:

D: Nilai yang akan dimasukkan ke register TCNT0

fclock : frekuensi clock (kristal) yang digunakan (Hz)

1+255 : nilai maksimum timer adalah 255 dan overflow saat 0xFF ke 0x00

.

PERHITUNGAN NILAI AWAL TCNT0 (tanpa prescaler)

Jika diketahui waktu tunda yang akan digunakan, maka nilai awal register TCNT0 dapat ditentukan dengan langkah-langkah berikut:

Contoh 1:

Buatlah program dalam bahasa C untuk men-toggle PORTB.0 secara kontinu dengan waktu tunda=25us. Gunakan Timer 0 mode normal tanpa prescaler dengan frekuensi osilator 8 MHz.

Program:

.

/*
 * TIM COUNT1.c
 *
 * Created: 29/01/2023 8:18:52
 * Author : DELL
 */ 
# include <avr/io.h>
void Todelay();
int main ()
{
	DDRB = 0x01; //inisialisasi PORTB sebagai output
	while (1)
	{
		PORTB = 0x01;
		Todelay();  //waktu tunda
		PORTB = 0x00; //toggle portB
		Todelay();   //waktu tunda
	}
}

void Todelay()
{
	TCNT0 = 0x38;
	TCCR0 = 0x01; //Timer0 mode normal tanpa prescaler
	while ((TIFR & 0x01) == 0); //tunggu sampai TOV0 roll over
	TCCR0 = 0; //matikan timer
	TIFR = 0x01; //clear TOV0
}

.

Hasil pada Oscilloscope:

Video Demo:

.

PENGGUNAAN PRESCALER PADA TIMER 0

Waktu tunda yang dibangkitkan oleh program timer mode normal pada pembahasan sebelumnya mempunyai keterbatasan. Di mana waktu tunda maksimum yang dapat dibangkitkan adalah TCNT0 = 0. Seperti yang kita lihat pada contoh di atas, besarnya waktu tunda tergantung pada dua faktor yaitu: (1) Frekuensi kristal, dan (2) register timer yang digunakan (register timer 0 = 8-bit). Untuk memperlama waktu tunda yang dihasilkan, disediakan fasilitas yang dinamakan prescaler. Prescaler berfungsi untuk membagi frekuensi osilator dengan bilangan faktor 8, 64, 256 dan 1024.

Untuk menghitung waktu tunda yang dibangkitkan oleh Timer0 mode normal dengan prescaler N, digunakan persamaan berikut:

 Waktu Tunda = N x (256 – D) x 1/fclock .......... (6.2)

di mana :

D: Nilai yang akan dimasukkan ke register TCNT0

fclock : frekuensi clock (kristal) yang digunakan (Hz)

1+255 : nilai maksimum timer adalah 255 dan overflow saat 0xFF ke 0x00

N : Prescaler (1, 8, 64, 256, 1024)

.

Berikut ini rangkuman beberapa waktu tunda Timer 0 mode Normal

.

Contoh 6.4:

Program:

.

/*
 * TIM COUNT EX 6.4.c
 *
 * Created: 29/01/2023 9:10:58
 * Author : DELL
 */ 

#include <avr/io.h>
void T0delay();
int main ()
{
	DDRB = 0X01; //inisialisasi PORTB sebagai output
	while (1)
	{
		T0delay ( ); //waktu tunda 100 us
		PORTB = PORTB ^ 0X01; //toggle portB.0
	}
}
void T0delay()
{
	TCNT0 = 131; //inisialisasi TCNT0 dengan nilai 131 (=1 ms)
	TCCR0 = 0x03; //Timer0 mode normal dengan prescaler 64
	while ((TIFR & (1<<TOV0))== 0);  //tunggu sampai TOV0 roll over
	TCCR0 = 0; //matikan timer
	TIFR = 0x01; //clear TOV0
}

.

Hasil pada Oscilloscope:

Video Demo:

.

.

Contoh 6.5:

.

Program:

.

/*
 * TIM COUNT EX 6.5.c
 *
 * Created: 29/01/2023 9:21:47
 * Author : DELL
 */ 

#include <avr/io.h>
void T0delay();
int main ()
{
	DDRA = 0X01; //inisialisasi PORTB sebagai output
	while (1)
	{
		T0delay ( ); //waktu tunda 100 us
		PORTA = PORTA ^ 0X01; //toggle portB.0
	}
}
void T0delay()
{
	TCNT0 = 99; //inisialisasi TCNT0 dengan nilai 99 (=5 ms)
	TCCR0 = 0x04; //Timer0 mode normal dengan prescaler 256
	while ((TIFR & (1<<TOV0))== 0);  //tunggu sampai TOV0 roll over
	TCCR0 = 0; //matikan timer
	TIFR = 0x01; //clear TOV0
}

.

Hasil Pada Oscilloscope:

Video Demo:

.

Contoh 6.6:

.

Program:

.

/*
 * TUM COUNT1 EX6.6.c
 *
 * Created: 29/01/2023 9:34:42
 * Author : DELL
 */ 
/*
 * TIM COUNT EX 6.5.c
 *
 * Created: 29/01/2023 9:21:47
 * Author : DELL
 */ 

#include <avr/io.h>
void T0delay();
int main ()
{
	DDRA = 0X01; //inisialisasi PORTB sebagai output
	while (1)
	{
		PORTA =  0X01; //toggle portA.0
		TCNT0 = 21; //UTK 30ms
		T0delay (); 
		PORTA =  0X00; //toggle portA.0
		TCNT0 = 177; ////UTK 10ms
		T0delay ();
	}
}
void T0delay()
{
	
	TCCR0 = 0x05; //Timer0 mode normal dengan prescaler 1024
	while ((TIFR & (1<<TOV0))== 0);  //tunggu sampai TOV0 roll over
	TCCR0 = 0; //matikan timer
	TIFR = 0x01; //clear TOV0
}

.

Hasil Pada Oscilloscope:

.

.

Waktu tunda timer dipengaruhi oleh dua faktor yaitu: (1) frekuensi kristal, dan (2) faktor prescaler. Dalam penggunaan bahasa C tentunya dapat menambah satu faktor lagi yaitu Compiler C itu sendiri, karena dengan Compiler C yang berbeda akan membangkitkan ukuran hex file dan jumlah overhead (yang ditimbulkan oleh berbagai instruksi compiler) yang berbeda pula.

Contoh 2:

Buatlah program dalam bahasa C untuk men-toggle bit PORTB.0 secara kontinu setiap 125 us. Gunakan Timer 0, mode normal dengan prescaler 8. Anggap frekeunsi krsital 8 MHz.

SOLUSI: Tclock = 1/8MHz = 0,125 us.

Dengan prescaler = 8 --> WT = 8 x (256 – D) x Tclock --> D = 256 – (100 us/8x0,125 us) = 156.

Jadi TCNT0 = 156.

Register TCCR0 = 0b00000010 = 0x02. (timer 0 mode normal dengan Register TCCR0 prescaler 8)

Program:

.

/*
 * TIM COUNT2.c
 *
 * Created: 29/01/2023 8:46:29
 * Author : DELL
 */ 

#include <avr/io.h>
void T0delay();
int main ()
{
	DDRB = 0X01; //inisialisasi PORTB sebagai output
	while (1)
	{
		T0delay ( ); //waktu tunda 100 us
		PORTB = PORTB ^ 0X01; //toggle portB.0
	}
}
void T0delay()
{
	TCNT0 = 156; //inisialisasi TCNT0 dengan nilai 156 (=100 us)
	TCCR0 = 0x02; //Timer0 mode normal dengan prescaler 8
	while ((TIFR & (1<<TOV0))== 0);  //tunggu sampai TOV0 roll over
	TCCR0 = 0; //matikan timer
	TIFR = 0x01; //clear TOV0
}

Hasil Pada Oscilloscope:

.

Video Demo:

.

.

Contoh 3:

To generate a square wave in normal mode, we can set COM bit as toggle mode (COM01:00=01), so OC0 pin will be toggle on each compare match and the square wave will be generated.

.

Progam:

.

/*
 * TIM COUNT3.c
 *
 * Created: 29/01/2023 10:42:12
 * Author : DELL
 */ 

#include <avr/io.h>

int main ( )
{
	DDRB = DDRB|(1<<3);
	TCCR0 = 0x11;	/* normal mode, clk- no pre-scaling */
	OCR0 = 100;	/* compare value */
	while (1);
	return 0;
}

.

Hasil Pada Oscilloscope:

.

.

TIMER 0 MODE CTC

Timer 0 mode CTC (Clear Timer on Compare Match) mirip dengan timer0 mode normal, perbedaannya terletak pada nilai TCNT0 yang dibandingkan dengan nilai yang terdapat pada OCR0. Artinya kenaikan cacahan clock pada TCNT0 dibandingkan hingga sama dengan nilai OCR0 (terjadi compare match), kemudian jika sudah sama maka flag OCF0 akan set ketika clock berikutnya masuk (lihat Gambar 6.16). Flag OCF0 terletak dalam register TIFR.

.

.

Contoh 4:

This is a better mode than the normal mode for generating square waves because the frequency of the wave can be easily adjusted using the OCR0 register. See the figure:

.

As you can see, when a compare match occurs, the timer value becomes zero.

Program:

.

/*
 * TIM COUNT4.c
 *
 * Created: 29/01/2023 10:59:19
 * Author : DELL
 */ 

#include "avr/io.h"
int main ( )
{
	DDRB = DDRB|(1<<3);	/* PB3 (OC0) as output */	
	TCCR0 = 0x19;		/* CTC mode, toggle on compare match,
                      		clk- no pre-scaling */ 
	OCR0 = 200;  		/* compare value */
	while (1);
}

.

Hasil Pada Oscilloscope:

.

.

Contoh 5:

Here we have changed the value of OCR0 in runtime, to generate different pulses in the below program.

Program:

.

/*
 * TIM COUNT5.c
 *
 * Created: 29/01/2023 11:07:57
 * Author : DELL
 */ 
#include "avr/io.h"
int main ( )
{
	DDRB |= (1<<3);		/*PB3 (OC0) as output */
	while (1)
	{
		OCR0 = 69;
		TCCR0 = 0x39;	/* CTC, set on match, no prescaler */
		while ((TIFR&(1<<OCF0)) == 0);  /* monitor OCF0 flag */
		TIFR = (1<<OCF0);/* Clear OCF0 by writing 1 */
		OCR0 = 99;
		TCCR0 = 0x29;	/* CTC, clear on match, no prescaler */
		while ((TIFR&(1<<OCF0)) == 0);
		TIFR = (1<<OCF0);/* Clear OCF0 by writing 1 */
	}
}

Hasil Pada Oscilloscope:

.

Video Demo:

.

.

Contoh 6: (Merupakan Lanjutan dari contoh 5 dengan mengubah nilai OCR0)

.

/*
 * TIM COUNT6.c
 *
 * Created: 29/01/2023 11:15:27
 * Author : DELL
 */ 
#include "avr/io.h"
int main ( )
{
	DDRB |= (1<<3);		/*PB3 (OC0) as output */
	while (1)
	{
		OCR0 = 69;
		TCCR0 = 0x39;	/* CTC, set on match, no prescaler */
		while ((TIFR&(1<<OCF0)) == 0);  /* monitor OCF0 flag */
		TIFR = (1<<OCF0);/* Clear OCF0 by writing 1 */
		OCR0 = 199;
		TCCR0 = 0x29;	/* CTC, clear on match, no prescaler */
		while ((TIFR&(1<<OCF0)) == 0);
		TIFR = (1<<OCF0);/* Clear OCF0 by writing 1 */
	}
}

.

Hasil Pada Oscilloscope:

Video Demo:

.

.


Timer/Counter 2

Timer 2 juga merupakan timer 8-bit yang serupa dengan Timer0, karena itu prinsip kerjanya sama. Perbedaannya ada dua yaitu:

  • Timer2 dapat digunakan sebagai real time counter. Untuk melakukan hal tersebut kita harus menghubungkan sebuah osilator 32,768 KHz ke pin TOSC1 dan TOSC2 pada AVR, dan menge-set bit AS2 pada register ASSR.
  • Pada Timer0, jika CS02-CS00 mempunyai nilai 110 atau 111, timer0 mencacah event eksternal. Tetapi pada Timer2, multiplexer hanya memilih sejumlah siklus clock/prescaler (lihat Gambar 6.18).

Bila AS2 nol, clock pada Timer2 dari clk_I/O

Bila AS2 set, Timer2 bekerja seperti RTC

Diagram blok Timer 2 ditunjukkan pada Gambar 6.19. Timer2 dapat di-clock secara internal melalui clock utama mikrokontroler (fclk_I/O). Frekuensi clock ini dapat juga dipercepat untuk sejumlah aplikasi. Karena itu, system pewaktuan dilengkapi dengan sebuah prescaler untuk membagi frekuensi clock utama menjadi frekuensi sistem timer (clkTn). Sumber clock untuk Timer2 dipilih menggunakan bit-bit CS22, CS21, CS20 yang berada dalam Timer/Control Register (TCCR2). Register TCCR2 juga berisi bit-bit WGM20,WGM21 dan bit-bit COM21, COM20 yang digunakan untuk memilih mode operasi untuk Timer 2.

Contoh 7:

.

Program:

.

/*
 * TIM COUNT7.c
 *
 * Created: 29/01/2023 13:59:40
 * Author : DELL
 */ 


#include <avr/io.h>
void T0delay();
int main ()
{
	DDRB = 0X08; //inisialisasi PORTB sebagai output
	while (1)
	{
		T0delay (); 
		PORTB = PORTB ^ 0X08; //toggle portB.3
	}
}
void T0delay()
{
TCNT2 = 6; //inisialisasi TCNT0 dengan nilai 6 (=2 ms)
TCCR2 = 0x04; //Timer0 mode normal dengan prescaler 64
while ((TIFR & (1<<TOV2))== 0);  //tunggu sampai TOV2 roll over
TCCR2 = 0; //matikan timer
TIFR = 0x40; //clear TOV2
}


.

Hasil Pada Oscilloscope:

Video Demo:

.

.

Contoh 8:

.

Program:

.

/*
 * TIM COUNT8.c
 *
 * Created: 29/01/2023 10:59:19
 * Author : DELL
 */ 
#include <avr/io.h>
void T0delay();
int main ()
{
	DDRB = 0X08; //inisialisasi PORTB sebagai output
	while (1)
	{
		T0delay ();
		PORTB = PORTB ^ 0X08; //toggle portB.3
	}
}
void T0delay()
{
	OCR2 = 156; 
	TCCR2 = 0x0E; //Timer2 mode normal dengan prescaler 256
	while ((TIFR&(1<<OCF2)) == 0); 
	OCR2 = 0; //matikan timer
	TIFR = (1<<OCF2);/* Clear OCF2 by writing 1 */
}


.

Hasil Pada Oscilloscope:

.

Video Demo:

.


Timer/Counter 1

Timer/Counter 1 merupakan timer/counter yang memiliki lebar 16-bit yang dapat memberikan program pewaktuan yang lebih besar. Register Timer1 dibagi menjadi 2 buah register masing-masing 8-bit yaitu TCNT1L dan TCNT1H. Juga terdapat dua register kontrol yaitu TCCR1A dan TCCR1B. Ada dua register OCR dalam Timer1 yaitu OCR1A dan OCR1B (keduanya 16-bit). Ada dua buah flag pada OCR yang masing-masing bekerja terpisah satu sama lain.

Ketika TCNT1 sama dengan OCR1A, maka pada siklus clock berikutnya flag OCF1A akan set. Ketika TCNT1 sama dengan OCR1B, maka pada siklus clock berikutnya flag OCF1B akan set. Register 16-bit OCR1A terbagi dua buah register 8-bit yaitu register OCR1AH (OCR1A byte atas) dan OCR1AL (OCR1A byte bawah).

Fitur-fitur Timer/Counter1 sebagai berikut:

  • Desain 16-bit (juga bisa untuk PWM 16-bit)
  • Dua unit pembanding (compare unit)
  • Dua register pembanding (comparator)
  • Satu input capture unit
  • Timer di-reset ketika match compare (auto reload)
  • Dapat menghasilkan gelombang PWM dengan glitch-free
  • Perioda PWM yang dapat diubah-ubah
  • Pembangkitan frekuensi
  • Empat sumber interupsi (TOV1, OCF1A, OCF1B dan ICF1)

Fitur input capture digunakan untuk meng-capture karakteristik/perilaku dari suatu sinyal input, termasuk perioda, frekuensi, duty cycle atau panjang pulsa. Hal ini diselesaikan oleh monitoring untuk user-specified edge pada pin ICP1 mikrokontroler. Bila tebing clock (edge) yang dikehendaki terjadi maka nilai register Timer/Counter1 (TCNT1) di-capture dan disimpan pada Input Capture Register1 (ICR1).

Register Pada Timer & Counter 1

Register-register yang terdapat pada Timer 1 ditunjukkan dalam Gambar. Setiap register akan dijelaskan berikut.

  1. Register TCCR1A dan TCCR1B. Register TCCR1 digunakan untuk: Memilih mode operasional Timer1 menggunakan bit-bit Waveform Mode Generation (WGM1[3:0])
  2. Menentukan operasi timer dalam mode khusus dengan bit-bit Compare Match Output Mode (Kanal A, COM1A[1:0]; dan Kanal B, COM1B[1:0]), dan
  3. Memilih sumber clock Timer1 menggunakan bit-bit CS1[2:0]

Setting bit untuk register TCCR1A dan TCCR1B dapat dilihat pada ringkasan Gambar berikut ini:

.

Timer/Counter Control Register – TCCR1A

  • Bit 7,6 – COM1A1, COM1A0: Compare Output Mode for Channel A
  • Bit 5,4 - COM1B1, COM1B0: Compare Output Mode for Channel B Bit-bit COM1A1, COM1A0 dan COM1B1, COM1B0 mengontrol tingkah laku/Mode pin-pin Output Compare (berturut-turut OC1A dan OC1B).

.

.

  • Bit 3 - FOC1A: Force Output Compare for Channel A
  • Bit 2 FOC1B: Force Output Compare for Channel B.  Bit-bit FOC1A/FOC1B hanya aktif bila bit-bit WGM13 s.d. WGM10 menetapkan sebuah mode non-PWM. Namun demikian, untuk menjamin kompatibilitas dengan piranti-piranti baru, bit-bit ini harus di-set ke nol ketika beroperasi pada mode PWM. Jika logika ‘1’ ditulis pada bit FOC1A/FOC1B, maka sebuah immediate compare match didorong pada unit pembangkit bentuk gelombang. FOC1A/FOC1B tidak akan membangkitkan interupsi apapun atau tidak akan meng-clear timer pada Clear Timer on Compare Match (CTC) mode menggunakan OCR1A sebagai TOP (WGM13:0 = 4). Bit-bit FOC1A/FOC1B selalu dibaca sebagai nol.
  • Bit 1, 0 – WGM11, WGM10: Waveform Generation Mode. Dikombinasikan dengan bit-bit WGM13, WGM12 diperoleh pada register TCCR1B, bit-bit ini mengontrol urutan (sequence) pencacahan counter, sumber untuk nilai counter maksimum (TOP), dan jenis pembangkit gelombang yang digunakan, lihat pada Tabel. Mode-mode operasi yang didukung oleh unit Timer/Counter adalah: Normal mode (counter), Clear Timer on Compare Match (CTC) mode, dan tiga jenis mode PWM.

Penjelasan bit mode pembangkitan bentuk gelombang

.

Timer/Counter Control Register – TCCR1B

  • Bit 7 – ICNC1: Input Capture Noise Canceler. Bit ini aktif jika di-set = ‘1’ dan sinyal yang masuk pada kaki Input Capture ICP1 akan difilter.
  • Bit 6 – ICES1: Input Capture Edge Select. Bit ini digunakan untuk memilih tepi sinyal trigger. Saat bit ini = ‘0’ maka trigger yang digunakan adalah falling edge. Jika sebaliknya maka trigger yang digunakan adalah rising edge.
  • Bit 5 - Reserved Bit
  • Bit 4:3 – WGM13:2: Waveform Generation Mode
  • Bit 2, 1, 0 – CS12, CS11, CS10: Clock Select. Ketiga bit Clock Select ini memilih sumber clock yang akan digunakan untuk Timer/Counter.

.

Register TCNT1

  • TCNT1 Timer/Counter1 Register digunakan untuk menyimpan nilai timer yang diinginkan. TCNT1 dibagi menjadi 2 register 8 bit yaitu TCNT1H dan TCNT1L.

.

Register TIMSK

Timer Interrupt Mask Register (TIMSK) dan Timer Interrupt Flag Register (TIFR) digunakan untuk mengendalikan interrupt-interrupt mana yang diaktifkan dengan cara melakukan setting pada TIMSK dan untuk mengetahui interrupt mana yang sedang terjadi.

  • Bit 5 TICIE1: Timer/Counter1, Input Capture Interrupt Enable. Bila bit ini di-set = ‘1’ dan I-flag dalam Status Register di-set (interupsi global di-enable), maka Timer/Counter1 Input Capture Interrupt di-enable.
  • Bit 4 - OCIE1A: Timer/Counter1, Output Compare A Match Interrupt Enable. Bila bit ini di-set = ‘1’ dan I-flag dalam Status Register diset (interupsi global di-enable), maka Timer/Counter1 Output Compare A Match Interrupt di-enable.
  • Bit 3 - OCIE1B: Timer/Counter1, Output Compare B Match Interrupt Enable. Bila bit ini di-set = ‘1’ dan I-flag dalam Status Register di-set (interupsi global di-enable), maka Timer/Counter1 Output Compare B Match Interrupt di-enable.
  • Bit 2 – TOIE1: Timer/Counter1, Overflow Interrupt Enable. Bila bit ini ditulisi satu dan I-flag dalam Status Register di-set (interupsi global di-enable), maka Timer/Counter1 Overflow Interrupt di-enable.

.

Register TIFR

Timer Interrupt Mask Register (TIMSK) dan Timer Interrupt Flag Register (TIFR) digunakan untuk mengendalikan interrupt mana yang diaktifkan dengan cara melakukan setting pada TIMSK dan untuk mengetahui interrupt mana yang sedang terjadi.

  • Bit 5 - ICF1: Timer/Counter1, Input Capture Flag. Flag ini set jika terjadi sebuah capture event pada pin ICP1. Jika Input Capture Register (ICR1) di-set sebagai nilai TOP oleh WGM13 s.d. WGM10, maka ICF1 Flag di-set jika counter mencapai nilai TOP. ICF1 secara otomatis di-clear jika Input Capture Interrupt Vector dieksekusi.
  • Bit 4 – OCF1A: Timer/Counter1, Output Compare A Match Flag. Flag ini di-set dalam siklus clock timer setelah nilai counter (TCNT1) sama dengan Output Compare Register A (OCR1A). Catatan bahwa dengan mengubah bit pada Force Output Compare (FOC1A) tidak akan menge-set Flag OCF1A. OCF1A secara otomatis di-clear jika vektor interupsi Output Compare Match A dieksekusi. Alternatifnya, OCF1A dapat di-clear dengan menuliskan logika satu pada bit nya.
  • Bit 3 - OCF1B: Timer/Counter1, Output Compare B Match. Flag ini di-set dalam siklus clock timer setelah nilai counter (TCNT1) sama dengan Output Compare Register B (OCR1B). Catatan bahwa dengan mengubah bit pada Force Output Compare (FOC1B) tidak akan menge-set OCF1B Flag. OCF1B secara otomatis di-clear jika vektor interupsi Output Compare Match B dieksekusi. Alternatifnya, OCF1B dapat di-clear dengan menuliskan logika satu pada bit nya.
  • Bit 2 – TOV1: Timer/Counter1, Overflow Flag. Setting flag ini tergantung pada setting bit-bit WGM13 s.d. WGM10. Pada mode normal dan mode CTC, TOV1 Flag di-set jika timer overflow. TOV1 secara otomatis di-clear jika vektor interupsi Timer/Counter1 Overflow dieksekusi. Alternatifnya, TOV1 dapat di-clear dengan menulis logika satu bit nya.

.

MODE OPERASI TIMER 1

Bit-bit WGM13, WGM12, WGM11, WGM10 (atau dituliskan WGM13:10) digunakan untuk menetapkan Mode Timer 1. Terdapat 16 macam mode Timer1 yang bisa dipilih sesuai kebutuhan pemrogram. Mode 13 merupakan mode yang tidak dapat diimplementasikan karena mode 13 adalah cadangan. Pada bab ini kita hanya akan membahas dua mode saja yaitu Mode Normal (mode 0) dan Mode CTC (mode 4).

.

TIMER 1 MODE NORMAL

Pada mode normal, TCNT1 akan menghitung naik dan membangkitkan interrupt Timer/Counter1 ketika nilainya berubah dari $FFFF ke $0000. Pada saat terjadi roll over dari FFFFh ke 0000h maka flag TOV1 menjadi set (lihat Gambar). Sering kali kita menganggap untuk menggunakan timer cukup dengan memasukkan nilai yang diinginkan ke TCNT1 dan menunggu sampai terjadi interrupt. Ini menjadi benar pada timer yang menghitung mundur, tetapi untuk timer yang menghitung maju, maka kita harus memasukkan nilai 65536 sebagai nilai ke dalam TCNT1.

LANGKAH-LANGKAH PEMROGRAMAN TIMER1 MODE NORMAL:

Untuk membangkitkan waktu tunda dengan Timer 1 mode normal, ikuti diagram alir langkah-langkah pengaktifan berikut ini:

Untuk menghitung waktu tunda yang dibangkitkan oleh Timer 1 mode normal tanpa prescaler digunakan persamaan berikut:

Waktu Tunda = Nx (65536 – D) x 1/fclock ..........(6.3)

Di mana:

D : Nilai yang akan dimasukkan ke register TCNT1

fclock : Frekuensi clock (kristal) yang digunakan (Hz)

N : Prescaler (1, 8, 64, 256, 1024)

1+65535: Nilai maksimum timer adalah 65535 dan overflow saat 65535 ke 0000h

.

.

.

.

Contoh 9:

Buat program Timer1 mode normal menggunakan frekuensi osilator 8 MHz untuk membangkitkan gelombang kotak (duty cycle 50%) dengan frekuensi 0,5 Hz. Sinyal ini keluar melalui PORTB.3 (PB3). Abaikan overhead waktu tunda yang ditimbulkan instruksi.

SOLUSI:

  • Perioda sinyal yang keluar pada PB3 = T = 1/0,5Hz = 2 detik
  • Sinyal gelombang kotak mempunyai duty cycle 50%, jadi TH =0,50xT=0,5 x 2 s=1 s, TL= T - TH = 2 s - 1 s = 1 s
  • Untuk membangkitkan waktu tunda 1 detik pada kristal 8 MHz maka diperlukan prescaler 256, Jadi WT = 256 x (65536 - D) x 0,125 us; 1s = 256 x (65536 – D) 0,125 us; D = 34286; Jadi TCNT1 = 0x85EE
  • TCCR1A = 0b00000000 (WGM11 = 0 WGM10 = 0), TCCR1B = 0b00000100 (WGM13 = 0, WGM12 = 0, CS12 = 1, CS11 = 0, CS10 = 0) sumber clock osilator, dengan prescaler 256.

.

Program:

.

# include <avr/io.h>
void T1delay();
int main ()
{
	DDRB = 0X08; //inisialisasi PORTB sebagai output
	while (1)
	{
		T1delay (); //waktu tunda 1 detik
		PORTB = PORTB ^ (1<<PB3); //toggle portB.3 atau PROTB = PORTB^0x08;
	}
}
void T1delay( )
{
	TCNT1H = 0x85; //inisialisasi TCNT1
	TCNT1L = 0xEE; //dengan nilai 0x85EE
	TCCR1A = 0x00;
	TCCR1B = 0x04; //Timerl mode normal dengan prescaler 256
	while ((TIFR & (1<<TOV1))== 0);
	//tunggu sampai TOV1 roll over
	TCCR1A = 0; TCCR1B = 0;
	//matikan timer
	TIFR = (1<<TOV1);//clear TOV1 atau TIFR = 0xl;
}

.

Hasil Pada Oscilloscope:

.

Video Demo:

.

.

TIMER 1 MODE CTC

Pada mode CTC (mode 4), timer mencacah naik isi dari register TCNT1 hingga sama dengan register OCR1A (terjadi compare match) kemudian timer akan clear pada clock berikutnya. Flag OCF1A akan set sebagai hasil dari compare match yang terjadi.

.

Contoh 10:

Berikut ini program untuk generate delay 1 detik menggunakan Timer1 mode CTC (mode 4):

.

/*
 * TIM COUNT10.c
 *
 * Created: 29/01/2023 14:55:26
 * Author : DELL
 */ 
#include <avr/io.h>
 //UNTUK GENERATE Delay = 1 s
 void T1delay();
 int main ()
 {
	 DDRB = 0X08; //inisialisasi PORTB sebagai output
	 while (1)
	 {
		 T1delay (); //waktu tunda 1 detik
		 PORTB = PORTB ^ (1<<PB3); //toggle portB.3 atau PORTB = PORTB^0x08;
	 }
 }
 void T1delay( )
 {
	 // initialize counter
	 TCNT1 = 0;
	 
	 OCR1A = 31250 - 1;
	 TCCR1A = 0X00;
	 TCCR1B = 0X0C; // set up timer with prescaler = 256 and CTC mode
	 while ((TIFR & (1<<OCF1A))== 0);
	 //tunggu sampai TOV1 roll over
	 TCCR1B = 0;
	 //matikan timer
	 TIFR = (1<<OCF1A);//clear TOV1 atau TIFR = 0xl;
 }

.

Hasil Pada Oscilloscope:

.

Contoh 11:

.

/*
 * TIM COUNT11.c
 *
 * Created: 29/01/2023 15:56:17
 * Author : DELL
 */ 

 //UNTUK GENERATE Delay = 25 us
#include <avr/io.h>

 void T1delay();
 int main ()
 {
	 DDRB = 0X08; //inisialisasi PORTB sebagai output
	 while (1)
	 {
		 T1delay (); //waktu tunda 1 detik
		 PORTB = PORTB ^ (1<<PB3); //toggle portB.3 atau PORTB = PORTB^0x08;
	 }
 }
 void T1delay( )
 {
	 // initialize counter
	 TCNT1 = 0;
	 
	 OCR1A = 199;
	 TCCR1A = 0X00;
	 TCCR1B = 0X09; // set up timer with NO prescaler and CTC mode
	 while ((TIFR & (1<<OCF1A))== 0);
	 //tunggu sampai TOV1 roll over
	 TCCR1B = 0;
	 //matikan timer
	 TIFR = (1<<OCF1A);//clear TOV1 atau TIFR = 0xl;
 }

.

.

Hasil Pada Oscilloscope:

.


Pemrograman Counter

Selain digunakan untuk membangkitkan waktu tunda, Timer juga dapat digunakan untuk melakukan pencacahan, mendeteksi, dan mengukur waktu yang terjadi pada event di luar mikrokontroler AVR. Ketika AVR digunakan sebagai counter, pulsa di luar AVR meng-increment register TCNTx. Register yang terlibat dalam mode counter ini misalnya register TCCR, OCR, dan TCNT sama dengan register yang digunakan pada mode timer sebelumnya.

Bit-bit CS02, CS01, CS00 PADA REGISTER TCCR0

Telah diketahui sebelumnya bahwa CS adalah bit-bit register TCCR0 yang diumpankan ke multiplexer untuk memilih sumber clock.

Jika CS02:CS00 antara 1 dan 5, maka timer memperoleh sumber pulsa dari kristal osilator. Sedangkan jika CS02:CS00 antara 6 atau 7, maka timer digunakan sebagai counter dan memperoleh sumber pulsa dari luar chip AVR. Oleh karena itu jika CS02:CS00 6 atau 7, maka counter TCNT0 mencacah naik pulsa-pulsa yang diumpankan dari pin T0 (masukan clock eksternal Timer/Counter0). Pada AVR ATmega32/16, T0 adalah fungsi alternatif PORTB.0.

Dengan cara yang serupa, untuk Timer/Counter1 jika CS12:CS10 antara 6 atau 7 maka counter TCNT1 mencacah naik pulsa-pulsa yang diumpankan dari pin T1 (masukan clock eksternal Timer/Counter1). Pada AVR ATmega32/16/8535, T1 adalah fungsi alternatif PORTB.1. Ketika CS12:CS10 adalah 6, maka counter mencacah naik pada falling (negative) edge.Ketika CS12:CS10 adalah 7, maka counter mencacah naik pada rising (positive) edge. Lihat Contoh berikut ini.

.

.

Contoh 12:

.

Program:

.

/*
 * TIM COUNT12.c
 *
 * Created: 29/01/2023 17:43:26
 * Author : DELL
 */ 
#include <avr/io.h>
int main ()
{
	DDRB = 0x00; //inisialisasi PORTB sebagai INPUT
	PORTB = 0XFF; //aktifkan internal pull-up resistor PORTB
	DDRA = 0XFF; //inisialisasi PORTA sebagai OUTPUT

	TCNT0 = 0; //REGISTER TCNTO = 0 KARENA DIGUNAKAN sebagai COUNTER
	TCCR0 = 0X06; //counter0, sumber clock eksternal tanpa prescaler, falling edge

	while (1)
	{
		do
		{
			PORTA = ~TCNT0; //kirim pulsa ke PORTA
		} while ((TIFR&(1<<TOV0)) == 0); //tunggu sampai TOV0 roll over
		TIFR = (1<<TOV0); //clear TOV0
	}
}

.

Video Demo:

.

.

.

Contoh 12 Dengan LCD 16x2 4 bit:

.

/*
 * TIM COUNT12 LCD.c
 *
 * Created: 29/01/2023 19:14:43
 * Author : DELL
 */ 

#define F_CPU 8000000UL	
#include <avr/io.h>
#include <util/delay.h>			/* Include Delay header file */
#include <stdio.h>		/* Include standard I/O header file */
#include <string.h>
#include "LCD_16x2_H.h"

int main ()
{
	DDRB = 0x00; //inisialisasi PORTB sebagai INPUT
	PORTB = 0XFF; //aktifkan internal pull-up resistor PORTB
	
	TCNT0 = 0; //REGISTER TCNTO = 0 KARENA DIGUNAKAN sebagai COUNTER
	TCCR0 = 0X06; //counter0, sumber clock eksternal tanpa prescaler, falling edge
	char buffer[10];
	unsigned char count;

	LCD_Init();
	LCD_String_xy(0, 0, "COUNTER 0");
	
	while (1)
	{	LCD_String_xy(0, 0, "COUNTER 0");
		do
		{
			count = TCNT0;
			sprintf(buffer, "%d",count);
			LCD_String_xy(1, 10, buffer);
			
		} while ((TIFR&(1<<TOV0)) == 0); //tunggu sampai TOV0 roll over
		TIFR = (1<<TOV0); //clear TOV0
		LCD_Clear();
		//
	}
}


.

Video Demo:

.

.

Contoh 13:

.

Program:

.

Contoh 13 Dengan LCD 16x2 4 bit:

/*
 * TIM COUNT13.c
 *
 * Created: 29/01/2023 19:57:01
 * Author : DELL
 */ 
#define F_CPU 8000000UL
#include <avr/io.h>
#include <util/delay.h>			/* Include Delay header file */
#include <stdio.h>		/* Include standard I/O header file */
#include <string.h>
#include "LCD_16x2_H.h"
int main ()
{
	DDRB = 0X00; //inisialisasi PORTB sebagai INPUT
	PORTB = 0XFF; //aktifkan internal pull-up resistor PORTB

	TCNT1L = 0; //inisialisasi cacahan ke 0
	TCNT1H = 0; //inisialisasi cacahan ke 0

	TCCR1A = 0x00; //sumber clock keluaran
	TCCR1B = 0X06; //sumber clock keluaran
	
	char buffer[10];
	unsigned char Lcount;
	unsigned int Tcount;
	
	LCD_Init();
	LCD_String_xy(0, 0, "COUNTER 1");
	while (1)
	{
		LCD_String_xy(0, 0, "COUNTER 1");
		do{
			Lcount = TCNT1L;		/* Read lower byte*/
			Tcount = Lcount + TCNT1H*256;
			sprintf(buffer, "%d",Tcount);
			LCD_String_xy(1, 10, buffer);
		} while ((TIFR & (1<<TOV1)) == 0); //tunggu sampai TOV1 roll over
		TIFR = (1<<TOV1); //clear TOV1
		LCD_Clear();
	}
}

.

Video Demo:

.


Timer 1 Mode Input Capture Pada AVR ATmega16/32/8535

Fungsi input capture dapat digunakan pada banyak aplikasi seperti:

  1. Pengukuran lebar pulsa (Pulse Width Measurement)
  2. Pengukuran Periode (Period Measurement)
  3. Menghitung waktu sebuah event

Pada ATmega32/16/8535, Timer 1 dapat digunakan sebagai input capture untuk mendeteksi dan mengukur kejadian-kejadian yang terjadi di luar mikrokontroler.

Saat mendeteksi event seperti rising edge atau falling edge pada pin ICP (PORTD.6), nilai pada register TCNT1 dimasukkan ke dalam register ICR1 dan flag ICF1 akan diset = ‘1’.

.

Berikut ini bit-bit yang digunakan pada register TCCR1B untuk mode input capture:

  • Bit 7 - ICNC1: Input Capture Noise canceller. Dengan mengatur bit ini = ‘1’ maka akan mengaktifkan noise canceller. Noise canceller menyebabkan delay selama 4 siklus clock karena Noise canceller memperhitungkan sebuah perubahan sinyal hanya jika sinyal input berada pada state yang sama setidaknya dalam 4 siklus clock sistem.
  • Bit 6 - ICES1: Input Capture Edge select. Bit ini digunakan untuk memilih tepi mana yang akan digunakan untuk merekam/mengangkap input.
    • 0 = menangkap saat falling edge
    • 1 = menangkap saat rising edge
  • Bit 4: 3 - WGM13 : WGM12: Timer1 Mode select. Bit-bit ini digunakan untuk pemilihan mode seperti: mode Normal, mode PWM, mode CTC, dll. Disini akan dipilih mode normal sehingga akan bit-bit tersebut diset ‘0’ semua.
  • Bit 2: 0 - CS12: CS10:Timer1 Clock Select.

Langkah-langkah pemrograman input capture:

  1. Inisialisasi register TCCR1A & TCCR1B untuk menentukan mode timer yang sesuai(mode apapun selain 8, 10, 12, 14) dan memilih tepi trigger(falling atau rising)
  2. Pantau flag ICF1 pada register TIFR untuk mendeteksi apakah tepi dari sinyal input sudah terdeteksi. Saat tepi sinyal tersebut terdeteksi maka nilai register TCNT1 dimasukkan pada ICR1 secara otomatis oleh kontroler.

Catatan: Pin input capture (PORTD.6) memiliki 1 lagi kegunaan yaitu output komparator analog. Anda dapat menggunakan bit ACIC pada register ACSR untuk membuat pin ini sebagai output komparator analog dengan mengatur bit ini = ‘1’. Sebaliknya pin ini tetap berfungsi sebagai ICP1 secara default setelah MCU dihidupkan atau di-reset. Sehingga anda tidak perlu mengatur register ACSR disini.

Program Input Capture Untuk Menghitung Frekuensi dan Duty Cycle Sinyal:

Diasumsukan sinyal pulsa dihubungkan dengan pin ICP1. Program berikut ini akan membaca nilai TCNT1 pada setiap tepi naik (rising edge) dan hasilnya ditampilkan pada LCD 16x2 mode 4 bit.

.

/*
 * TIM COUNT14.c
 *
 * Created: 29/01/2023 20:57:01
 * Author : DELL
 */ 
#define F_CPU 8000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <stdlib.h>
#include "LCD_16x2_H.h"

int main ( )
{
	unsigned int a,b,c,high,period;
	char frequency[14],duty_cy[7];
	
	LCD_Init();
	PORTD = 0xFF;			/* Turn ON pull-up resistor */
	
	while(1)
	{
		TCCR1A = 0;
		TCNT1=0;
		TIFR = (1<<ICF1);  	/* Clear ICF (Input Capture flag) flag */

		TCCR1B = 0x41;  	/* Rising edge, no prescaler */
		while ((TIFR&(1<<ICF1)) == 0);
		a = ICR1;  		/* Take value of capture register */
		TIFR = (1<<ICF1);  	/* Clear ICF flag */
		
		TCCR1B = 0x01;  	/* Falling edge, no prescaler */
		while ((TIFR&(1<<ICF1)) == 0);
		b = ICR1;  		/* Take value of capture register */
		TIFR = (1<<ICF1);  	/* Clear ICF flag */
		
		TCCR1B = 0x41;  	/* Rising edge, no prescaler */
		while ((TIFR&(1<<ICF1)) == 0);
		c = ICR1;  		/* Take value of capture register */
		TIFR = (1<<ICF1);  	/* Clear ICF flag */

		TCCR1B = 0;  		/* Stop the timer */
		
		if(a<b && b<c)  	/* Check for valid condition, 
					to avoid timer overflow reading */
		{
			high=b-a;
			period=c-a;
			
			long freq= F_CPU/period;/* Calculate frequency */

						/* Calculate duty cycle */
            		float duty_cycle =((float) high /(float)period)*100;			
			ltoa(freq,frequency,10);
			
			itoa((int)duty_cycle,duty_cy,10);
			
			LCD_Command(0x80);
			LCD_String("Freq: ");
			LCD_String(frequency);
			LCD_String(" Hz    ");
			
			LCD_Command(0xC0);
			LCD_String("Duty: ");
			LCD_String(duty_cy);
			LCD_String(" %      ");
			
		}
		
		else
		{
			LCD_Clear();
			LCD_String("OUT OF RANGE!!");
		}
		_delay_ms(50);
	}

}

..

Video Demo:


.

Berikut ini Link semua program di atas:

https://drive.google.com/file/d/1vKChk2WWNDzQcGoLLf_t-WlGvejoPb2-/view?usp=sharing

Tinggalkan Balasan

Alamat email Anda tidak akan dipublikasikan. Ruas yang wajib ditandai *