Arduino ile Zamanlayıcılar ve Sayıcılar (Timers and Counters)

watch_later 1/19/2016
comment 1 Comment
3 tane zamanlayıcı/sayıcı bulunmakta:
   2 tanesi 8-bit Timers/Counters (0-255)
      Timer 0
      Timer 2
   1 tanesi 16-bit Timer/Counter (0-65535)
      Timer 1



Zamanlayıcı Saklayıcıları ve Bayrakları
TCNTn (Timer/CouNTer Register)
TOVn (Timer OVerflow Flag)
TCCRn (Timer/Counter Control Register)
OCRn (Output Compare Register)
OCFn (Output Compare Match Flag)
TIFRn (Timer Interrupt Flag Register)
(n=0,1 veya 2)

Zamanlayıcı Saklayıcı ve Bayrak Simülasyonu
Normal Mode

                                            
Normal Mod Çalışma Prensibi
Örneğin Normal Modda 8 sn zamanlayıcı tasarlayalım.

Zaman Periyodu=(1/Frekans)
Zaman Periyodu=1/16000000
Zaman Periyodu=0.0000000625 sn
1 sn Zaman Sayacı=16000000 /1024
1 sn Zaman Sayacı=15625
Maximum Ölçülebilecek Süre=(1/15625)*65535
Maximum Ölçülebilecek Süre=4.19424 sn

8 sn Zaman Sayacı=(Gecikme Süresi*1 sn Zaman Sayacı)
8 sn Zaman Sayacı=(8*15625)
8 sn Zaman Sayacı=125000
X=125000

            Zaman Sayacı=125000>65536
      125000/65536 bölümden kalan değer kadar taşma olacaktır.
      125000 değeri içerisinde 1 tane 65536 değeri bulunur ve 1 taşma olacaktır.
      125000-65536=59464 kadar yeniden sayması gerekir.
                                          
CTC (Clear Timer on Compare Match) 


CTC Mod Çalışma Prensibi
Örneğin CTC Modda 10 sn zamanlayıcı tasarlayalım.

Zaman Periyodu=(1/Frekans) 
Zaman Periyodu=1/16000000
Zaman Periyodu=0.0000000625 sn

1 sn Zaman Sayacı=16000000/256
1 sn Zaman Sayacı=62500
Maximum Ölçülebilecek Süre=(1/62500)*65535
Maximum Ölçülebilecek Süre=1.04856 sn

Zaman Sayacı=(Gecikme Süresi*1 sn Zaman Sayacı)
Zaman Sayacı=(10*62500)
Zaman Sayacı=625000
Y=625000

              Zaman Sayacı=625000>65536
       625000/65536 bölümden kalan değer kadar taşma olacaktır.
       625000 değeri içerisinde 9 tane 65536 değeri bulunur ve 9 taşma olacaktır.
       625000-65536*9=35176 kadar yeniden sayması gerekir.
                                                  
Zamanlayıcının çalışması için osilatör de prescaler ayarı vardır. Bu ayar bizim kristalimizin çalışma frekansını düşürmek için kullanılır. Arduino osilatörü 16Mhz de çalışır. 64 prescaler değeri ile kullanmak istersek 16000000 / 64 yani 250000 anlamına gelir. 

Fcpu=16 MHz
             TIMER 0 8-bit (0−255)
prescaler = 1, 16 ms sayar.
prescaler = 1024, 16.384 ms sayar.
TIMER 1 16-bit (0−65536)
prescaler = 1,  4.096 ms sayar.
prescaler = 1024, 4.194 saniye sayar.
TIMER 2 8-bit (0−255)
             prescaler = 1, 16 ms sayar.

Osilatörde Prescaler Değeri Olmadığında
                                      
Osilatörde Prescaler Değeri Olduğunda
Zamanlayıcı tasarlarken yardımcı olacak saklayıcı, prescaler ve bayrak değer tabloları:

TIMER1 Prescaler Değerleri 
                                  
TIMER1 TCCR1A, TCCR1B ve TIFR1 saklayıcıları


Normal Modda 8 sn zamanlayıcı AVR C kodu:
                                                                                  
#include 
int sayac = 0; //bayrakların sayısını tutan değişken
int main()
{
setup:
  DDRD |= (1 << 5); //pinMode olarak 5 nolu pin ayarlanır. 00100000
  PORTD &= ~(1 << 5); //tüm pinler(0-7) LOW olarak ayarlandı. 00000000
  TCCR1B = ((1 << CS12) | (1 << CS10)); //prescaler değeri 1024 olarak ayarlanır. 00000101
loop:
  while (1)
  {
    TCNT1 = 49911; //1 sn değeri için zaman sayacı 65535-15625=49911
    if (TCNT1 == 49911) //Bu değere eşitse
    {
      while ((TIFR1 & (1 << TOV1)) == 0); /*sorgulama yap bayrak yani 
   TOV1 1 mi değilse bişey yapma.*/
      sayac++;
      TIFR1 |= (1 << TOV1); //bayrak yani TOV1 değerini sıfırla.
    }

    if (sayac == 8) //8sn'ye eşit olunca yani sayac 8'e eşitse
    {
      PORTD ^= (1 << 5); //HIGH ise LOW/LOW ise HIGH
      sayac = 0;
    }
  }
  return 0;
}
CTC Modda 10 sn zamanlayıcı AVR C kodu(256 prescaler):
#include 
int sayac = 0;//bayrakların sayısını tutan değişken
int main()
{
setup:
  DDRB |= (1 << 1); //pinMode olarak 9 nolu pin ayarlanır. 00000010
  PORTB &= ~(1 << 1); //tüm pinler(8-13) LOW olarak ayarlandı. 00000000
  TCCR1B |= (1 << WGM12); //CTC Mode çalıştığını belirt. 00001000
  TCCR1B |= (1 << CS12); //prescaler değeri 256 olarak ayarlanır. 00000100
  OCR1A = 62500; //yükselen kenar tetiklemesinin max değeri
loop:
  while (1)
  {
    if (OCR1A == 62500) //Bu değere eşits
    {
      while ((TIFR1 & (1 << OCF1A)) == 0);/*sorgulama yap bayrak yani 
     OCF1A 1 mi değilse bişey yapma.*/
      sayac++;
      TIFR1 |= (1 << OCF1A);//bayrak yani OCF1A değerini sıfırla.
    }
    if (sayac == 10) //10sn'ye eşit olunca yani sayac 10'a eşitse
    {
      PORTB ^= (1 << 1);//HIGH ise LOW/LOW ise HIGH
      sayac = 0;
    }
  }
  return 0;
}
T0 ve T1 Pinout Diyagramı 






Bir sonraki yazımda görüşmek üzere…
avatar

Merhaba. Ben rfid ile kilit projesi yapıyorum. Koda eklediğim kartlar dışında
Mesela yanlış kart okuttuktan sonra 2sn içinde master kart okutulur sa kart ekleme fonksiyonu devreye girsin önce yeni kart sonra bir süre içinde master kart okunurse yeni kartı hafızaya kaydet sin istiyorum. Bu süre sayacını nasıl sağlarım.

delete 23 Aralık 2016 01:20



sentiment_satisfied Emoticon