ATMEL PROGRAMLAMA 24 - Timer/Counter1 Interrupt


Bir önceki konuda Timer/Counter1 birimini normal mode'da çalıştırarak 1sn lik zamanlama yapmıştık.Bu çalışmamızda ise 1sn'lik zamanlamayı interrupt ile yapacağız. Öncelikle bir önceki konuyu okumanızı ve prescaler değerinin nasıl ayarlandığını, çalışma mode'larının hangi kaydedicilerle kontrol edildiğini öğrenmenizi tavsiye ederim.


Öncelikle 1sn'lik zamanlama yapabilmek için prescaler değerini hesaplamalıyız. Bunu bir önceki konuda hesaplayıp 256 olarak bulmuştuk. Programımızda da "TCCR1B |=0x04;" ile yapmıştık.
Bu çalışmamızda interrupt kullanacağımız için interrupt ile ilgi registerları da ayarlamamız gerekmekte . Bunlar  :

1-  TIMSK1  ( Timer/Counter 1 Interrupt Mask Register) 
2-  TIFR1      (Timer/Counter1 Interrupt Flag Register )
3-  SREG      (Status Register)



 1-  TIMSK1 ( Timer/Counter 1 Interrupt Mask Register)



Bu registerda şimdilik bizi ilgilendiren  0.bit olan TOIE (Timer/Counter1 Overflow Interrupt Enable) bitidir.

TOIE = 1 ==>>  Timer/Counter1 Overflow Interrupt aktif olur.
TOIE = 0 ==>>  Timer/Counter1 Overflow Interrupt pasif olur.

gördüğümüz gibi  default olarak bu bit 0 . Biz 1 yapmalıyız.

Bunun için   TIMSK1 |= 0x01; komutunu kullanırız. 

Bu registerda başka bir düzenleme yapmayacağız. 

 

2-  TIFR1      (Timer/Counter1 Interrupt Flag Register )

 Bu register ile ilgili bir işlem yapmayacağız. Burada timer/counter1  Normal veya CTC mode da  timer overflow (TCNT1 istenilen değere ulaşıp tekarar 0'a döndüğünde ) olduğunda interrupt için 0. bite bakarak interrupt olup olmadığını anlayabiliriz. CTC mode işlemi yaptığımızda bu register kullanılacak.

3-  SREG      (Status Register)




Bu register'ın 7. biti yani I (Global Interrupt Enable)  ile bütün interruptlara izin vermeliyiz. aksi halde ayarlamış olduğumuz interruptlar aktif olmayacaktır.

İnterruptları aktif  yapmak için  sei(); komutunu kullanırız.

İnterruptları pasif yapmak için  cli(); komtunu kullanırız.




Programı yazarken dikkat edeceğimiz noktalar ;

1- #include <avr/interrupt.h>  programımıza interruptlarla ilgili header dosyasını eklemeliyiz.

2- 




Prescaler 256 olduğunda  TCNT1  31250 sayma yapmalı .Programda her 32 mikro saniyede bir TCNT1 bir artırılır ve 16 bit olduğu için 65535'e kadar sayar ve 65536 sayma yapmış olur .  fakat biz toplam 31250 sayma istiyoruz o zaman TCNT1  65536-31250=34286 değerinden başlayarak saymalı . Bu şekilde 34286 'dan başlar 65535'e kadar sayar ve oradan 0 a geçtiği an toplam 31250 sayma yapmış olur .sonuç olarak da 31250x32usn =1sn lik zamanlama sağlanmış olur.



şimdi programımızı yazacak olursak 



#include <avr/io.h>
#include <avr/interrupt.h>
#define F_CPU 8000000ul
#define led  PORTB0

void Timer1_ayar()
{
    TCNT1= 34286;
    TCCR1B |=0x04;     //prescaler değeri 256
    TIMSK1 |=0x01;    // Timer/Counter1 Overflow Interrupt aktif olur.
    sei();            // İnterruptları aktif
  
}

ISR(TIMER1_OVF_vect)
{
    PORTB^=(1<<led);
    TCNT1= 34286;  
}

int main(void)
{
    DDRB|=(1<<led);
    Timer1_ayar();
    while(1);
}

Yorumlar

Yorum Gönder