ATMEL PROGRAMLAMA 23 - Timer/Counter1 Normal Mode


     Timer/Counter1 birimi çalışma mantığı ve yapısal  olarak Timer/Counter0 birimine benzemekle birlikte en temel fark 16 bit olmasıdır. Bu sayede daha uzun süreli zamanlama yapılabileceği gibi 16 bitlik PWM sinyali de üretilebilmektedir.


Kaydediciler (Registers)

1- Sayma değerlerinin tutulacağı kaydediciler 16 bittir. bunlar :
    
    a)    TCNT1            :  Timer/Counter1 kaydedicisi
    b)    OCR1A/B       : Output Compare1  A ve B kaydedicisi 
    c)    ICR1               :  Input Capture  16 bitlik kaydedicilerdir. 

2- Kontrol kaydedicileri 8 bittir.
  
     a)  TCCR1A/B/C    :  Timer/Counter1Kontrol Kaydedicisi 
     b)  TIFR1                :   Timer  Interrupt Flag kaydedicisi
     c)  TIMSK1             :   Timer Interrupt Mask Kaydedicisi


Timer/Counter1 birimi clock kaynağı olarak prescaler ile dahili olarak veya T1 pininden harici olarak alabilir.



16 bitlik kaydediciler ile işlem yapmak:

    Normalde AVR CPU 8 bitlik data hattına sahiptir. Kaydediciler 16 bitlik dense bile gerçekte 328p içersinde 16 bitlik kaydedici yoktur. TCNT1,OCR1A/B ve ICR1  sanal 16bitlik kaydedicilerdir. C derleyicisi bu kaydedicileri tanır ancak  gerçekte ise yapılan işlem farklıdır.

   TCNT1 kaydedicisi gerçekte  bellekte TCNT1H VE TCNT1L olmak üzere 8 bitlik iki ayrı kaydedicidir. Aşağıdaki şekilde de bu durum görülmektedir. TCNT1H değeri geçici 8 bitlik bir kaydediciye yazılır ve kaydediciden okunarak işlem yapılır.

















Örneğin TCNT1 kaydedicisine 0x01FF bilgisi yüklenmek istenirse işlemlerin nasıl yapıldığı aşağıdaki şekilde görülmektedir. C derleyicisinde  TCNT1=0x01FF yazarak işlemi gerçekleştirebiliriz. Gerçekte ise derleyici bunu  aşağıdaki şekilde (datasheet sayfa 114) Assembly komutları kısmında görüleceği gibi 16 bitlik 0x01FF bilgisini 0x01 ve 0xFF olmak üzere iki kısma ayırır. Yüksek değerlikli olan 0x01 bilgisi TCNT1H kaydedicisine , düşük değerlikli olan 0xFF bilgisi ise TCNT1L kaydedicisine yüklenir. Okuma işlemi de aynı şekilde yapılır. 




   Burada dikkat edilmesi gereken olay TCNT1H ve TCNT1L 'ye değer yükleme sırasında kesme oluşursa yüklenecek değerlerde kayıp veya yanlışlık olabilir. Bunu engellemek için yapılması gereken 16 bitlik registerlara yazma-okuma yapmadan önce  kesmeleri iptal edilmelidir.  Aşağıdaki şekilde bununla ilgili örnek program görülmektedir.(datasheet sayfa 116)



Çalışma mod seçimi
     Timer/Counter1 biriminin hangi modda kullanılacağına WGM1[3:0] ve COM1x[1:0] bitleri ile karar veririz. Burada sadece Normal ve  CTC Modları anlatacağım için bizim için önemli olan WGM1[3:0] bitleridir. Aşağıdaki tabloda gördüğümüz gibi toplam 14 mod var ve  bunlardan birçoğu PWM ile ilgili .


WGM1[3:0] bitlerini  TCCR1A ( Timer/Counter1 Control Register A) ve TCCR1B ( Timer/Counter1 Control Register B) kaydedicileri ile düzenleriz.Default olarak denetleyicimiz normal moddadır.



 Clock kaynağı seçimi

Timer/Counter1 birimi zamanlayıcı (Timer) olarak kullanılmak istendiğinde saat sinyali kaynağı olarak sistem saat sinyalini kullanır. Sayıcı (Counter ) olarak kulllanılacağı zaman ise sayılacak pulsler T1 pininden alınır. Herhangi bir saat sinyal kaynağı seçilmemişse  Timer/Counter1 birimi aktif olmaz.  Saat sinyali seçimi TCCR1B kaydedicisi içindeki Clock Select (CS12:0) bitleri tarafından yapılır.  Clock Select (CS1[2:0]) bitleri aynı zamanda prescaler değerinin belirlenmesini sağlar.

  Aşağıdaki tabloda Clock Select (CS1[2:0]) bitlerinin alabileceği değerler ve buna karşılık seçilecek saat sinyal kaynağı ve prescaler değeri görülmektedir.


Clock Select (CS1[2:0]) bitlerini TCCR1B ( Timer/Counter1 Control Register B) kaydedicisi ile düzenleriz.

Zaman ayarı

Timer/Counter1 birimi 16 bit olduğundan dolayı Timer/Counter0 birimine  göre daha uzun süreler elde edebiliriz. Çalışma mantıkları aynıdır.

Örneğin 1sn'lik bir süre elde etmek istersek Timer/Counter1 birimini nasıl ayarlayacağız.

Mikrodenetleyicimiz  8Mhz lik dahili RC osilatör ile çalıştığını unutmamalıyız.  Buna göre aşağıdaki tabloda kullanılabilecek prescaler değerleri ve buna karşılık TCNT1 kaydedicisinin sayma  değerleri gösterilmiştir.

 
 TCNT1 kaydedicimiz 16 bitliktir ve alabileeği en büyük değer 0xFFFF yani 65535'tir. bu bilgiye göre tablyu incelersek ilk üç değer (8000000,1000000 ve 125000) 65535 değerinden büyüktür. bu nedenle bunlara karşılık gelen prescaler değerini kullanamayız. Son değer olan 7812,5 sayısı     65535'ten küçüktür. Ancak ondalıklı sayı olduğu için hesaplamalarda kesin doğru sonuçlar çıkarmaz. burada kullanabileceğimiz en uygun değer 31250'dir ve prescaler değeri 256 olmalıdır.(bu tablonun nasıl oluştuğunu bu konuyu inceleyerek öğrenebilirsiniz.)

 programımız

TCCR1B registerını incelerseniz reset değeri 0x00 olduğunu görürsünüz.   Yani denetleyicimiz default olarak normal mode'da .Bu nedenle programda normal mode ile ilgili bir düzenleme yapmıyoruz. Sadece prescaler değerini ayarlıyoruz.

#include <avr/io.h>
#define F_CPU 8000000ul
#define led  PORTB0
uint16_t sayac=0;

void Timer1_ayar()
{
    TCCR1B |=0x04;  
//prescaler değeri 256    
    TCNT1=0 
}

int main(void)
{
    DDRB|=(1<<led);
   
    Timer1_ayar();
   
    for(;;)
    {
        if(TCNT1 >=31249 // tabloda 31250 biz (31250-1 ) yapıyoruz
        {
          
            PORTB^=(1<<led);
            TCNT1=0;
        }
          
    }
   
}
 




 



Yorumlar