Kesme (Interrupt)   mikrodenetleyicilerde kullanılan ve gerçekten çok önemli olan bir kavramdır. Kesmenin ne olduğunu bir örnek ile basitçe açıklayacak olursak; diyelim ki bilgisayarda oyun oynuyoruz. Tam o sırada cep telefonunuz çalıyor ve oyunu bekletip telefona bakıyoruz. Telefon konuşmamız bitince oyuna kaldığımız yerden devam ediyoruz. Bu örnekte asıl işimiz olan oyun oynamak, telefonun çalması ile kesildi ve başka bir iş olan telefon görüşmesi yapıldıktan sonra  oyuna geri dönüldü. İşte kesme böyle birşey. Önceliği yüksek işlerin mikrodenetleyici tarafından ana program akışı kesilerek halledilmesine biz kesme diyoruz.  Eğer bir kesme kaynağından mikrodenetleyiciye uyarı gelir ise uC yapmakta olduğu işi “pause” eder, kesme alt programına gider , o programı icra eder, daha sonra ana programda kaldığı yerden devam eder. Peki biz kesmeleri nerelerde kullanırız? Genellikle çok hızlı yapılması gereken işlemlerde, anlık tepki verilmesi gereken yerlerde kesmeleri kullanırız.

PIC16f628A’nın  RB0 kesmesi, RB4-7 değişiklik kesmesi, Timer0 kesmesi, Timer1 kesmesi, Timer2 kesmesi, seri iletişim kesmesi gibi kesmeleri bulunur. Toplamda 10 adet kesmeye sahiptir. Bu yazıda işleyeceğimiz kesme olan RB0 kesmesi, RB0 pininde meydana gelecek bizim önceden belirlediğimiz herhangi bir değişikliği (0’dan 5V’a veya 5v’tan 0’a) algılayıp anında işlem yapmamıza yarayan bir kesmedir. Bunu nerede kullanabiliriz diye bir soru gelebilir aklınıza. Hemen şöyle bir örnekle açıklayalım; bir hastanenin elektrikleri kesiliği anda devreye girecek bir jeneratör bulunduğunu düşünelim. Bu jeneratörün hastanedeki medikal cihazların çalışmaları kesilmeden devreye girmesi gerekmektedir. Çünkü hastanelerde bulunan medikal cihazların bir çoğu hayati öneme sahiptirler. Bu yüzden elektriğin kesildiğinin anında algılanması ve müdahale edilmesi gerekir. Biz eğer ana programımız içerisinde “if” komutu ile RB0 pininde elektriğin olup olmadığını algılatmak istersek, ana programdaki diğer komutların işlenip bitmesi ve sıranın if komutuna gelmesini beklememiz gerekir. Yani programın uzunluğuna bağlı olarak us veya ms boyutunda gecikmeler meydana gelecektir. Biz bu gecikmelerden kurtulmak için RB0 kesmesini kullanırız. Bu kesmeyi kurduğumuz senaryoda ise elektrikler kesildiği anda işlemci ana programın akışını yarıda kesecek ve kesme alt programına giderek gerekli işlemi icra edecektir. RB0 kesmesinin kurulumu için aşağıdaki adımları izlemek gerekir:

  1. INTCON – INTERRUPT CONTROL REGISTER’ındaki  GIE: Global Interrupt Enable bit’i  “1” yapılmalıdır.
  2. INTCON – INTERRUPT CONTROL REGISTER’ındaki   INTE: RB0/INT External Interrupt Enable bit’i “1” yapılmalıdır
  3. OPTION_REG – OPTION REGISTER’ındaki INTEDG: Interrupt Edge Select bit’i yükselen kenar isteniyor ise “1” düşen kenar isteniyo ise “0” yapılmalıdır.
  4. RB0 pini giriş olarak ayarlanmalıdır. (TRISB.F0=1;)

İsterseniz hemen programımızı yazıp denememizi yapalım.

void interrupt()    // interrupt alt programı
{
portb=~portb;      // portb'yi tersle
INTCON.INTF=0;     // RB0 kesmesi bayrağını sıfırla
}

void main()     //Ana program
{
INTCON.GIE=1;            //INTCON – INTERRUPT CONTROL REGISTER'ındaki  GIE: Global Interrupt Enable bit'i  "1" yapılmalıdır.
INTCON.INTE=1;          //INTCON – INTERRUPT CONTROL REGISTER'ındaki   INTE: RB0/INT External Interrupt Enable bit'i "1" yapılmalıdır
OPTION_REG.INTEDG=0;    //OPTION_REG – OPTION REGISTER'ındaki INTEDG: Interrupt Edge Select bit'i yükselen kenar isteniyor ise "1" düşen kenar isteniyo ise "0" yapılmalıdır.
trisb=0b00000001;       //RB0 pini giriş olarak ayarlanmalıdır. (TRISB.F0=1;)
portb=0;                //PORT'yi sıfırla
while(1)                //Sonsuz Döngü
{
portb=0xff;    // PORTB'nin tüm pinleri 1
delay_ms(2000);//2 saniye bekle
portb=0;       //PORTB'nin tüm pinleri 0
delay_ms(2000);//2 saniye bekle
}
}

Programdaki en önemli kısım “void interrupt” kısmıdır. bütünkesme alt programları bu kısma yazılır. Bir diğer dikkat çeken nokta ise INTCON.INTF bitinin temizlenmesidir. Bu bite RB0 kesme bayrağı ismi verilmiştir. Kesme gerçekleştiğinde bu bayrak 1 olur. Tekrar kesme oluşabilmesi için silinmesi gerekir. Devre şeması aşağıda görülmektedir.

Programımızda PORTB 2 saniyede bir değişirken, eğer RB0 kesmesi gelirse anında değiştiği gözlenmekdir. Yani hiç bir gecikmeye maruz kalmadan kesme alt programı içerisinde yapılan iş anında gerçekleşmektedir.

Yazıya ait bütün dosyaları buradan indirebilirsiniz.

İyi çalışmalar..

yorum
  1. Özkan dedi ki:

    İyi ki varsınız…

  2. vedat dedi ki:

    Kodlarının doğru çalıştığına eminmisin stack overflow hatası alıyorum pbp ile çalışırken daha kolaydı mikrobasic e geçmeye çalışıyorumda

  3. erdinc dedi ki:

    arkadaşlar keypad encoder 72c922 ile çalıştırmak isteyenler için bu kodu paylaşmak isterim
    4×2 için yaptım iseyenler sayısını arttırabilir(örn:4×4)

    int keys[]={1,2,3,4,
    5,6,7,8} ;
    int temp=0;

    void interrupt()
    { // interrupt alt programı

    temp=keys[portb>>1] ; // portb’yi tersle
    portc=temp ;

    INTCON.INTF=0; // RB0 kesmesi bayrağını sıfırla

    }

    void main() {
    INTCON.GIE=1; //INTCON – INTERRUPT CONTROL REGISTER’ındaki GIE: Global Interrupt Enable bit’i “1” yapılmalıdır.

    INTCON.INTE=1; //INTCON – INTERRUPT CONTROL REGISTER’ındaki INTE: RB0/INT External Interrupt Enable bit’i “1” yapılmalıdır

    OPTION_REG.INTEDG=0; //OPTION_REG – OPTION REGISTER’ındaki INTEDG: Interrupt Edge Select bit’i yükselen kenar isteniyor ise “1” düşen kenar isteniyo ise “0” yapılmalıdır.

    trisb=0b00011111; //RB0 pini giriş olarak ayarlanmalıdır. (TRISB.F0=1;)
    trisc=0b00000000;

    portb=0; //PORT’yi sıfırla

    while(1) { //Sonsuz Döngü

    delay_ms(2000);//2 saniye bekle
    portc=0; //PORTB’nin tüm pinleri 0

  4. erdinc dedi ki:

    örnek içinde çok teşekkürler

  5. erdinc dedi ki:

    18f4520 için rb0 interruptını yapabilirmisinniz ? bütün tanımlamaları yaptım fakat bir türlü interruptın içne girmiyor

  6. ciwan dedi ki:

    hocam 3 kere rb0 kesmesı geldıgınde 7.ledi yaksın bunu çözebılırmısın ?

Bir Cevap Yazın

Aşağıya bilgilerinizi girin veya oturum açmak için bir simgeye tıklayın:

WordPress.com Logosu

WordPress.com hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap / Değiştir )

Twitter resmi

Twitter hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap / Değiştir )

Facebook fotoğrafı

Facebook hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap / Değiştir )

Google+ fotoğrafı

Google+ hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap / Değiştir )

Connecting to %s