Merhaba, uzunca bir aradan sonra tekrar birlikteyiz. CCS-C ile Pic programlama kategorisinde en son Timer’lar ve interrupt konularına değinmiştik, bu yazımızda da timer’lardan devam ediyoruz.

Yazımızın amacı CCS-C derleyicisinde Timer modüllerinin nasıl kullanılabileceğini göstermek. İlk konularda da söylediğimiz gibi CCS-C derleyicisinin hiçbir hazır fonksiyonunu kullanmak zorunda değilsiniz. Sadece datasheet’e bakarak PIC’in tüm donanımları için kod yazabilirsiniz. Yazı içerisinde hem hazır fonksiyonlar, hem de hazır fonksiyonlar olmadan bu işin nasıl yapılabileceğini anlatmaya çalışacağım. Örnek PIC denetleyicisi olarak PIC16F628A kullanacağım, elinizde datasheet’in olması faydalı olacaktır.

Dahili fonksiyonlar ile Timer0 kullanımı

  • setup_timer_0() : Timer0 konfigürasyonu için,
  • set_timer0() veya set_rtcc() : Timer0′a değer atamak için,
  • get_timer0() veya get_rtcc(): Timer0 değerini okumak için kullanılır

setup_timer_0(mode)

Bu fonksiyon timer0′ı konfigüre etmek için kullanılır. Öncelikle Timer0′ın dahili mi yoksa harici mi kullanılacağını belirtmemiz gerekiyor, bunun için şu değerler kullanılabilir;

RTCC_INTERNAL: Timer0 dahili clock sinyalini kullanacak.
RTCC_EXT_L_TO_H: Timer0 harici clock sinyali kullanacak (TOCKI Pin’inden) , sinyalin yükselen kenarında sayacak.
RTCC_EXT_H_TO_L: Timer0 harici clock sinyali kullanacak (TOCKI Pin’inden) , sinyalin düşen kenarında sayacak.

Daha sonra prescaler değerini belirtmemiz gerekecek, bunun için ise aşağıdaki değerleri kullanabilirsiniz.

RTCC_DIV_2, RTCC_DIV_4, RTCC_DIV_8, RTCC_DIV_16, RTCC_DIV_32, RTCC_DIV_64, RTCC_DIV_128, RTCC_DIV_256

Sadece PIC18FXXX serisinde geçerli olmak üzere RTCC_OFF ve RTCC_8_BIT parametreleride  kullanılabiliyor.

// Timer0 internal ve prescaler 4
setup_timer_0(RTCC_INTERNAL | RTCC_DIV_4); 

// Timer0 external girişten yükselen kenarda sayacak precaler 8
setup_timer_0(RTCC_EXT_L_TO_H | RTCC_DIV_8); 

// 18FXXX için timer0 8 bit dahili clock ve prescaler 2
setup_timer_0(RTCC_8_BIT|RTCC_INTERNAL|RTCC_DIV_2); 

set_timer0(value), set_rtcc(value)

Bu fonksiyonların ikiside Timer0 değerini ayarlamak için kullanılır,  parametre olarak 8 bit 0-255 arasında bir değer alır (18FXXX serisinde 16 bit yani 0-65535)

set_timer0(125); // Timer0 değeri 125 olur
set_rtcc(125); // Timer0 değeri 125 olur
set_timer0(0); // timer0 değeri 0 olur
set_timer0(0x0f); // Timer0 değeri 15 olur    (hex atama)
set_timer0(0b00001111); //Timer0 değeri 15 olur (binary atama)

get_timer0(value), get_rtcc(value)

Bu fonksiyonlar da timer0′ın o anki değerini okumak için kullanılırlar. Fonksiyonlardan geriye dönen değerler 8 bit yani 0-255 arasında bir değerdir (18FXXX serisinde 16 bit 0-65535 arası)

int x;
long y;
x= get_timer0(); // x = timer0'ın o anki değeri
y= get_timer0(); // y = timer0'ın o anki değeri (18fxxx)

Timer0 için kendimiz kod yazalım

Öncelikle datasheet’te Timer0 modülü ile ilgili kısmı inceliyoruz ve inceleme sonucunda OPTION register’inde timer0 ile ilgili ayarlar olduğunu görüyoruz.

optionreg

TOCS: “0″ yapılırsa timer0 modülü dahili saat frekansını kullanır, “1″ yapılırsa RA4/TOCKI pininden uygulanacak sinyali kullanır.
TOSE: “0″ yapılırsa RA4/TOCKI pininden uygulanan sinyalin yükselen kenarında sayar, “1″ yapılırsa düşen kenarında sayar. Bu ayar TOCS  “1″ olduğu durumda geçerlidir.
PSA: Timer0 ve WatchDog Timer’ın  aynı prescaler’i kullandığını bir önceki timer yazımızda belirtmiştik. PSA biti 0 yapılırsa prescalar’ı Timer0 modülüne atanır, bu durumda timr0 için istenilen prescaler değeri ayarlanabilirken watchdog timer için prescaler değeri sadece “1:1″ olur. PSA biti 1 yapıldığında ise prescaler WatchDog Timer’ına atanacağında WDT için istenilen prescaler seçilebilirken Timer0 için prescaler sadece “1:2″ olarak ayarlanır.

PS2-PS0: 3 Bitlik bu değer ise istenilen prescaler değerini ayarlamak için kullanılır, prescaler timer0 veya WDT den hangisine atanmışsa ayar onun için geçerli olur.

Timer0 a değer atamak veya Timer0 değerini okumak için tek bir register kullanılmaktadır. Bu register 0×01 adresindeki TIMER0 registeridir.

#byte OPTION_REG = 0x81      // OPTION Register tanımlaması
#byte TIMER0 = 0x01 // Timer0 modül registeri
int x;
// Timer0 internal, prescaler = 4
OPTION_REG = OPTION_REG & 0xC1;

// Timer0 external, Yükselen kenar, prescaler 8
OPTION_REG = OPTION_REG & 0xE2; 

TIMER0 = 125  // Timer0 değeri 125 olur
TIMER0 = 0  // Timer0 değeri 0 olur
x = TIMER0  // Timer0'ın değerini x'e aktar

Dahili fonksiyonlar ile Timer1 kullanımı

  • setup_timer_1() : Timer1 konfigürasyonu için,
  • set_timer1() : Timer1′e değer atamak için,
  • get_timer1() : Timer1 değerini okumak için kullanılır.

setup_timer_1(mode)

Bu fonksiyon Timer1′in ayarlarını yapmak için kullanılır, kullanılabilecek parametreler şunlardır;

T1_DISABLED: Timer1 modülünü kapatmak için kullanılır, güç tüketiminin kritik öneme sahip olduğu uygulamalarda kullanılmayan timer’ları kapatmak akıllıca olacaktır.

T1_INTERNAL: Timer1 modülü dahili saat frekansını kullanır.

T1_EXTERNAL: Timer1 modülü harici sinyal kullanacak. (Kristal veya Başka bir sinyal)

T1_EXTERNAL_SYNC: Timer1 harici clock kullanacak ve bu clock dahili olarak senkronize edilecek.

T1_DIV_BY_1, T1_DIV_BY_2, T1_DIV_BY_4, T1_DIV_BY_8: Timer1 için 4 adet prescaler kullanılabilmektedir.

Örnekler:

// Timer1 dahili clock ile çalışacak, prescaler değeri 4.
setup_timer_1(T1_INTERNAL | T1_DIV_BY_4) 

// Timer1 modulünü kapat
setup_timer_1(T1_DISABLED); 

// Timer1 harici clock ile çalışacak, prescaler değeri 8
setup_timer_1(T1_EXTERNAL | T1_DIV_BY_8);

set_timer1(value)

Bu fonksiyon timer1′e değer atamak için kullanılır, timer1 16 bit olduğu için atanacak değer 0-65535 arası olabilir (0×0000-0xffff)

set_timer1(0x00ff);  // Timer1 değeri 255 olur
set_timer1(0); // Timer1 değeri sıfırlanır
set_timer1(20000); //Timer1 değeri 20000

get_timer1(value)

Bu fonksiyon timer1′in değerini okumak için kullanılır, timer1 16 bit olduğu için fonksiyondan geriye dönen değer değer 0-65535 arası olabilir (0×0000-0xffff)

long x;
x = get_timer1();  // timer1 değerini x'e aktar

Timer1 için kendimiz kod yazalım

Timer1 ayarları için kullanılan register T1CON registeridir.

t1con

T1CKPS1: T1CKPS1: Timer1 için 2 bitlik prescalar ayarı  , Timer1 prescaler’ı 1,2,4,8 oalrak ayarlanabilmektedir.

00 — 1:1 Prescaler
01 — 1:2 Prescaler
10 — 1:4 Prescaler
11 — 1:8 Prescaler

T1OSCEN: Timer1 için kristal ayar biti, eğer kristal kullanılıyorsa bu bit “1″ yapılmalıdır
T1SYNC: Timer1 için harici clock seçildiğinde senkronizasyon olup olmayacağını belirtmek için kullanılır değerinin “0″ olması senkronize olacak manasına gelir. Timer1 için dahili clock seçildiği durumda değeri önemsizdir.
TMR1CS: Timer1′in clock seçim biti, değeri “0″ ise timer1 dahili clock kullanır, “1″ yapıldığında harici clock seçilmiş olur.
TMR1ON: Timer1 kontrol biti, “0″ yapıldığında timer1 modülü durur, “1″ yapıldığında çalışır.

Timer1 16 bitlik olduğu için değeri 2 adet 8 btilik register’da saklanır, bu register’lar TMR1L ve TMR1H’dır.

#byte T1CON = 0x10  // T1CON tanımlaması
#byte TMR1L = 0x0E  // TMR1L tanımlaması
#byte TMR1H = 0x0F  // TMR1L tanımlaması
long time;

T1CON = 0x21; // Timer1 dahili clock, prescaler 4 0b00100001
T1CON = 0; // Timer1 kapalı
T1CON = 0x37 //Timer1 ext. clock,prescaler 8,senkronizasyon yok

time = ((time|TMR1H) <<8 )|TMR1L; //timer1 değerini time'a ata
TMR1L = time;             // time değişkenine
TMR1H = (time >> 8);   // timer1 değerini al

Dahili fonksiyonlar ile Timer2 kullanımı

  • setup_timer_2() : Timer2 konfigürasyonu için,
  • set_timer2() : Timer2′ye değer atamak için,
  • get_timer2(): Timer2 değerini okumak için kullanılır

setup_timer_2(mode,period,postscale);

Timer2 ayarları bu fonksiyon ile gerçekleştirilebilir, mode parametresi aşağıdaki değerlerden birini alabilir,

T2_DISABLED: Timer2 modülünü kapatmak için bu değer kullanılır, diğer parametreler önemsiz olur

T2_DIV_BY_1, T2_DIV_BY_4, T2_DIV_BY_16: Timer2 prescaler değeri 1,4 veya 16 olarak ayarlanabilir.

period: 0 ila 255 arası bir değer alır, timer2 bu değere kadar sayar ve taşma oluşur. Örneğin bu değer 125 yapılırsa timer2 0-125 arası sayar

postscale: 1 – 16 arası bir değer atanabilir, 1 atanması timer2 her taştığında interrupt oluşacak manasına gelir 2 atanması her 2 taşmada bir interrup oluşturulacağı 16 atanması her 16 taşmada bir interrupt oluşturulacağı manasına gelir.

// Prescaler 16, sayma 0-255, interrupt her taşmada
setup_timer_2(T2_DIV_BY_16,255,1); 

// Prescaler 4, sayma 0-100, interrupt her 4 taşmada 1
setup_timer_2(T2_DIV_BY_4,100,4);

set_timer2(value)

Bu fonksiyon timer2′ye değer atamak için kullanılır, atanacak değer 0-255 arasında yani 8 bitlik  olmalıdır

set_timer2(200);  // Timer2 değeri 200 olur
set_timer2(0);  // Timer2 değeri sıfırlanır
set_timer2(10);  //Timer2 değeri 10 olur

get_timer2(value)

Bu fonksiyon timer2′nin değerini okumak için kullanılır, timer2 8 bit olduğu için fonksiyondan geriye dönen değer değer 0-255 arasındadır

int x;
x = get_timer2();  // timer2 değerini x'e aktar

Timer2 için kendimiz kod yazalım

t2con

Timer2 ayarları için kullanılan register’in adı T2CON’dur ve adreside 0×12 dir. Şimdi bu registerla yapılabilen ayarlamaları görelim;
TOUTPS3:TOUTPS0: 4 Bitlik Ppostscale ayarı, daha önce bahsetmiştik 1-16 arası bir değer alabiliyor.
TMR2ON: Timer2 kontrol biti, Timer2 modülünü kapatmak için bu bit “0″ yapılır, açmak için ise “1″ yapılır.
T2CKPS1:T2CKPS0: 2 Bitlik Prescaler seçimi, prescaler değeri 1,4,16 değerlerinden birine ayarlanabilir.
00: prescaler 1
01: prescaler 4
1x: prescaler 16

Yukarıda timer2′nin periyot ayarından bahsetmiştik, gördüğünüz gibi bu ayar T2CON registerinde değil. Periyot kontrolü için PR2 isimli 8 bitlik ayrı bir register kullanılıyor ve adreside 0×92.

#byte T2CON = 0x12  // Timer2 control register
#byte TMR2  = 0x11 // Timer2 değerini tutan register
#byte PR2 = 0x92 // Timer2 periyot register
int x;

// Prescaler 16, sayma 0-255, interrupt her taşmada
T2CON = 0x06;  //0b00000110
PR2 = 255;

// Prescaler 4, sayma 0-100, interrupt her 4 taşmada 1
T2CON = 0x25;  //0b00100101
PR2 = 100;

//timer2 değerini okuma
x = TMR2;  // Timer2 değeri x'e okunur.

//Timer2 derini yazma
TMR2 = 50;  // Timer2 değeri 50 olur

PIC Mikro Denetleyicilerinde en sık kullanılan Timer modüllerinin CCS-C derleyicisinde nasıl kullanıldığını öğrendik artık. Bir sonraki yazı yine timer’lar, yeni yazımda timer modüllerinin kullanımıyla ilgili gerçek örnekler bulunacak. Örnekleri Pic Geliştirme Kiti üzerinde yapacağım, imkanım olursa videolarını da koymayı düşünüyorum.