Bölüm-5 İleri Kesme Uygulamaları ve Diğer Zamanlayıcı Modülleri

PIE1 ve PIR1 Kaydedicileri

Bu başlık altında temel kesme uygulamaları kapsamında anlatılmış olan Timer0 modülünden farklı olarak diğer zamanlayıcı modülleri (Timer1, Timer2 ve Timer3) ve kesme uygulamalarından bahsedilecektir. Bu zamanlayıcı modülleri çevresel aygıt arayüzü (peripheral interface) olarak değerlendirildiklerinden onların kontrolü için ayrı kaydediciler vardır. Genel olarak Timer1 ve Timer2 modülleri PIE1 kaydedicisi ile etkinleştirilip, kesme kontrolü de PIR1 kaydedicisi ile yapılırken, Timer3 modülü PIE2 ve kesme kontrolü de PIR2 kaydedicisi üzerinden sağlanır.

Hafıza elemanları, seri haberleşme aygıtları, analog/dijital-dijital/analog dönüştürücüler, harici osilatör ve darbe üreteçleri, vb. çeşitli çevresel aygıtlardan oluşacak kesme işlemlerinin etkinleştirilmesi ve izlenmesi için bu kaydedicilerden faydalanılır.

PIC12F675, PIC16F628A, PIC16F887, PIC18F2550 gibi pek çok PIC ailesi MCU’da PIE1 ve PIR1 kaydedicileri bulunmaktadır. Bu kaydediciler MCU’nun yapısına bağlı olarak farklı özelliklere sahip olmakla birlikte, genel olarak çevresel aygıtlarla ilgili işlevleri yerine getirmek için kullanılmaktadır. PIC16F887 ve PIC18F2550 gibi çok işlevli mikrodenetleyicilerde bu kaydedicilerden ikişer adet bulunmaktadır.

Bu bölümde temel olarak PIC16F628A MCU’sunun PIE1 ve PIR1 kaydedicileri açıklanacaktır. Timer3 modülü ise PIC18F2550 mikrodenetleyicisi referans alınarak açıklanacaktır. Kaydedicilerde yer alan bitlerin sıralamaları değişmekle birlikte, diğer MCU’larda da aynı işlevlere sahiptirler.

PIE1 KAYDEDİCİSİ (ADRES: 8Ch) – Çeşitli çevresel aygıt kesmelerinin etkinleştirilmesini sağlayan bitlerin tutulduğu kaydedicidir.

bit 7 EEIE: EEPROM yazma işlemi tamamlandı kesmesi etkinleştirme biti
1 = EEPROM yazma işlemi tamamlandı kesmesi etkin
0 = EEPROM yazma işlemi tamamlandı kesmesi pasif
bit 6 CMIE: Karşılaştırıcı kesmesi etkinleştirme biti
1 = Karşılaştırıcı kesmesi etkin
0 = Karşılaştırıcı kesmesi pasif
bit 5 RCIE: USART RX alma kesmesi etkinleştirme biti
1 = USART alma kesmesi etkin
0 = USART alma kesmesi pasif
bit 4 TXIE: USART TX gönderme kesmesi etkinleştirme biti
1 = USART gönderme kesmesi etkin
0 = USART gönderme kesmesi pasif
bit 3 Kullanılmıyor: '0' olarak okunur.
bit 2 CCP1IE: CCP1 kesmesi etkinleştirme biti
1 = CCP1IE kesmesi etkin
0 = CCP1IE kesmesi pasif
bit 1 TMR2IE: Timer2 ile PR2 karşılaştırma kesmesi etkinleştirme biti
1 = Timer2 ile PR2 karşılaştırma kesmesi etkin
0 = Timer2 ile PR2 karşılaştırma kesmesi pasif
bit 0 TMR1IE: TMR1 taşma kesmesi etkinleştirme biti
1 = TMR1 taşma kesmesi etkin
0 = TMR1 taşma kesmesi pasif

Görüldüğü üzere PIE1 kaydedicisi, INTCON kaydedicisinin dışında kalan kesme işlemlerinin etkinleştirilmesi için kullanılır.

PIR1 KAYDEDİCİSİ (ADRES: 0Ch) – Çeşitli çevresel aygıt kesmelerinin aktif hale gelip gelmediğini bildiren bayrak bitlerinin tutulduğu kaydedicidir.

bit 7 EEIF: EEPROM yazma işlemi tamamlandı kesmesi bayrak biti
1 = EEPROM yazma işlemi tamamlandı (yazılım içinde sıfırlanması gerekir)
0 = EEPROM yazma işlemi tamamlanmadı ya da henüz başlamadı
bit 6 CMIF: Karşılaştırıcı kesmesi bayrak biti
1 = Karşılaştırıcı çıkışı değişti
0 = Karşılaştırıcı çıkışı değişmedi
bit 5 RCIF: USART RX alma kesmesi bayrak biti
1 = USART alma tamponu dolu
0 = USART alma tamponu boş
bit 4 TXIF: USART TX gönderme kesmesi bayrak biti
1 = USART gönderme tamponu dolu
0 = USART gönderme tamponu boş
bit 3 Kullanılmıyor: '0' olarak okunur.
bit 2 CCP1IF: CCP1 kesmesi bayrak biti
Tutma (Capture) Modu
1 = Bir TMR1 kaydedicisi tutma işlemi gerçekleşti (yazılım içinde temizlenmelidir)
0 = TMR1 kaydedicisi tutma işlemi gerçekleşmedi
Karşılaştırma (Capture) Modu
1 = Bir TMR1 kaydedicisi karşılaştırma eşleşmesi gerçekleşti
16 bitlik CCPR1 kaydedicisinin değeri TMR1H ve TMR1L kaydedicisi ile karşılaştırılır. Eşleşme (match) olursa bayrak değeri ‘1’ olur.
0 = TMR1 kaydedicisi karşılaştırma eşleşmesi gerçekleşmedi
PWM Modu
Bu modda kullanılmaz
bit 1 TMR2IF: Timer2 ile PR2 karşılaştırma kesmesi bayrak biti
1 = Timer2 ile PR2 karşılaştırması gerçekleşti (yazılım içinde temizlenmelidir)
0 = Timer2 ile PR2 karşılaştırması gerçekleşmedi
bit 0 TMR1IF: TMR1 taşma kesmesi bayrak biti
1 = TMR1 taşma kesmesi gerçekleşti
0 = TMR1 taşma kesmesi gerçekleşmedi

Görüldüğü üzere PIR1 kaydedicisi, INTCON kaydedicisinin dışında kalan kesme işlemlerinin durumunun izlenmesi için kullanılır.

Timer1 Modülü ve Timer1 Kesmesi

Pek çok 8 bit mikrodenetleyicide 16 bit değerinde bir Timer1 modülü bulunur. 16 bitlik Timer1 modülü PIC mikrodenetleyicilerde zamanlayıcı/sayıcı olarak kullanılmaktadır. TMR1H ve TMR1L olarak adlandırılan 8 bitlik iki ayrı kaydediciden oluşur. Timer1 modülünün Timer0 modülünden en önemli farkı yalnızca 16 bitlik olması değildir. Timer1 modülü yardımıyla gerçek zaman saati uygulamaları yapılabilir. Ayrıca MCU’nun düşük güç tüketimi sağlayan uyku modunda (SLEEP) çalışması istenen durumlarda, Timer1 kesmesi MCU’yu uyku modundan uyandırma özelliğine sahiptir. Bunun yanında Timer1 gibi zamanlayıcıların en önemli özelliği, mikrodenetleyicinin çevresel aygıtlardan gelen sinyalleri izlemesini sağlamaktır.

Şekil 5.1’de gösterilen kaydediciler yardımıyla 216-1 = 65535 değerine kadar sayma işlemi gerçekleştirilebilir. MCU’yu uyku modundan uyandırma özelliğine sahip kesmelerden biri de Timer1 kesmesidir. Program içinde 0-65535 arasında bir değere kurulan TMR1 değeri maksimum değere ulaştığında PIR1 kaydedicisinin TMR1IF bayrağı ‘1’ olur. Bu durumda, eğer mikrodenetleyici düşük güç tüketimi için uyku moduna sokulmuşsa uyku modundan çıkar ve normal güç tüketimi gerçekleşir.

Şekil-5.1 16-bit Timer1 modülünün 8 bitlik kaydedicileri

T1CON: TIMER1 KONTROL KAYDEDİCİSİ (ADRES: 10h – PIC16F628A)

bit 7-6 Kullanılmıyor: '0' olarak okunur.
bit 5-4 T1CKPS1:T1CKPS0: Timer1 giriş saat darbesi için 2 bitlik önölçekleyicidir.
11 = 1:8 Ön ölçekleme oranıdır. Saat frekansını 8’e böler. Böylece süre 8 katına çıkar.
10 = 1:4 Ön ölçekleme oranıdır. Saat frekansını 4’e böler.
01 = 1:2 Ön ölçekleme oranıdır. Saat frekansını 2’ye böler.
00 = 1:1 Ön ölçekleme oranıdır. Saat frekansını bire bir alır.
bit 3 T1OSCEN: Timer1 osilatörü kontrol bitidir.
1 = Osilatör etkinleştirilir.

Timer1 osilatör modunda çalıştırılacağı zaman T1OSI (giriş) ve T1OSO (aplifikatör çıkışı) pinleri arasına kristal osilatör bağlanabilir. Bu şekilde çalıştırılacak osilatörün en büyük avantajı MCU’nun uyku modunda olması durumunda da çalışmaya devam edecek olmasıdır. Bu pinlere bağlanacak düşük güç (Low Power-LP) ve düşük frekans (maks. 200kHz) bir kristal osilatör ile gerçek zaman saati uygulamaları yapılabilir. Şekil 5.2’de Timer1 harici OSC bağlantısına sahip bir PIC mikrodenetleyicisi için 32,768 kHz kol saati kristalinin bağlantısı gösterilmiştir.

Şekil-5.2 Timer1 modülünün harici düşük güç kristal ile osilatör modunda çalıştırılması

Mikrodenetleyici uyku modunda çalışıyorken uyku modundan çıkartılması istenen durumlarda osilatör modundan faydalanılır. T1OSO ve T1OSI girişlerine bağlanacak ikinci bir osilatör ile ya da harici saat darbesi kaynağı ile MCU’yu uyandıracak kesme elde edilebilir.

Tablo 5.1 Timer1 modülünün osilatör modu için düşük güç kristallerin seçimi
OsilatörFrekansC1C2
LP32 kHz33 pF33 pF
100 kHz15 pF15 pF
200 kHz15 pF15 pF
0 = Osilatör kapatılır. Osilatörün drain akımını kesmek için geri besleme direnci ve invertör devresi kapatılır.
bit 2 T1SYNC: Timer1 harici saat darbesi girişi senkronizasyon kontrol bitidir.
TMR1CS = 1 olması durumunda,
1 = Harici saat darbesi girişi senkronize edilmez.

MCU’nun uyku modunda çalıştırılması ve harici osilatör kaynağı yardımıyla uyku modundan çıkartılması isteniyorsa bu bit ‘1’ yapılmalıdır. Böylece MCU’nun kendi osilatörüyle bir bağ kurulmamış olur.

0 = Harici saat darbesi girişi senkronize edilir.
TMR1CS = 0 olması durumunda bu bitin değeri dikkate alınmaz.

Bu bit ‘0’ yapıldığında harici saat darbesi girişi MCU dâhili saat darbesiyle senkronize edilir. Bu durumda zamanlayıcının TMR1 kaydedicisi MCU uyku modundayken artış göstermez.

bit 1 TMR1CS: Timer1 saat darbesi kaynağı seçim bitidir.
1 = RB6/T1OSO/T1CKI pini üzerinden harici saat darbesidir (yükselen kenar tetiklemeli).

Sayıcı (counter) modunda çalışma yapılacaksa bu bit ‘1’ yapılır. Eğer T1OSCEN biti ‘1’ ise bu durumda Timer1 kaydedicisinin değeri, RB7/T1OSI girişine bağlı harici osilatörün her yükselen saat darbesinde artar. T1OSCEN biti ‘0’ ise bu durumda Timer1 kaydedicisinin değeri, RB6/T1OSO/T1CKI pinine dışarıdan uygulanan bir osilatör frekasının yükselen saat darbelerine göre artar. Giriş sinyalinin yükselen kenarında sayma işleminin başlaması için, öncesinde en az bir düşen kenar değişiminin sağlanmış olması gerekir (Bkz. Şekil 5.3). Sayıcı modu örnek olarak, yüksek devirli motorların devrinin tespit eidlmesinde oldukça sağlıklı sonuç verir.

Şekil-5.3 Timer1'in sayıcı modunda sayma işleminin başlaması (harici kaynaklı ve dâhili işlemci frekanslı çalışma)

0 = Dâhili saat darbesidir (FOSC/4).
bit 0 TMR1ON: Timer1 etkinleştirme bitidir.
1 = Timer1 etkinleştirilir.
0 = Timer1 durdurulur.

Timer1 kaydedicisi ile süre hesabı şu şekilde gerçekleştirilir: Eğer MCU’nun kendi çalışma osilatörü kullanılıyorsa;

Denklem 5.1

eğer düşük frekanslı harici bir kristal osilatör ya da saat darbesi kaynağı kullanılıyorsa;

Denklem 5.2

şeklinde hesaplanır. Dikkat edileceği üzere ikincil düşük frekans osilatör girişi kullanıldığında frekans değeri 4’e bölünmemektedir. Bu durumda düşük frekans osilatör olarak 32,768 kHz kol saati kristali kullanıldığında, ön ölçekleme değeri 1:1 olarak ayarlandığında ve TMR1H = 0x80 (128), TMR1L = 0x00 olarak kurulduğunda;

olarak gerçek zaman gecikmesi elde edilir. 2’li ve 16’lı sayı sistemleri hakkında bilgi almak için Ek-A8’e bakınız.

Tablo 5.2 TMR1 kaydedicisine yüklenen değerin desimal karşılığı

Şekil 5.4’te TMR1 kaydedicisini ve TMR1 kesmesini kullanan bir alarm-ikaz devresi gösterilmiştir. Devre okullarda bulunan acil durum kapılarının amacı dışında kullanımını önlemeye yönelik olarak geliştirilmiş bir alarm devresidir. Mikrodenetleyici dâhili 4 MHz osilatörüyle çalıştırılmaktadır. Timer1 kesmesi kullanılarak, mikrodenetleyicinin harici zamanlayıcı girişine bağlanmış 32768 Hz’lik kristal yardımıyla gerçek zamanlı olarak çalışması sağlanmaktadır.

Gerçek zaman sayacı (Real Time Counter-RTC) özellikle hassas saat ve zamana dayalı uygulamalarda tercih edilen bir donanımdır. Pek çok MCU’nun sahip olduğu Timer1 ClockIn girişiyle bu tür uygulamalar yapılabilmektedir. Kol saatlerinin içinde de kullanılan 32,768 KHz’lik kristal yardımıyla bu işlem sağlanır.

Şekildeki devrede iki adet besleme kaynağı kullanılmıştır. MCU’nun stabil çalışması için 3V’luk bir lityum ion pil (CR2032 saat pil) ve alarm devresinin sürülmesi için de 9V’luk bir kaynak kullanılmıştır. Devre tamamen pille çalışmakta olup, MCU’nun kesme algılaması gerçekleşmediği sürede minimum enerji tüketimiyle çalışması için assembly koduyla uyku moduna sokulması sağlanmıştır.

MCU’nun program kodunun düşük voltajlarda da düzgün çalışmasını sağlamak için Voltaj düşmesi kesmesi (Brown-out Reset) devre dışı bırakılmıştır (Project-->Edit Project – Brown-out Detect Disabled).

Şekil-5.4 Alarm-ikaz devresi açık şeması

Düşük güç tüketimi sağlanması için MCU uyku modunda çalıştırılmaktadır. Bu işlem bir assembly komutu olan “sleep” komutuyla yapılır. MikroC’de assembly kodu yazmak için “asm{ }” komutu kullanılır. Reed röle’nin karşısına denk gelen mıknatıs alarm devresinden ayrıldığında (kapı açıldığında), harici kesme algılanmakta ve alarm devresi çalışmaktadır. Bu durumda MCU uyku modundan çıkar. Alarm devreye girdiğinde belli bir süre çalışır ve MCU tekrar uyku moduna girer. Alarmın ne kadar süre çalacağı 2’li dip anahtarı (DIP SWITCH) ile ayarlanmaktadır. 22 = 4 farklı zaman kurma değerimiz vardır. Harici kesme dışında Timer1 kesmesi ile de MCU uyku modundan uyandırılmakta ve mavi LED kısa süreli olarak yakılıp söndürülmektedir. Ardından MCU tekrar uyku moduna girer. Böylece alarm-ikaz devresinin çalıştığı fasılalı olarak dış ortama gösterilmiş olur.

Tablo 5.3 Timer1 kesmesini kullanan alarm-ikaz devresi mikroC kodu

unsigned short ikaz_biti=0;
unsigned short zaman=0;
unsigned short i, yukselen=0;
unsigned short ilk=0;
sbit BIR at RB4_bit;
sbit IKI at RB5_bit;
sbit SES at RB3_bit;
sbit KIRMIZI at RB2_bit;
sbit MAVI at RB1_bit;

void ayar(){
 TRISB = 0x31; // Harici kesme ve DIP switch bağlantıları giriş yapılıyor.
 PORTB = 0;
 TRISA = 0x00;
 PORTA = 0;
 INTCON.GIE=1;   //Evrensel kesme aktif
 INTCON.PEIE=1;  //Çevresel kesme aktif
 INTCON.INTE=1;  //Harici kesme aktif
 PIE1.TMR1IE=1; //Timer1 kesmesi aktif
 CMCON=0X07;  //Analog karşılaştırıcılar kapatıldı
 OPTION_REG = 0b01000111;   // Önölçekleyici WDT olarak 1:128
 TMR1H=0X00;  //Süre = Prescaler*(65535-0+1)*______1______ = 8*2 = 16sn
 TMR1L=0X00;  //                                32768 
 Delay_us(10); 
 T1CON.TMR1ON=0; // Timer1 önce kapalı
 T1CON=0X3F; //Ön ölçekleyici 1:8
 Sound_Init(&PORTB, 3);  //Buzzer'ın bağlı olduğu port
 MAVI=0;
 KIRMIZI=0;
 SES=0;
 ikaz_biti=0;
}

void Alarm() {
  Sound_Play( 1000, 50);
}

void bitti(){
 PORTB = 0X00;
 zaman=0;
 ikaz_biti=0;
}

void bir_dakika(){
  if(zaman<4){
   Alarm();
   KIRMIZI=~KIRMIZI;
  }
  if(zaman>=4){
    bitti();
  }
}
void iki_dakika(){
  if(zaman<8){
   Alarm();
   KIRMIZI=~KIRMIZI;
  }
  if(zaman>=8){
    bitti();
  }
}
void uc_dakika(){
  if(zaman<12){
   Alarm();
   KIRMIZI=~KIRMIZI;
  }
  if(zaman>=12){
    bitti();
  }
}
void bes_dakika(){
  if(zaman<20){
   Alarm();
   KIRMIZI=~KIRMIZI;
  }
  if(zaman>=20){
    bitti();
  }
}

void main() {
 ayar();
 while(1){
  if(!ikaz_biti){
   SES=0;
   KIRMIZI=0;
   if(zaman>=1){
    zaman=0;
    for(i=0;i<5;i++){
     MAVI=~MAVI;
     delay_ms(50);
    }
    delay_ms(10);
    MAVI=0;
   }
    Delay_us(20);
    asm{
     sleep
    }
  }
  if(ikaz_biti){
    if(!BIR && !IKI){//Her iki anahtar da 0 konumunda. Süre yaklaşık 1dk.
     bir_dakika();
    }
    if(!BIR && IKI){//Anahtarlar 0-1 konumunda. Süre yaklaşık 2dk.
     iki_dakika();
    }
    if(BIR && !IKI){//Anahtarlar 1-0 konumunda. Süre yaklaşık 3dk.
     uc_dakika();
    }
    if(BIR && IKI){//Her IKI anahtar da 1 konumunda. Süre yaklaşık 5dk.
     bes_dakika();
    }
   }
 }
}
void interrupt(){
 if(INTCON.INTF){
   zaman=0;
   ikaz_biti=1;
   INTCON.INTF=0;
 }
 if(PIR1.TMR1IF){
   zaman++;
   asm{
    BTFSC TMR1L, 0 //TMR1L 0 olana kadar döner
    GOTO $-1
   }   
   T1CON.TMR1CS = 0; //Timer1 için dahili osilatör seçiliyor   
   TMR1H=0X00; //Timer1 yüksek baytı yükleniyor   
   T1CON.TMR1ON=0; //Timer1 kapatılıyor
   T1CON=0x3F; //Süre = Prescaler*(65536-0)*______1______ = 8*2 = 16sn
               //                               32768
   PIR1.TMR1IF=0;
 }
}

Program kodu incelendiğinde TMR1 kaydedicisinin 0 olarak yüklendiği görülür. Ön ölçekleme değeri 8 olarak ayarlandığından TMR1IF bayrağının ‘1’ olması için geçecek minimum süre 16 sn olarak ayarlanmış olur. Bu durumda MCU uyku modundan çıkar ve Mavi LED ile fasılalı olarak sinyal verilir. Harici kesme girişinden tetikleme gerçekleştiğinde MCU tekrar uyku modundan çıkar ve ‘ikaz_biti’ değişkeni Lojik-1 yapılır ve ikili dip anahtarının konumuna göre ilgili alarm prosedürü çağrılır. Bu süre zarfında TMR1IF kesmesi her gerçekleştiğinde ‘zaman’ isimli değişken birer artırılır. İstenilen frekansta ve fasıla süresinde sesli ikaz verdirmek için mikroC programının “Sound” kütüphanesi kullanılır. “Sound_Init(&PORTB, 3)” komutuyla B portunun 3 numaralı pini ses çıkışı olarak kullanılır. “Sound_Play(1000, 50)” komutuyla da 1 kHz’lik ve 50 ms fasılalı sinyal üretilir. Şekil 5.5’te PROTEUS ARES yazılımında tasarlanmış baskı devre şeması ve malzeme yerleşim görüntüsü gösterilmiştir.

Şekil-5.5 Alarm-ikaz devresinin malzeme yerleşim ve PCB yol görüntüsü

ÖNEMLİ: Kitap içinde anlatılan PIC12F675, PIC16F628A ve PIC18F2550/4550 mikrodenetleyicilerinin Timer1 modülü ile ilgili düzeltmenin yayınlandığı bir Errata dökümanı bulunur (DS80329B). Üretici firma tarafından bu tür düzeltmeler ayrıca ilgili mikrodenetleyicinin veri kılavuzunda ayrı bir “Silicon Errata” başlığı altında yayınlanır.

Timer1 başlatıldığında ya da güncellendiğinde, zamanlayıcının harici saat darbesi kaynağından, bir yükselen kenarın sayıcının değerini artırmasından önce bir düşen kenar görmesi gerektiği söylenmişti. Eğer harici saat darbesi kaynağı hâla yüksek seviyedeyken TMR1H ve TMR1L kaydedicilerine yazma işlemi tamamlanmamışsa, Timer1 güncellemeden sonraki ilk darbeyi saymayı kaçırır. Harici bir krital kullanılırken, yükselen kenardan düşen kenara kadar geçen darbe genişliği sıcaklığa bağlı olarak değişebiliir. Sonuç olarak, zamanlayıcı taşma için ek bir süre gerektirebilir.

Tablo 5.3’teki kod örneğinin kesme yordamı altında assembly komutuyla, Timer1 alçak baytının 0 olana kadar döndürülmesi gösterilmiştir. Ardından Timer1 modülü kapatılıp tekrar açılarak güncellenmiştir. Böylece Timer1 modülünün doğru zamanlamayla sayabilmesi garanti edilmiştir.

Tablo 5.4’te Errata verikılavuzu doğrultusunda yapılan düzeltmeyle birlikte Timer1 RTC kristal osilatörünün kullanılmasıyla 1 sn’nin elde edilmesi ve saat uygulamasının gerçekleştirilmesi PIC18F2550 üzerinden gösterilmiştir.

Tablo 5.4 Errata kılavuzu kapsamında yapılan düzeltme

char kesmeTMR1;
unsigned int saniye, dakika, saat;
void ayarlar(){
  CMCON=0X07; // Analog karşılaştırıcılar kapalı
  ADCON0=0; // A/D modülü kapalı
  ADCON1=0X0F; // Tüm AN kanalları dijital I/O olarak ayarlı
  OSCCON = 0X72;
  TRISA=0;
  TRISB=0;
  TRISC=0;
  PORTA=0;
  PORTB=0;
  PORTC=0;
  TMR1H=0X80; // TMR1 kaydedicisi 32768 ile yükleniyor
  TMR1L=0X00;
  INTCON.GIE=1; // Evrensel kesme aktif
  INTCON.PEIE=1; // Çevresel aygıt kesmesi aktif
  PIE1.TMR1IE=1; // Timer1 kesmesi aktif
 T1CON=0X0F; // Prescaler 1:1 Timer1 hariciosilatör kaynağından
 // açılıyor
}
void main() {
  ayarlar();
  while(1){
  if(!kesmeTMR1){
   asm{
    sleep
    }
  }
  if(kesmeTMR1){
   if(saniye>59){
    dakika++;
    saniye=0;
     if(dakika>59){
      saat++;
      dakika=0;
      if(saat>24) saat=0;
     }
   }
   kesmeTMR1=0;
  }
 }
}
void Kesme_yordami() iv 0x000008{
  if(PIR1.TMR1IF){ //Timer1 kesmesi mi?
   kesmeTMR1=1;
   saniye++;
   asm{
    BTFSC TMR1L, 0 //TMR1L'nin 0 olduğu garanti
    BRA $-2 //edilene kadar dönüyor
   }
  TMR1H=0x80;
  PIR1.TMR1IF=0;
 }
}


Timer2 Modülü ve Timer2 Kesmesi

Timer2 modülü de diğer zamanlayıcılar gibi zamanlayıcı/sayıcı olarak çalışan bir modüldür. 8-bit uzunluğunda TMR2 ve PR2 adında iki kaydedicisi vardır. Diğer zamanlayıcı/sayıcı modüllerinden farklı olarak önölçekleyici yanında son ölçekleyicisi (postscaler) vardır. Timer2 modülünün sahip olduğu özellikler şu şekilde maddelenebilir:

  • 2 adet 8-bit kaydedicisi vardır (TMR2 ve PR2).
  • Okunabilir ve yazılabilirdir.
  • Bir ön önölçekleyici ve bir son ölçekleyiciye sahiptir.
  • CPU çalışma frekansına, bir diğer ifadeyle MCU’nun osilatörüne bağlı olarak çalışır.
  • Taşma durumu kesmesi vardır.

İlk ve son ölçekleyicileri en yüksek değerlerine ayarlandığında, taşma süresi 16-bit bir zamanlayıcının ki gibi olur. TMR2 ve PR2 kaydedicilerinin her ikisi de program içinde yazılabilir ve okunabilir kaydedicilerdir. TMR2 kaydedicisi cihaz resetlendiğinde (WDT, POR, (MCLR) ̅ ya da BOR reseti durumunda) 0x00 değeriyle, PR2 kaydedicisi ise 0xFF değeriyle yüklenir. TMR2 kaydedicisi “ilk sayma değerini” (saymaya başlanan ilk değer) tutan, PR2 kaydedicisi ise “son sayma değerini” (ulaşmak istediğimiz en yüksek değer) tutan kaydedicidir.

TMR2 kaydedicisinin içeriği Timer2 kaydedicisinin çalışmasıyla birlikte, mikrodenetleyicinin çalışma frekansının her yükselen kenarında artmaya başlar. Her artışta PR2 kaydedicisinin içeriğiyle karşılaştırılır. İki değer eşleştiğinde, karşılaştırıcı bir eşleşme sinyali üretir. Bir sonraki çevrimde TMR2 kaydedicisinin içeriği 0x00 değerine resetlenir. Karşılaştırıcının çıkışından elde edilen eşleşme sinyali son ölçekleyicinin girişi olur. Son ölçekleyici ile Timer2 kesmesini tetikleyecek eşleşme sinyali geciktirilir, böylece MCU’nun üzerindeki kesme yükü hafifletilmiş olur. Timer2 modülünün çalışma ilkesi kısaca Şekil 5.6’da gösterilmiştir.

Şekil-5.6 Timer2 modülünün çalışma ilkesi

Timer2 modülünün bir diğer özelliği, diğer çevresel aygıtlarla MCU’nun iletişim kurmasında kullanılan SSP (Synchronous Serial Port) modülü için gerekli baud hızını sağlamasıdır. Bu işlem karşılaştırıcının ürettiği sinyal ile sağlanır. Böylece MSSP’nin SPI modunda çalışması Timer2 modülü sayesinde gerçekleşir. Timer2 modülünün en önemli özelliklerinden birisi de CCP (Capture/Compare/PWM) modülünün PWM modunda çalışması durumunda gerekli olan PWM zamanını sağlamasıdır. Dolayısıyla, MSSP ve CCP modüllerine sahip tüm PIC mikrodenetleyicileri Timer2 modülüne de sahiptir.

T2CON: TIMER2 KONTROL KAYDEDİCİSİ (ADRES: 12h – PIC16F628A)

bit 7 Kullanılmıyor: ‘0’ olarak okunur.
bit 6-3 TOUTPS3:TOUTPS0: Timer2 çıkış son ölçekleyici tercih bitleridir.
0000 = 1:1 Son ölçekleme oranıdır. Timer2 kesmesi aynı periyotta aktif olur.
0001 = 1:2 Son ölçekleme oranıdır. Timer2 kesmesi 2 katı geciktirilir.
.
.(NOT: Ara değerleri 4-bit lojik sayı sistemine göre ilerlemektedir.)

1111 = 1:16 Son ölçekleme oranıdır. Timer2 kesmesi 16 katı geciktirilir.
bit 2 TMR2ON: Timer2’yi etkinleştirme bitidir.
1 = Timer2 etkinleştirilir.
0 = Timer2 kapatılır.
Tüm zamanlayıcılarda olduğu gibi Timer2 modülü de kapatılabilir. Böylece modülün güç tüketimi azaltılmış olur.
bit 1-0 T2CKPS1:T2CKPS0: Timer2 için saat darbesi ön ölçekleme tercih bitleridir.
00 = Ön ölçekleme 1:1
01 = Ön ölçekleme 1:4
1X = Ön ölçekleme 1:16

Timer2 modülünün Prescaler ve Postscaler sayıcıları aşağıdaki durumlar gerçekleştiğinde sıfırlanır. Bir diğer ifadeyle sistem içinde bir değişiklik meydana geldiğinde sayma işlemi kaldığı yerden devam etmez ve başa döner.

  • TMR2 kaydedicisine yazma işlemi yapıldığında
  • T2CON kaydedicisine yazma işlemi yapıldığında
  • Power-on Reset (POR) durumunda
  • Brown-out Reset (BOR) durumunda
  • (MCLR resetinde
  • Watchdog Timer (WDT) resetinde
  • Parite taşması resetinde

Uyku modundayken TMR2 artmaz. Önölçekleyici en sonki ön ölçekleme sayma değerini tutar. MCU uyku modundan çıkınca kaldığı yerden artmaya devam eder.

Timer2 modülünü kullanarak periyot hesabını aşağıdaki gibi yapabiliriz:

Denklem 5.3

Burada “Sayac” isimli değişken program içinde isteğe bağlı olarak kullanabileceğimiz bir geciktirme döngü değişkenidir. Örnek olarak Timer2 kesmesinin 1sn’lik periyotlarla aktif olmasını istiyorsak hesabımızı şu şekilde yapabiliriz:

İlk önce MCU’nun osilatör frekansının 4 MHz olduğunu varsayalım. Ardından prescaler ve postscaler her ikisi de 1:16 değerlerine kurulu olsun. TMR2 ve PR2 kaydedicilerinin değerleri sırasıyla 0x00 ve 0xFF olsun. Bu durumda;

“Sayac” değişkenini çekersek,

Bu değerlere göre programlanarak çıkışta 1sn süreyle artan ya da azalan tek basamaklı 7 segment gösterge devresi Şekil 5.7’de gösterilmiştir. Devrede tek basamaklı sayma değerini durdurma; ileri ve geri saydırma butonları bulunmaktadır.

Şekil-5.7 Timer2 modülüyle çalışan tek basamaklı 7 segment gösterge devresi

Şekilde görülen devrede 3 adet buton için B portunun port değişim kesmesine sahip olan son dört pini kullanılmıştır. Bu nedenle 7 segment gösterge A portuna çıkış bileşeni olarak bağlanmıştır. A portunun reset haricinde geriye kalan 7 pinini aktif olarak kullanabilmek için PIC16F628A’nın dâhili 4 MHz osilatörü aktif kılınmıştır ve konfigürasyon sözcüğü RA6 ve RA7 pinleri I/O olacak şekilde ayarlanmıştır (Bkz.Ek-D3). Burada dikkat edileceği üzere açık akar (Open Drain-OD) yapısında olan RA4 pinini çıkış olarak kullanabilmek için NPN ve PNP transistör ikilisiyle push-pull bir bağlantı yapılmıştır.

Devrenin mikroC kodu Tablo 5.5’te gösterildiği gibidir.

Tablo 5.5 Timer2 modülüyle çalışan tek basamaklı 7 segment gösterge devresi mikroC kodu

#define ILERI PORTB.RB5
#define GERI PORTB.RB6
#define DURDUR PORTB.RB7
unsigned char sayac=0, dur=0, artir=1, azalt=0;
int digit=0;
unsigned int display[10]={95,6,155,143,198,205,221,7,223,207};
   /*display göstergeleri burada tanımlandı*/
void main() {
 TRISB=0xF0; /*7 segment göstergenin bağlı olduğu pinler çıkış yapılıyor */
 PORTB=0;
 TRISA=0X00;
 PORTA=0;
 CMCON =0x07;/* Karşılaştırıcı kapatıldı. Pinler dijitale ayarlandı. */
 OPTION_REG = 0B00000111;//Dâhili pull-up'lar aktif
 T2CON = 0B01111011;  //Prescaler ve postscaler 1:16
 TMR2 = 0;
 PR2 = 0XFF;
 INTCON.RBIE = 1;
 INTCON.GIE = 1;
 INTCON.PEIE = 1;
 PIE1.TMR2IE = 1;  //Timer2 kesmesi aktif
 T2CON.TMR2ON = 1; //Timer2 sayacı başlatılıyor
 while(1){ /* Sonsuz döngü */
  if(dur){
   PORTA=display[digit];/*dijiti display içine yazdık */
   if(digit >= 10)digit = 0; /*dijit değeri kontrol ediliyor */
   if(digit < 0) digit = 9;
  }
 }
}
void interrupt(){
 if(INTCON.RBIF){ //B portu değişim kesmesi
  if(!DURDUR){
   dur = ~dur;
  }
  if(!ILERI){
    artir = 1;
    azalt = 0;
  }
  if(!GERI){
    artir = 0;
    azalt = 1;
  }
  INTCON.RBIF=0;
 }
 if(PIR1.TMR2IF){ //Timer2 kesmesi
  if(dur){
   sayac++;
   if(sayac>15){
    if(artir) digit++;
    if(azalt) digit--;
    sayac=0;
   }
  }
  PIR1.TMR2IF = 0;
 }
}


Timer3 Modülü ve Timer3 Kesmesi

Kitapta açıklanan mikrodenetleyiciler içinde yalnızca PIC18F2455/25550/4455/4550 serisinde Timer3 modülü bulunmaktadır. Bu nedenle Timer3 modülü PIC18F2550 için açıklanacaktır. Timer3 modülü:

  • Yazdığınız program içinden 16-bit zamanlayıcı ya da sayıcı olarak seçilebilen çalışma özelliğine sahiptir.
  • Okunabilir ve yazılabilir 8-bitlik kaydedicilere (TMR3H ve TMR3L) sahiptir.
  • Dâhili ya da harici seçilebilir saat darbesi kaynağı özelliğine sahiptir. Osilatör seçimi MCU’nun kendi osilatörü ya da Timer1 osilatörü arasında olabilmektedir.
  • CCP (Capture/Compare/PWM-Bkz.8.1) özel olay tetiklemesiyle resetlenme özelliğine sahiptir.

T3CON: TIMER3 KONTROL KAYDEDİCİSİ (ADRES: FB1h – PIC18F2550)

bit 7 RD16: 16-bir Okuma/Yazma etkinleştirme bitidir.
1 = Timer3’ün tek bir 16-bitlik işlemle okuma/yazma yapmasını etkinleştirir. Kısaca 16-bit modudur.
0 = Timer3’ün iki 8-bitlik işlemle okuma/yazma yapmasını etkinleştirir. Kısaca 8-bit modudur.
bit 6,3 T3CCP2:T3CCP1: Timer2 çıkış son ölçekleyici tercih bitleridir.
1x = Timer3 modülü her iki CCP modülü için de capture/compare saat kaynağıdır.
01 = Timer3 modülü CCP2 modülü için capture/compare saat kaynağıdır.
Timer1 modülü CCP1 modülü için capture/compare saat kaynağıdır.
00 = Timer1 modülü her iki CCP modülü için de capture/compare saat kaynağıdır.
bit 5-4 T3CKPS1:T3CKPS0: Timer3 giriş saat kaynağı için ön ölçeklme bitleridir.
11 = Ön ölçekleme 1:8
10 = Ön ölçekleme 1:4
01 = Ön ölçekleme 1:2
00 = Ön ölçekleme 1:1
Tüm zamanlayıcılarda olduğu gibi Timer3 modülü de kapatılabilir. Böylece modülün güç tüketimi azaltılmış olur.
bit 2 (T3SYNC:): Timer3 harici saat kaynağı giriş senkronizasyon kontrol bitidir (Saat kaynağının Timer1/Timer3’den gelmesi durumunda kullanılır değildir).
TMR3CS = 1 ise:
1 = Harici saat kaynağı MCU osilatörüyle senkronize edilmez.
0 = Harici saat kaynağı MCU osilatörüyle senkronize edilir.
TMR3CS = 0 ise:
Bu bit önemsenmez. Timer3 dâhili saati kullanır.
bit 1 TMR3CS: Timer3 saat kaynağı seçim bitidir.
1 = Timer1 osilatöründen ya da T1CKI girişinden (ilk düşen kenardan sonraki yükselen kenarda) harici saat kaynağı seçimidir.
0 = Dâhili saat kaynağıdır (FOSC/4).
bit 0 TMR3ON: Timer3 aktifleştirme bitidir.
1 = Timer3 etkinleştirilir.
0 = Timer3 kapatılır.

Timer3 için saat kaynağı olarak işlemcinin çekirdek frekansının seçilmesi durumunda süre hesabı Denklem 5.4’te olduğu gibi yapılır.

Denklem 5.4

Şekil-5.8 Timer3 modülü basitleştirilmiş diyagramı

Timer3 modülü, diğer zamanlayıcı modülleri gibi kullanıcıya ek bir bağımsız zamanlama donanımı kazandırmış olur. Çalışma ilkesi görüldüğü üzere Timer1 modülüne benzemektedir. İsteğe bağlı olarak mikrodenetleyicinin çekirdek frekansını saat kaynağı olarak kullanabildiği gibi, Timer1 modülünün harici osilatör (T1OSC) ya da saat darbesi girişini (T1CKI) de kullanabilir.

Timer3 modülünün PIC18F2550 mikrodenetleyicisi ile kullanımını daha iyi anlamak için örnek bir zamanlayıcı uygulaması geliştirilmiştir. Şekil 5.9’da gösterilen uygulamada, mikrodenetleyicinin 3 farklı harici kesme girişinden gelen tetiklemeye göre 3 farklı bekleme süresince bir LED’i yakacak devre şeması gösterilmiştir. Devrenin uygulama kodu Tablo 5.6’da verilmiştir. Harici kesme girişlerine bağlı butonlardan hangisi aktif olursa ‘buton’ isimli değişkenin değeri değiştirilmektedir. Değişkenin aldığı değere göre ilgili bekleme rutini çağrılmaktadır. Uygulamada 100ms, 250ms ve 500 msn’lik beklemeleri elde edecek şekilde 3 farklı rutin hazırlanmıştır. Timer3 modülünün zaman sayacı kaydedicileri olan TMR3H ve TMR3L kaydedicilerine yüklenen değere göre bu süreler hesaplanmaktadır. Bu kaydedicilerin toplam değeri 65535 sayısını aştığında taşma meydana gelir ve TMR3IF kesme bayrağı lojik-1 olur.

Şekil-5.9 Timer3 modülüyle bekleme süresi uygulama devresi

Tablo 5.6 Timer3 modülüyle bekleme süresi uygulama devresi mikroC kodu

#define LED PORTA.RA0
char buton=0;
void delay100(){
 TMR3H=0XCF;
 TMR3L=0X2C;
 T3CON.TMR3ON=1;
 while(PIR2.TMR3IF==0); //Timer3 taşması oluşana kadar döner
 T3CON.TMR3ON=0;
 PIR2.TMR3IF=0;
}
void delay250(){
 TMR3H=0X85;
 TMR3L=0XEE;
 T3CON.TMR3ON=1;
 while(PIR2.TMR3IF==0); //Timer3 taşması oluşana kadar döner
 T3CON.TMR3ON=0;
 PIR2.TMR3IF=0;
}
void delay500(){
 TMR3H=0X0B;
 TMR3L=0XDC;
 T3CON.TMR3ON=1;
 while(PIR2.TMR3IF==0); //Timer3 taşması oluşana kadar döner
 T3CON.TMR3ON=0;
 PIR2.TMR3IF=0;
}
void ayarlar(){
 PORTB=0;
 CMCON=0X07; //Analog karşılaştırıcılar kapalı
 ADCON0=0; //A/D modülü kapalı
 ADCON1=0X0F; //Tüm AN kanalları dijital I/O olarak ayarlı
 TRISB=0B00000111; //3 harici kesme pini de giriş
 TRISA=0;
 PORTA=0;
 TRISC=0;
 PORTC=0;
 INTCON.GIE=1; //Evrensel kesme aktif
 INTCON.INT0E=1; //1.harici kesme aktif
 INTCON2.RBPU=1; //Dâhili pull-up'lar kapalı
 INTCON3.INT1E=1; //2. harici kesme aktif
 INTCON3.INT2E=1; //3. harici kesme aktif
 OSCCON=0X62; // 8MHz/2=4MHz dâhili osilatör
}
void timer3_ayar(){
 T3CON.T3CKPS1=1;
 T3CON.T3CKPS0=1; //1:8 prescaler
 T3CON.TMR3CS=0; // FOSC/4 işlemci saat kaynağı
 T3CON.TMR3ON=0; //Timer3 kapalı
}
void main() {
 ayarlar();
 timer3_ayar();
 while(1){
  switch(buton){
   case 1:
    LED=1;
    delay100(); //kullanıcı tanımlı bekleme süresi
    buton=0;
    break;
   case 2:
    LED=1;
    delay250();//kullanıcı tanımlı bekleme süresi
    buton=0;
   break;
   case 3:
    LED=1;
    delay500();//kullanıcı tanımlı bekleme süresi
    buton=0;
   break;
   default: LED=0;
  }
 }
}
void interrupt(){
 if(INT0F_bit){ //0 nolu harici kesme bayrağı
  buton=1;
  INT0F_bit=0;
 }
 if(INT1F_bit){ //1 nolu harici kesme bayrağı
  buton=2;
  INT1F_bit=0;
 }
 if(INT2F_bit){ //2 nolu harici kesme bayrağı
  buton=3;
  INT2F_bit=0;
 }
}

Program incelendiğinde kullanıcı tanımlı 3 farklı bekleme rutini tasarlanmış olduğu görülmektedir. PIC18F2550’nin dâhili osilatörü (CONFIG1H-300001h:0X0008 değeri) ve OSCCON kaydedicisi kullanılarak (ayrıntılı bilgi için Ek-F’ye bakınız) 4 MHz’lik FOSC değeri elde edilmiştir. Bu frekans değeri referans alınarak 100 ms, 250 ms ve 500 ms için TMR3L ve TMR3H kaydedicilerine yüklenmesi gereken değerler hesaplanmıştır. Bu işlemi 100 ms için yapacak olursak;

Program kodunda görüleceği üzere T3CON kaydedicisinin T3CKPS1 ve T3CKPS0 bitleri lojik-1 olarak ayarlandığından 1:8’lik önölçekleme değeri elde edilmiştir. Denklem 5.4’te görüldüğü üzere FOSC değerinin 4’te 1’inin alındığı dolayısıyla paydada 1.000.000 değerinin kaldığı görülür. Bu durumda pay sayısının 100 bin olması gerektiği ortaya çıkar (100.000/1.000.000 = 100m = 0,1).

100.000 / 8(prescaler) = 12.500

Bu değer 65536 sayısından TMR3 kaydedicisinin farkı alındığında çıkan sayıdır. Bu durumda TMR3 değerini bulmak için;

TMR3=65536-12500=53036=CF2C

Aritmetik işlemini gerçekleştiririz. Bu durumda, 4 MHz’lik çalışma frekansı altında 100 msn’lik bekleme süresinin elde edilmesi için; TMR3H kaydedicisinin ‘CF’, TMR3L kaydedicisinin ise ‘2C’ onaltılı değeriyle yüklenmesi gerektiği ortaya çıkar. Timer3 modülü ile ilişkili kaydediciler Tablo 5.7’de listelenmiştir.

Tablo 5.7 Timer3 kaydedicisi ile ilişkili kaydediciler
KaydediciBit 7Bit 6Bit 5Bit 4Bit 3Bit 2Bit 1Bit 0
INTCONGIE/GIEHPEIE/GIELTMR0IEINT0IERBIETMR0IFINT0IFRBIF
PIR2OSCFIFCMIFUSBIFEEIFBCLIFHLVDIFTMR3IFCCP2IF
PIE2OSCFIECMIEUSBIEEEIEBCLIEHLVDIETMR3IECCP2IE
IPR2OSCFIPCMIPUSBIPEEIPBCLIPHLVDIPTMR3IPCCP2IP
TMR3LTimer3 kaydedicisi düşük bayt
TMR3HTimer3 kaydedicisi yüksek bayt
T1CONRD16T1RUNT1CKPS1T1CKPS0T1OSCENT1SYNCTMR1CSTMR1ON
T3CONRD16T3CCP2T3CKPS1T3CKPS0T3CCP1T3SYNCTMR3CSTMR3ON

Uygulama incelendiğinde Timer3 INTCON kaydedicisi ile çevresel aygıt kesmesinin ve PIE2 kaydedicisi ile Timer3 kesmesinin aktif edilmesine gerek kalmadığı görülmektedir. Normal çalışma durumunda Timer3 kesmesinin aktif kılınmasına gerek yoktur. Varsayılan kaydedici ayarlarıyla Timer3 taşma kesmesi oluşmakta ve program içinde kesme bayrağı kaydedicisi PIR2 ile kontrol işlemi yapılmaktadır. Ancak mikrodenetleyicinin uyku modunda çalışması istendiğinde kesme etkinleştirmesinin yapılması gerekir. Ayrıca her bir kesme için öncelik (priority) tanımlaması yapan kaydedicilerden olan IPR2 kaydedicisiyle de öncelik tanımlamasına gerek duyulmamıştır. 16X serisi mikrodenetleyicilerde bulunmayan öncelik tanımlamasıyla ilgili daha ayrıntılı bilgi bir sonraki başlıkta sunulmuştur.

PIC18F serisi mikrodenetleyicilerde iki tane kesme vektörü bulunmaktadır ve bu sayede kesme yordamını mikroC program editöründe farklı isimlerle adlandırmak mümkündür. Bir sonraki uygulamada bu gösterimin de kullanıldığı bir örnek sunulmuştur.

Şekil 5.10’da saat kaynağı olarak Timer1 harici saat darbesi girişini (RC0/T1OSO/T1CKI) kullanan ve uyku modunda çalışan bir devre uygulaması gösterilmiştir. Bir üretim bandında geçen ürünleri algılamak üzere kızılötesi (infrared) tx/rx çiftinden oluşan bir algılayıcı kullanıldığı düşünülsün. Sensörün mikrodenetleyicinin T1CKI girişine bağlandığını düşünelim. Timer3 modülünün TMR3 kaydedicisi T1CKI girişiyle ilişkilendirilmiş olsun ve oradan gelen algılayıcı bilgisine bağlı olarak değeri artsın. TMR3 kaydedicisinde taşma meydana geldiğinde Timer3 kesmesi ile mikrodenetleyici uyku modundan çıksın ve tanımlanmış bir pinden ikaz versin.

Şekil-5.10 Kızılötesi algılayıcı ile sayma işlemi yapan Timer1 ve Timer3 kesme uygulaması

Piyasada farklı tipte IR algılayıcılar bulunur. Uygulamada verici ve alıcısı aynı devre sistemi üzerinde bulunan bir IR sensörü kullanılmıştır. Sensörlerin algılama yaptığı durumda çıkışta lojik-0 ya da lojik 1 değerinden hangisini verdiği de önemlidir. Örneğin MZ-80 IR nesne algılayıcısı boştayken lojik-1 verirken, algılama yaptığında lojik-0 değerini verir. PROTEUS-ISIS® uygulamasında harici olarak “Infrared Sensor” kütüphanesi kullanılmıştır. Bu kütüphanede kullanılan algılayıcı algılama yaptığında lojik-1 değerini vermektedir. Ayrıca bu tür tx/rx çiftinden oluşan IR sensörlerinin pek çoğu içinde bulunan TTL dönüştürücüleri sayesinde doğrudan MCU’nun dijital I/O pinine bağlanabilir.

Proteus® İçin Infrared Modülü Kütüphane Dosyalarının Yüklenmesi (Windows 10 İşletim Sistemi için)

  • Kitap ile birlikte verilen ya da internetten temin edilen InfraredSensorsTEP.LIB ve InfraredSensorsTEP.HEX dosyaları C:\ProgramData\Labcenter Electronics\Proteus 8 Professional\LIBRARY klasörüne kopyalanır.
  • InfraredSensorsTEP.IDX dosyası C:\ProgramData\Labcenter Electronics\Proteus 8 Professional\MODELS klasörüne kopyalanır.
Tablo 5.8 Kızılötesi algılayıcı ile sayma işlemi yapan Timer1 ve Timer3 kesme uygulaması mikroC kodu

#define LED_TMR1 PORTA.RA0
#define LED_TMR3 PORTA.RA1
#define T1CKI PORTC.RC0
char kesmeTMR1=0, kesmeTMR3=0;
unsigned int zaman1, zaman2;
void ayarlar(){
 PORTB=0;
 CMCON=0X07; // Analog karşılaştırıcılar kapalı
 ADCON0=0; // A/D modülü kapalı
 ADCON1=0X0F; // Tüm AN kanalları dijital I/O olarak ayarlı
 TRISB=0;
 TRISA=0;
 PORTA=0;
 TRISC=0x01;
 PORTC=0;
 INTCON.GIE=1; // Evrensel kesme aktif
 INTCON.PEIE=1; // Çevresel aygıt kesmesi aktif
 INTCON.T0IE = 1; // Timer0 kesmesi aktif
 T0CON=0B00000110; //Timer0 prescaler 1:128
 T0CON.TMR0ON=1;
 TMR0L=0xF7;
 TMR0H=0xC2; //49911 değeri yükleniyor
 PIE1.TMR1IE=1; // Timer1 kesmesi aktif
 PIE2.TMR3IE=1; // Timer3 kesmesi aktif
 OSCCON=0X72; // 8MHz dâhili osilatör
}
void timer1_ayar(){
 T1CON.T1CKPS1=1;
 T1CON.T1CKPS0=1; // Timer1 prescaler 1:8
 T1CON.T1OSCEN=0;
 T1CON.TMR1CS=1;
 T1CON.T1SYNC=1;
 TMR1H=0XFF;
 TMR1L=0XFE; // 65534 değeri başlangıç olarak yükleniyor
 Delay_ms(50);
 T1CON.TMR1ON=1;
}
void timer3_ayar(){
 T3CON.T3CKPS1=0;
 T3CON.T3CKPS0=0; // Timer3 prescaler 1:1
 T3CON.TMR3CS=1; // T1CKI girişi saat darbesi kaynağı
 T3CON.T3SYNC=1;
 TMR3H=0XFF;
 TMR3L=0XFE; // 65534 değeri başlangıç olarak yükleniyor
 Delay_ms(50);
 T3CON.TMR3ON=1;
}
void main() {
 ayarlar();
 timer1_ayar();
 timer3_ayar();
 while(1){
  if(!kesmeTMR1 && !kesmeTMR3){
   asm{
   sleep
   }
  }
  if(kesmeTMR1){
   if(zaman1>2){
    LED_TMR1=0;
    kesmeTMR1=0;
    zaman1=0;
   }
  }
  if(kesmeTMR3){
   if(zaman2>2){
    LED_TMR3=0;
    kesmeTMR3=0;
    zaman2=0;
   }
  }
 }
}
void Kesme_yordami() iv 0x000008{ //Kesme yordami isimlendirildi
 if(PIR1.TMR1IF){ //Timer1 kesmesi mi?
  LED_TMR1=1;
  kesmeTMR1=1;
  T1CON.TMR1ON=0;
  Delay_us(30);
  TMR1H=0XFF;
  TMR1L=0XFE;
  T1CON.TMR1ON=1;
  PIR1.TMR1IF=0;
 }
 if(PIR2.TMR3IF){ //Timer3 kesmesi mi?
  LED_TMR3=1;
  kesmeTMR3=1;
  T3CON.TMR3ON=0;
  Delay_us(30);
  TMR3H=0XFF;
  TMR3L=0XFE;
  T3CON.TMR3ON=1;
  PIR2.TMR3IF=0;
 }
 if(INTCON.T0IF){ //Timer0 kesmesi mi?
  if(LED_TMR1){
   zaman1++;
  }
  if(LED_TMR3){
   zaman2++;
  }
  INTCON.T0IF=0; //TMR0 bayrağı siliniyor ki tekrar kesme gerçekleşebilsin
  TMR0L=0xF7;
  TMR0H=0xC2; //49911 değeri yükleniyor
 }
}


Uygulamada hem Timer1 hem de Timer3 kesmesi bağımsız olarak birlikte kullanılmıştır. Sayma işleminin çabuk bitmesi istendiğinden her iki kaydedicinin zaman sayacı başlangıç değerleri FFFE-65534 olarak yüklenmiştir. Aynı saat darbesi kaynağını kullanarak farklı zamanlamada kesme üretimini göstermek amacıyla Timer1 ve Timer3 zamanlayıcılarının ön ölçekleme değerleri farklı programlanmıştır. Arzu edilen değer kadar sayma işlemi gerçekleştiğinde ve kesme üretildiğinde her bir zamanlayıcı için ayrı bir çıkış hattından sinyal alınmakta ve Timer0 kaydedicisiyle ayarlanmış süre kadar (8 MHz dâhili OSC için 2 sn) ilgili çıkış aktif olmaktadır. Kısaca uygulamada Timer0, Timer1 ve Timer3 zamanlayıcıları birlikte kullanılmıştır.

ÖNEMLİ: PROTEUS-ISIS® programında gelişmiş güç yönetimine ve osilatör seçeneklerine sahip mikrodenetleyicilerin bu özellikleri canlandırılamaz. PIC18F2550 mikrodenetleyicisi uyku modunda (SLEEP mode) ve çalışmayan modunda (IDLE mode) gibi çeşitli güç tasarrufu modlarına sahiptir. Ek F’de anlatıldığı üzere OSCCON kaydedicisi güç yönetimi ve osilatör tercihleri için kullanılan kaydedicilerdendir. OSCCON kaydedicisinin tüm özellikleri devre simülasyon programında canlandırılamamaktadır. Bu nedenle uyku modunda yapacağınız çalışmalarınızı izlemek ve sonuçlarını görmek için uygulamanızı gerçek devre üzerinde kurmanız önemle rica olunur.

Şekil 5.10’daki uygulama 8 MHz dâhili çalışma frekansında hem uyku modu hem de normal modda gerçekleştirilmiş ve akım değerleri ölçülmüştür. Söz konusu devrenin uyku modunda 40uA-50uA arasında akım çektiği, normal modda ise 5,6mA (5600uA) akım çektiği gözlemlenmiştir. Dolayısıyla uyku modu ile normal çalışma modu arasında 8 MHz FOSC altında 100 kattan fazla akım tüketimi farkı olduğu görülmektedir.

PIC mikrodenetleyicilerinin büyük çoğunluğu nanoWatt teknolojisine sahiptir. Ayrıca 2V – 5,5V gibi geniş bir çalışma aralığına sahiptirler. PIC18F2550 mikrodenetleyicisinin akım tüketimi 2 V besleme ve 32 kHz osilatör ile uyku modunda 100 nA seviyesine kadar düşürülebilir. Bu kadar düşük akım değerlerinin piyasada satılan standart ölçü aletleriyle ölçülmesi mümkün değildir. Bunun için çok yüksek kalibrasyon ve ölçme hassasiyetine sahip pahalı ölçü aletleri kullanmak gerekir.

Yüksek ve Düşük Öncelikli Kesme Kavramı

PIC18F2455/2550/4455/4550 mikrodenetleyici ailesi çok sayıda kesme kaynağına sahiptir. Ayrıca 10F/12F/16F serisi mikrodenetleyicilerde olmayan öncelik kesmesi özelliğine sahiptir. Yüksek-öncelik kesmesi vektörü 000008h adresinde, alçak-öncelik kesmesi vektörü 000018h adresinde yer alır. Yüksek öncelikli kesmeler işlem sürecinde olan düşük öncelikli kesmeleri keser ve onların önüne geçer. Bu mikrodenetleyici ailesinde kesme işlemlerinin kontrol edilmesi için 10 adet kaydedici vardır. Bunlar:

  • RCCON – Reset Control Register: RCON kaydedicisi son Reset işleminin nedenini ve Boşta ya da Uyku modlarından uyanıldığını tespit etmeyi sağlayan bayrakları bulundurur. Ayrıca bu kaydedici tüm kesmeler için önceliği etkin kılacak IPEN bitini içerir.
  • RCON: RESET KONTROL KAYDEDİCİSİ (ADRES: FD0h – PIC18F2550)

    bit 7 IPEN: Kesme önceliğini etkinleştirme bitidir.
    1 = Kesmelerdeki önceliği etkinleştirir.
    0 = Kesmelerdeki önceliği kapatır.
    bit 6 SBOREN: BOR yazılım etkinleştirme bitidir(1).
    CONFIG2L yapılandırma kaydedicisinin BOREN1:BOREN0 bitleri = 01 ise:
    1 = BOR etkin
    0 = BOR kapalı
    CONFIG2L yapılandırma kaydedicisinin BOREN1:BOREN0 bitleri = 00, 10 ya da 11 ise:
    Bit devre dışı bırakılır ve ‘0’ olarak okunur.
    bit 5 Kullanılmıyor: ‘0’ olarak okunur.
    bit 4 (RI:): Reset komutu bayrak bitidir.
    1 = RESET komutu işletilmedi (yalnızca yazılım içinde kurulur).
    0 = Bir cihaz resetlenmesine neden olan RESET komutu işletildi (Brown-out reseti gerçekleştikten sonra yazılım içinde kurulmalıdır).
    bit 3 (TO:): Vardiya zamanlayıcısı zaman aşımı bayrak bitidir.
    1 = CLRWDT ya da SLEEP komutuyla ve cihaza besleme verildiğinde kurulur.
    0 = Bir WDT zaman aşımının olduğunu ifade eder.
    bit 2 (PD:): Güç düşmesi algılama bayrağı bitidir.
    1 = Besleme yükselmesi (uyku halinden çıkılması) ya da CLRWDT komutuyla vardiya zamanlayıcısı temizlendiğinde kurulur.
    0 = SLEEP komutunun işletildiğini gösterir.
    bit 1 (POR:): Power-on (cihaza güç verilmesi) Reset durumu bitidir2.
    1 = Bir Power-on resetinin olmadığını gösterir (yalnızca yazılım içinde kurulur).
    0 = Bir Power-on resetinin gerçekleştiğini gösterir (bir power-on reseti olduktan sonra yazılım içinde kurulmalıdır).
    bit 0 (BOR:): Brown-out (voltaj düşmesi) Reset durumu bitidir.
    1 = Bir Brown-out resetinin gerçekleşmediğini gösterir (yalnızca yazılım içinde kurulur).
    0 = Bir Brown-out reseti gerçekleşti (bir Brown-out reseti olduktan sonra yazılım içinde kurulmalıdır).
    Notlar:
    1: SBOREN etkinse, Reset durumu ‘1’, aksi durumda ‘0’ dır.
    2: POR bitinin gerçek reset değeri cihaz reseti türüyle belirlenir.

  • INTCON – Interrupt Control Register: 1 numaralı kesme kontrol kaydedicisidir. 4.bölüm altında da anlatılmış olan temel kesme işlemleri bu kaydedici altındadır. Öncelik durumuyla ilgili bir biti yoktur.
  • INTCON2 – Interrupt Control Register 2: 2 numaralı kesme kontrol kaydedicisidir. Harici kesmelerin kenar seçim yönleri bu kaydediciyle belirlenir. Timer0 ve RB port durum değişimi kesmesi için öncelik tanımlama bitlerini içerir.
  • INTCON3 – Interrupt Control Register 3: 3 numaralı kesme kontrol kaydedicisidir. INT1 ve INT2 harici kesme girişlerinin durumunu ve kesme önceliklerini kontrol eder.
  • PIR1 – Peripheral Interrupt Request 1: 1 numaralı çevresel aygıt kesmesi bayrak kaydedicisidir. Öncelik durumuyla ilgili bir biti yoktur.
  • PIR2 - Peripheral Interrupt Request 2: 2 numaralı çevresel aygıt kesmesi bayrak kaydedicisidir. Öncelik durumuyla ilgili bir biti yoktur.
  • PIE1 – Peripheral Interrupt Enable 1: 1 numaralı çevresel aygıt kesmesi etkinleştirme kaydedicisidir.
  • PIE2 – Peripheral Interrupt Enable 2: 2 numaralı çevresel aygıt kesmesi etkinleştirme kaydedicisidir.
  • IPR1 – Peripheral Interrupt Priority Register 1: 1 numaralı PIR kaydedicisinin öğeleri için öncelik belirleme bitlerini içerir.
  • IPR2 – Peripheral Interrupt Priority Register 2: 2 numaralı PIR kaydedicisinin öğeleri için öncelik belirleme bitlerini içerir.

Tablo 5.9’da tüm bu kesmelerin bayrak, etkinleştirme ve öncelik bitleriyle birlikte kaydedici isimleri özet olarak sunulmuştur. Tüm bu kesme önceliklerinin kullanılabilmesi için öncelikle RCON kaydedicisinin IPEN biti etkinleştirilmelidir.

Tablo 5.9 Tüm kesme kontrol kaydedicileri için kesme bitleri özet tablosu
Kesme AdıKesme Bayrak BitiKesme Etkinleştirme BitiKesme Öncelik BitiÖncelik Bitinin Yer Aldığı Kaydedici
0 numaralı harici kesmeINT0IFINT0IEBu kesme her zaman için yüksek önceliklidir-
1 numaralı harici kesmeINT1IFINT1IEINT1IPINTCON3[6]
2 numaralı harici kesmeINT2IFINT2IEINT2IPINTCON3[7]
RB port durum değişim kesmesiRBIFRBIERBIPINTCON2[2]
Timer0 taşma kesmesiTMR0IFTMR0IETMR0IPINTCON2[2]
Timer1 taşma kesmesiTMR1IFTMR1IETMR1IPIPR1[0]
Timer2 PR2 ile eşleşme kesmesiTMR2IFTMR2IETMR2IPIPR1[1]
Timer3 taşma kesmesiTMR3IFTMR3IETMR3IPIPR2[1]
A/D tamamlandı kesmesiADIFADIEADIPIPR1[6]
CCP1 kesmesiCCP1IFCCP1IECCP1IPIPR1[2]
CCP2 kesmesiCCP2IFCCP2IECCP2IPIPR2[0]
Akış paralel portu (SPP) okuma/yazma kesmesiSSPIFSSPIESSPIPIPR1[7]
EUSART alma kesmesiRCIFRCIERCIPIPR1[5]
EUSART gönderme kesmesiTXIFTXIETXIPIPR1[4]
MSSP kesmesiSSPIFSSPIESSPIPIPR1[3]
Osilatör hata kesmesiOSCIFOSCIEOSCIPIPR2[7]
Karşılaştırıcı kesmesiCMIFCMIECMIPIPR2[6]
USB kesmesiUSBIFUSBIEUSBIPIPR2[5]
Veri EEPROM/Flash yazma kesmesiEEIFEEIEEEIPIPR2[4]
Veri yolu çarpışma testi kesmesiBCLIFBCLIEBCLIPIPR2[3]
Yüksek/düşük voltaj algılama kesmesiHLVDIFHLVDIEHLVDIPIPR2[2]

Kesme sırasında dönüş PC adres değerinin yığına kaydedildiği daha önceden söylenmişti. Ayrıca, STATUS, BSR (Bank Select Register) ve WREG (Akümülatör) kaydedicilerinin değerleri de hızlı kaydedici yığınına (Fast Register Stack-FRS) gönderilir. Ancak yüksek ve düşük öncelikli kesmelerin her ikisinin de kullanılması durumunda, düşük öncelikli kesmelerden dönüşte bu kaydedicilerin değerlerinin doğruluğundan emin olunamaz. Çünkü düşük öncelikli kesmeler işlerken, yüksek öncelikli bir kesme oluşması durumunda düşük öncelikli kesme tarafından yığına alınmış olan bu değerlerin üzerine yazılır.

Kesme önceliği kullanılmadığı durumda, tüm kesmeler kesmeden dönüşte FRS’yi kullanır. Kesme kullanılmadığında ise, STATUS, BSR ve WREG kaydedicilerinin değerlerinin kullanıcı tarafından program içinde geçici olarak belleğin bir bölgesine kaydedilmesi gerekebilir. Bu işleme durum kaydı Context Saving denir. Ardından kesme işleminden dönüşte geçici belleğe kaydedilen bu veriler geri yüklenir.

Bu işleme ilişkin örnek Tablo 5.10’da gösterilmiştir. Program kodunun tamamı verilmemiş olup, böyle bir uygulamayı yapmak istediğiniz bir programda kodlamayı nasıl yapacağınıza açıklık getirilmiştir. Örnek uygulamada yüksek ve düşük öncelik kesmelerinin her ikisinin de kullanıldığı düşünülmüştür. Böylece hangi kesmeye girilmiş olursa olunsun bu durum kaydedicilerinin değerleri ana program işleyişi sırasında kullanıcı RAM’ine alınır ve kesme oluştuğunda tekrar geri yüklenir.

Tablo 5.10 Durum kaydedicileri değerlerinin geri yüklenmesi örneği

void main(){
 .
 .
 while(1){
  .
  .
  asm{  
   MOVWF 20h // akümülatör veri belleğinin 0.bankının 20h adresine yazılır
   MOVFF STATUS, 21h // Veri belleğinin 0.bankının 21h adresine yazılır
   MOVFF BSR, 22h // Veri belleğinin 0.bankının 22h adresine yazılır
  }
}

void Dusuk_oncelik_kesmesi() iv 000018h{
  .
  .
  asm{
   MOVFF 22h, BSR  //22h adresindeki veri BSR kaydedicisine yüklenir
   MOVF 20h, 0, 0 //20h adresindeki veri akümülatöre yüklenir
   MOVFF 21h, STATUS //21h adresindeki veri STATUS kaydedicisine yüklenir
  }
}
void Yuksek_oncelik_kesmesi() iv 000008h{
 .
 .
 asm{
  MOVFF 22h, BSR  //22h adresindeki veri BSR kaydedicisine yüklenir
  MOVF 20h, 0, 0 //20h adresindeki veri akümülatöre yüklenir
  MOVFF 21h, STATUS //21h adresindeki veri STATUS kaydedicisine yüklenir
 }
}


USB Kesmesi

Diğer çevresel aygıtlardan farklı olarak USB modülü çeşitli olay türlerine bağlı olarak çok geniş bir aralıkta kesme üretme özelliğine sahiptir. Bu olayları idare edebilmek için, USB modülü mevcut kesme kontrol kaydedicilerinden farklı olarak kendisine ait bir kesme lojiği ile donatılmıştır. Bu lojik sistemin basitleştirilmiş blok yapısı Şekil 5.11’de gösterilmiştir. Ancak davranış olarak normal kesme yönetimine benzer. Her kesme kaynağının ayrı bir bayrak ve etkinleştirme biti bulunur.

Şekil-5.11 USB kesmesi lojiği

Tüm bu olay kesmeleri nihayetinde tek bir kesme bayrağına çıkar. Bu kesme PIR2 kaydedicisinin 5.biti olan USBIF bayrağıdır. Tek başına bu bayrak bitine bakıldığında hangi olayın meydana geldiği tespit edilemediğinden USB modülü için hazırlanmış ilgili kaydedicilere bakmak gerekir. Ayrıca USB kesmelerinin kendi içinde öncelik seviyelendirmesi yoktur. Öncelik durumu yalnızca tüm USB kesmeleri için USBIP bitiyle belirlenir. Tablo 5.11’de USB kesmelerini kontrol etmeyi sağlayan kaydedicilerin özeti sunulmuştur.

Tablo 5.11 USB kesmeleri özet tablosu
KaydediciBit 7Bit 6Bit 5Bit 4Bit 3Bit 2Bit 1Bit 0
USB INTERRUPT STATUS REGISTER – USB KESMESİ DURUM KAYDEDİCİSİ
UIR-SOFIFSTALLIFIDLEIFTRNIFACTVIF
D+/D- USB
veri hatlarında
aktivite var mı?
1 = Var
0 = Yok
UERRIFURSTIF
USB INTERRUPT ENABLE REGISTER – USB ETKİNLEŞTİRME KAYDEDİCİSİ
UIE-SOFIESTALLIEIDLEIETRNIEACTVIEUERRIEURSTIE
USB ERROR INTERRUPT STATUS REGISTER – USB HATA KESMESİ DURUMU KAYDEDİCİSİ
UEIRBTSEF--BTOEFDFN8EFCRC16EFCRC5EFPIDEF
USB ERROR INTERRUPT ENABLE REGISTER – USB HATA KESMESİ ETKİNLEŞTİRME KAYDEDİCİSİ
UEIEBTSEE--BTOEEDFN8EECRC16EECRC5EEPIDEE

Veri hattında bir hareketlilik olup olmadığını izlememizi sağlayan ACTVIF biti USB modülü askı (suspend) modundan uyanmasının ya da askı moduna girmesinin hemen ardından temizlenemez. Yazılım tarafından ACTVIF bayrağı temizlenmeden önce, dahili donanım durum makinesini senkronize etmek için birkaç saat darbesi çevrimine ihtiyaç duyulur. Dahili donanımın senkronize edilmesinden önce ACTVIF’i temizlemenin ACTVIF bayrağı üzerinde bir etkisi olmayabilir. Ayrıca, USB modülü 96 MHz PLL kaynağından saat darbesi kaynağını kullanırsa, ardından USB kontrol kaydedicisinin (UCON) SUSPND biti temizlendikten sonra, USB modülü 96 MHz PLL için beklemesi sırasında hemen çalışmaya başlayamayabilir. Bunun için, ACTVIF bayrağının temizlenmesini garanti etmek için yazılımınız içinde aşağıdaki ufak kod parçasını kullanmanız tavsiye edilir.


UCON.SUSPND = 0;
while (UIRbits.ACTVIF) { UIRbits.ACTVIF = 0; }

USB donanımının kullanımıyla ilgili ayrıntılı bilgiye 9.5. bölümden ve EK-I6’dan ulaşabilirsiniz.