ATMega328 memiliki 8 bit timer/counter dan 16 bit timer/counter.
Masing-masing conter/timer memiliki prescaler 1, 8, 64, 256 dan 1024
dari pulsa clock. Selain itu counter/timer dapat mempergunakan pulsa
clock dari eksternal (Osilator yg terpisah) yaitu melalui pin 6 (PD4)
dan pin 11 (PD5). Kedua timer dan counter diperlengkapi dengan TOV0
(Timer Over Flow 0), OCF0A (Output Compare Flag 0A) dan OCF0B (Output
Compare Flag 0B). pada 16 bit counter/timer mendapat tambahan ICF1
(Input Capture Flag 1).
Timer sebenarnya merupakan sebuah counter, yaitu UC menghitung pulsa
clock yang berasal dari oscilator. Pulsa clock yang dihitung sudah
melalui prescaler atau dengan kata lain, pulsa dari oscilator dibagi
dengan prescale. Contoh frekuensi oscilator 1 MHz, dan prescaler
diset 8, maka satu hitungan sama dengan (1/1 MHz) * 8 = 8 μdet.
Prescaler diset melalui register TCCR1B (Timer Counter Control
Register 1B). Sehingga untuk menset prescaler 8 maka CS11 =
1, CS10 dan CS12 diclearkan. Gambar 1 memperlihatkan register TCCR1B.
Untuk memilih prescaler ditentukan oleh bit 0 sampai bit 2 pada
register TCCR1B. Gambar 2 memperlihatkan harga bit bit tersebut untuk
mensetting prescaler.
Gambar 2. Mensetting prescaler 16 bit counter pada ATMega328
Jumlah
pulsa clock yang telah dihitung, disimpan pada register TCNT1 untuk counter
16 bit atau TCNT0 untuk counter 8 bit. Jangkauan untuk 8 bit adalah
255 sedangkan pada 16 bit sebesar 65535. Berikut adalah
potongan program untuk mengakses TCNT1
Definisi
untuk jangkauan 16 bit counter adalah :
Contoh
mempergunakan counter 8 bit. Jika TCNT0 diberi nilai 250, maka bit
TOV0 akan menjadi satu (set) jika telah terjadi 56 pulsa clock.
Gambar 3. Isi Register TIFR1 pada ATMega328
Interrupt
pada register TIFR dapat dinonaktifkan jika global interrupt yang
terdapat pada register SREG didisable. Menclearkan bit ke-7 pada
register SREG mengakibatkan seluruh interrupt pada ATMega328 menjadi
tidak berfungsi. Maka global interrupt yang terdapat pada register
SREG harus diset agar interrupt dapat berfungsi. Perintah untuk
mengaktifkan global interrupt pada register SREG adalah sei().
Isi register SREG diberikan pada supplemen Bab ini.
Berikut
adalah potongan program untuk menonaktifkan interrupt dan
mengaktifkannya kembali.
ICIE1
(Timer1 Input Capture Interrupt Enable). Bit ke-5 dari register
TIMSK1 adalah bit ICIE1 yang bekerja jika global interrupt pada
register SREG diset dan bit ICIE1 dalam keadaan set. Jika ICF1 yang
terdapat pada register TIFR1 berubah menjadi set maka maka interrupt
vektor akan dieksekusi. OCIE1B (Timer1, Output Compare B Match
Interrupt Enable). Bit OCIE1B jika diset dan global interrupt
dalam posisi set maka Interrupt vector akan dijalankan saat OCF1B
yang terdapat pada register TIFR1 berubah menjadi set. Nama vektor
interrupt OCF1B dalam keadaan set adalah TIMER1_COMPB_vect.
Hal yang sama berlaku pada OCIE1A dengan
nama vektor interrupt TIMER1_COMPA_vect
TOIE1
(Timer1 Overflow Interrupt Enable). Bit yang sangat penting untuk
menjalankan vektor interrupt pada timer 16 bit adalah bit TOIE1. Agar
vektor interrupt yang bernama TIMER1_OVF_vect
dijalankan
maka bit ini harus diset. Vektor
TIMER1_OVF_vect
akan
dieksekusi jika isi register TCNT mengalami overflow yaitu berubah
keadaan dari top ke bottom.
Pada
gambar 1, Bit WGM12 dan WGM13 pada Register TCCR1B disetting
berdasarkan kombinasi dari register TCCR1A yaitu pada bit WGM10 dan
WGM11. WGM adalah Waveform Generation Mode. Isi Register TCCR1A
diperlihatkan pada gambar 4, sedangkan kombinasi WGM diperlihatkan
pada gambar 5.
Gambar 4. Isi register TCCR1A untuk counter 16 bit pada ATMega328
Bit
ke-4 sampai ke-7 (COM1B0,COM1B1, COM1A0, COM1A1) pada register TCCR1A
adalah Compare Output Mode pada channel A dan channel B. Pada
microcontroller ATMega328 terletak pada pin PB1 dan PB2 (OC1A dan
OC1B). Hal yang patut dicatat dalam hal ini adalah Data Direction
Register yang berkaitan dengan pin tersebut (OC1A atau OC1B) harus
diset agar driver output menjadi enable.
Berikut
adalah contoh program yang tampa mempergunakan interrupt vector.
//program
menyalakan 7 buah LED di PORTB dan 7 buah LED diPORTD
//
Untuk selengkapnya program dan video dapat dilihat diwebsite
//https://newbiehack.com/TimersandCountersDefaultandBasicUsage.aspx
#include
<avr/io.h>
int main(void)
{
int main(void)
{
DDRB
= 0b01111111; //mensetting agar PORTB seluruhnya menjadi
output
PORTB = 0b00000000; //Seluruh PORTB bernilai low
DDRD = 0b01111111; // Mensetting PORTD seluruhnya output
PORTD = 0b00000000; // Seluruh PORTD bernilai low
TCCR1B |= 1<<CS10 | 1<<CS11; // Prescaler 64.
int LEDNumber[2];
while(1)
{
PORTB = 0b00000000; //Seluruh PORTB bernilai low
DDRD = 0b01111111; // Mensetting PORTD seluruhnya output
PORTD = 0b00000000; // Seluruh PORTD bernilai low
TCCR1B |= 1<<CS10 | 1<<CS11; // Prescaler 64.
int LEDNumber[2];
while(1)
{
if
(TCNT1 > 2232) //menghitung pulsa clock sampai 2232
{
{
TCNT1
= 0; // menolkan isi register TCNT1.
PORTB = 1<<LEDNumber[0];
LEDNumber[0] ++;
if (LEDNumber[0] > 6)
{
PORTB = 1<<LEDNumber[0];
LEDNumber[0] ++;
if (LEDNumber[0] > 6)
{
LEDNumber[0]
= 0;
PORTD = 1<<LEDNumber[1];
LEDNumber[1] ++;
if (LEDNumber[1] > 6)
PORTD = 1<<LEDNumber[1];
LEDNumber[1] ++;
if (LEDNumber[1] > 6)
LEDNumber[1]
= 0;
}
}
}
}
Berikut
adalah contoh program counter 8 bit dengan mempergunakan interrupt
timer overflow dengan nama vektor interrupt TIMER0_OVF_vect.
//Id:
TOV0_sevenseg.c,ATmega8,8MHz,10Des2011,sidiknur@yahoo.com
#include
<avr/io.h>
#include
<avr/interrupt.h>
#include
"sevenseg.h"
#include
"_74595.h"
#define
DIGIT_NUM 3 //jumlah digit seven segment
#define
CHIP_NUM 2 //jumlah IC 74595
uint8_t
sevenseg_buf[DIGIT_NUM];
void
sevenseg_buf_put(uint8_t data, uint8_t *buf);
void
timer0_ovf_1ms_init(void);
int
main(void){
uint8_t
data;
DDRB
= 0x00;
PORTB
= 0xff;
_74595_init();
timer0_ovf_1ms_init();
while(1){
data
= PINB;
sevenseg_buf_put(data,sevenseg_buf);
}
return
0;
}
void
sevenseg_buf_put(uint8_t data, uint8_t *buf){
uint8_t
temp;
temp
= data/100;
buf[0]
= sevenseg_pattern(temp);
data
-= temp*100;
temp
= data/10;
buf[1]
= sevenseg_pattern(temp);
temp
= data%10;
buf[2]
= sevenseg_pattern(temp);
}
#define
T0V0_PRELOAD_1MS (0xff + 1 - 125)
//menginisialisasi
timer0 overflow tiap 1ms
void
timer0_ovf_1ms_init(void)
{
TCNT0
= T0V0_PRELOAD_1MS; //memberi nilai pada register TCNT0 = 131
TCCR0
= _BV(CS01) | _BV(CS00); //prescaler 64
TIMSK
|= _BV(TOIE0); //mengaktifkan timer0 overflow interrupt.
Sei();
// global interrupt pd sreg diaktifkan
}
//vektor
interupsi timer0 overflow
ISR(TIMER0_OVF_vect)
{
static
uint8_t digit = 0;
uint8_t
buf[CHIP_NUM];
TCNT0
= T0V0_PRELOAD_1MS;
buf[1]
= sevenseg_buf[digit];
buf[0]
= ~_BV(digit);
_74595_put(buf,CHIP_NUM);
if(++digit>=DIGIT_NUM)
digit
= 0;
}
#include
<avr/io.h>
#include <avr/interrupt.h>
int main(void)
{
#include <avr/interrupt.h>
int main(void)
{
sei();
DDRB |= 1<<PINB0;
TCCR1B |= 1<<CS10 | 1<<CS11 | 1<<WGM12;
TIMSK1 |= 1<<OCIE1A; // Mengaktifkan interrupt pada output compare match
DDRB |= 1<<PINB0;
TCCR1B |= 1<<CS10 | 1<<CS11 | 1<<WGM12;
TIMSK1 |= 1<<OCIE1A; // Mengaktifkan interrupt pada output compare match
OCR1A
= 15624; //membandingkan dengan TCNT.
//Jika
isi TCNT = 15624 maka Output Compare Interrupt akan
aktif
while(1)
{
}
while(1)
{
}
}
ISR(TIMER1_COMPA_vect)
{
ISR(TIMER1_COMPA_vect)
{
PORTB
^= 1<<PINB0;
}
Tidak ada komentar:
Posting Komentar