2 Ocak 2018 Salı

Zaman Kesmesi (Timer Interrupt)


Zaman kesmesi (timer interrupt), belirli süre aralıklarında belirli görevlerin yapılabilmesi için kullanılır. Örneğin bir LED'in saniyede bir yakıp söndürülmesi gerekmektedir. Bu işlem için loop fonksiyonunun kullanılması yerine, zaman kesmesinin kullanılması Arduino programının rahatlamasını sağlayacaktır. Kullanılan kesme her saniyede bir Arduino'ya haber vererek, LED'in yakılıp söndürülmesini sağlayacaktır.
Zaman kesmelerinin ayarlanabilmesi için bazı program değişkenlerinin ayarlanması gerekir. Bunlardan en önemlisi zaman sayıcısıdır. Bu değişkende tutulan değer, her saat darbesinde bir artar. Taşma değerine ulaştığında sıfırlanır ve Arduino'ya sürenin dolduğunu, kesmenin yapılması gerektiğini bildirir. Bu değişkenin başlangıç değeri ayarlanarak, kesmeler arasındaki geçecek zaman ayarlanabilir.
Farz edelim ki, 8 bitlik zaman sayıcısının ilk değeri 50 olarak belirlendi. Her adımda bu değer bir artırılacaktır. Zaman sayıcısının değeri 255 olduktan bir adım sonra sıfırlanacaktır. Bu noktada zaman kesmesi gerçekleşecektir. Kesme gerçekleştiğinde Arduino otomatik olarak "ISR(TIMERx_COMPA_vect)" fonksiyonunu çalıştıracaktır. Bu fonksiyonun içerisine her kesmede yapılması istenilen görevler yazılır.
Zaman kesmesinin ne kadar sürede bir gerçekleşeceği, her adımın ne kadar sürede gerçekleşeceğiyle de alakalıdır. Bu süre Arduino'nun kristalinin 1, 1/8, 1/64, 1/256 ve 1/1024 oranında olması sağlanabilir. Zaman kesmesinin oluşma süresi aşağıdaki formül ile hesaplanabilir.

Zaman kesmesi kullanarak Kara Şimşek devresi

Zaman kesmesinin ne olduğunu ve nasıl ayarlandığını öğrendiğimize göre, bilgilerimizi pekiştirmek için bir örnek yapalım. Bu örnekte, ilk uygulamalarımızda yaptığımız Kara Şimşek devresini zaman kesmesi kullanarak yapacağız. Önceki uygulamada Kara Şimşek loop fonksiyonu içerisinde yapılmıştı. Bu projede Arduino'nun tüm gücü LED'leri kontrol etmek için kullanılmıştı. Eğer başka bir işlem yapılmak istenseydi, Arduino yetersiz kalabilirdi.
Bu projede ise LED'ler zaman kesmesi ile belirli sürelerde otomatik olarak yapılacağı için, Arduino başka işlemleri de rahatça yapabilecek.
Bu uygulamayı yapmak için ihtiyacımız olan malzemeler:
  • 1 x Arduino
  • 8 x LED
  • 8 x 220 Ohm direnç
  • 1 x Breadboard
const int LEDdizisi[] = {2,3,4,5,6,7,8,9};
int j = 0;

void setup()
{
  Serial.begin(9600);
  
  for(int i=0; i<8 ;i++)    
  { /* For döngüsüyle LEDdizisi elemanlarına ulaşıyoruz */
    pinMode(LEDdizisi[i], OUTPUT); /* LED pinleri çıkış olarak ayarlandı */
  } 
  
  cli();
  /* Ayarlamaların yapılabilmesi için öncelikle kesmeler durduruldu */

  /* Timer1 kesmesi saniyede bir çalışacak şekilde ayarlanacaktır (1 Hz)*/
  TCCR1A = 0;
  TCCR1B = 0;
  TCNT1  = 0;
  OCR1A = 15624;
  /* Bir saniye aralıklar için zaman sayıcısı ayarlandı */
  TCCR1B |= (1 << WGM12);
  /* Adımlar arasında geçen süre kristal hızının 1024'e bölümü olarak ayarlandı */
  TCCR1B |= (1 << CS12) | (1 << CS10);
  TIMSK1 |= (1 << OCIE1A);
  /* Timer1 kesmesi aktif hale getirildi */

  sei();
  /* Timer1 kesmesinin çalışabilmesi için tüm kesmeler aktif hale getirildi */

}

/* Arduino otomatik olarak her saniye aşağıdaki fonksiyonu çalıştıracaktır */
ISR(TIMER1_COMPA_vect){
  for(int i=0; i<8; i++){         
    digitalWrite(LEDdizisi[i],LOW);   
    /* Tüm LED'ler söndürüldü */      
  }
  digitalWrite(LEDdizisi[j],HIGH); 
  /* Sıradaki LED yakıldı */
  j ++;
  if(j > 7)
    j = 0;
}

void loop()
{
 Serial.println("Arduino burada baska islemler yapabilir");
 delay(100);
}
Yukarıdaki Arduino programında "LEDdizisi" değişkeninde Arduino'ya bağlanan LED'lerin pinleri kaydedildi. Setup fonksiyonu içinde bu LED pinleri çıkış olarak ayarlandı. Programın başka işler de yapabildiğini gösterebilmek için loop fonksiyonu içinde seri monitöre mesaj yazdırıldı. Bunun için setup fonksiyonunda seri haberleşme başlatıldı. Zaman kesmesinin açılması ve saniyede bir görev yapılabilmesi için setup fonksiyonu içerisinde Timer1 ayarlandı.
Zaman kesmesi saniyede bir "ISR(TIMER1_COMPA_vect)" fonksiyonunu çalıştırır. Bu fonksiyonun içinde LED'lerin sırayla yanmasını sağlayacak kodlar yazıldı. Bu kodlarda öncelikle tüm LED'ler sönük konuma getirilir, daha sonra sadece yanması gereken LED yakılır.

Hiç yorum yok:

Yorum Gönder