fpganedir.com'da ara

fpganedir mail

IRQ HARİCİ KESME UYGULAMASI (EXTERNAL INTERRUPT)

Bu örneğimizde ARM 7 tabanlı bir mikrodenetleyici olan LCP2134 üzerinde harici kesme uygulamasını gerçekleştireceğiz. Bu uygulama kapsamında mikrodenetleyicinin P0.1 (EINT0) pinini süren bir sinyalin yükselen ucunda bir kesme oluşturacağız. Harici kesme bir anahtarın basıldığını anlamak yada matriks yapı Keypad sürücülerini kontrol etmek gibi bir çok uygulamada tasarımcılara yardımcı olan bir uygulamadır.

Örneğimizin yazılım kodunu C dilini kullanarak oluşturacağız. Derleyici program olarak Keil-uVision4 programını kullanacağız. Son olarak oluşturduğumuz tasarımın uVision4 programında simülasyonunu yapıp, hata ayıklama işleminin nasıl yapıldığını göreceğiz.

Projeye başlamadan önce LPC2134 mikrodenetleyicinin user manual ile datasheet'ini incelemenizi ve proje boyunca yardımcı bir eleman olarak kullanmanızı tavsiye ederiz.

uVision4 programını açalım ve yeni bir proje oluşturalım. Ardından projeye yeni bir C dosyası ekleyelim. uVision4 programında yeni bir projenin nasıl oluşturulduğunu ilk Arm Projem örneğinde bulabilirsiniz.

C Yazılımı

Proje c yazılımına PINSEL0 saklayıcını modifiye ederek P0.1 pininin fonksiyonunu GPIO formundan Harici Kesme (EINT0) formuna çevirerek başlayalım.

PINSEL0 = 0xC; //P0.1 pinini EINT0 olarak ayarla

Ardından Vector control 0(VICVectCntl0) saklayıcısında modifikasyon yapalım. LPC2134 mikrodenetleyicisinde bulunan 16 ayrı IRQ kesmesi kontrolleri için 16 adet vector control saklayıcısı bulunur (VICVectCntl0 ...VICVectCntl15). VICVectCntl0 en yüksek önceliğe VICVectCntl15 ise en düşük önceliğe sahiptir.

Biz örneğimizde harici kesmeyi vector control 0 saklayıcısı ile kontrol edeceğiz. Bunun için aşağıda verilen kodu kullanacağız.

VICVectCntl0 = 0x20 | 14; // EINT0 harici kesmesi için VIC 0 kullan

Yukarıdaki kodun kullanılma şekli VICVectCntl0 = 0x20 | VIC Channel Mask ; şeklindedir. Herhangi bir kesmenin "VIC Channel Mask" ine ilgili mikrodenetleyicinin user manual'inden ulaşabilirsiniz.

Örneğimize Vector Address (VICVectAddr0) saklayıcısına kesme fonksiyonun adresini atayarak devam edeceğiz. Bu adres sayesinde harici kesme oluştuğu zaman, program sayacına  işlenecek fonksiyonun(ISR) adresi yüklenir. Ardes atama işlemi için aşağıdaki ifade kullanılır.

VICVectAddr0 = (unsigned long) kesme_fonksiyon_ismi;

Bizim örneğimizdeki fonkiyon ismi "kesme" olacak. Dolayısıyla C koduna ekleyeceğimiz ifade aşağıdaki gibi olacak.

VICVectAddr0 = (unsigned long) kesme;

Örneğimizin koduna harici kesmenin hangi şartlarda oluşacağını tanımlayacağımız ifadeleri c koduna ekleyerek devam edelim. Biz örneğimizde harici sinyalin yükselen kenarında kesme oluşturacağız. Bunun için External Interrupt Flag (EXTMODE) saklayıcısı ile External Interrupt Wakeup (EXTPOLAR) saklayıcılarını kullanacağız.

EXTMODE harici kesmenin sinyal seviyesi mi yoksa sinyal kenarı duyarlımı olacağını belirlemek için kullanılır. EXTPOLAR ise sinyal kenar duyarlı bir kesmenin sinyalin düşen kenarında mı yoksa yükselen kenarında mı olacağını belirlemek için kullanılır. Bizim örneğimizde harici kesme yükselen kenar duyarlı olacak. Bunun için proje kodumuza aşağıdaki ifadeleri ekleyeceğiz.

EXTMODE = 1;    //EINT0 kenar duyarlı mod olarak ayarla
EXTPOLAR = 1; // Yükselen kenar duyarlı

Sıradaki işlem tanımladığımız kesmeyi aktif etme işlemidir. Bunun için Interrupt Enable (VICIntEnable) saklayıcısını modifiye edeceğiz. Bu saklayıcı 32 adet kesme isteğini aktif etmek için kullanılan bir saklayıcıdır. Biz örneğimizde harici kesme 0 (EINT0) ile ilgilendiğimiz için bu saklayıcı içerisinde bu kesmeyi aktif etmek için kullanılan 14. biti '1' yapacağız. Örneğin c koduna ekleyeceğimiz ifade aşağıdaki gibi olacak.

VICIntEnable = 1 << 14; // ENT0 aktif et

Artık kesme fonksiyonunu yazabiliriz. Bu fonksiyon kesme oluştuğu zaman işlenecek olan fonksiyondur. Kesme fonksiyonunu tanımlarken isminin yanına fonksiyonun IRQ olduğunu göstermek için __irq son ekini ekleyeceğiz. Kesme fonksiyonu içerinde External Interrupt Flag (EXTINT) saklayıcısının EINT0 bayrağını temizlememiz gerekir. Aksi durumda program daima kesme modunda kalır.

Örneğimizin kesme fonksiyonunda bir sayıcı tanımlayacağız ve program her kesmeye girdiğinde sayıcıyı bir artıracağız. Sayıcı 7 olduğunda P0.0 pinine bağladığımız ledi yakacağız.

void kesme (void) __irq
{
     ++sayici; // sayıcıyı 1 artır
     if (sayici==8) sayici=0;
     EXTINT = 1; // ENT0 kesme bayrağını temizle
     VICVectAddr = 0;
}

Örneğimizin bütün c kodu ağağıdaki gibi olur.

#include <LPC213X.H>

int volatile sayici = 0;

/* Kesme fonksiyonu */
void kesme (void) __irq
{
     ++sayici; // sayiciyi 1 artır
     if (sayici==8) sayici=0;
     EXTINT = 1; // ENT0 kesme bayragini temizle
     VICVectAddr = 0;
}

/* Initialize EINT1 Interrupt Pin */
void init_eint0 (void)
{
     PINSEL0 = 0xC;                                               //P0.1 pinini EINT0 olarak ayarla
     VICVectCntl0 = 0x20 | 14;                              // EINT0 harici kesmesi için VIC 0 kullan
     VICVectAddr0 = (unsigned long) kesme;
     EXTMODE = 1;                                                //EINT0 kenar duyarli mod olarak ayarla
     EXTPOLAR = 1;                                              // Yükselen kenar duyarli
     VICIntEnable = 1 << 14;                               // ENT0 aktif et
}

int main (void) {

     IODIR0 = 0x00000001; //P0.0 pinini output olarak ayarla
     IOCLR0= 0x00000001; // P0.0 pinine 0 değerini yükle
     init_eint0();

     while (1)
     {
        if (sayici = 7)
             IOSET0= 0x00000001;// P0.0 pinine 1 değerini yükle
      }
}

Artık projemizin simülasyonunu yapıp tasarımı doğrulayabiliriz. Simülasyon esnasında External Interrupts diyalog kutusunu, GPIO 0 diyalog kutusunu, VIC diyalog kutusu ile watch penceresini kullanacağız.

External Interrupts diyalog kutusunu ile EINT0 kesmesinin statüsünü inceleyebiliriz. Diyalog kutusunu, menü çubuğunda Peripherals>System Control Block > External Interrupts'ı seçerek açabiliriz.

GPIO 0 diyalog kutusunda harici kesme oluşturmak için P0.1 pinine değer verebilir, P0.0 pininden de değer okuyabiliriz.

VIC diyalog kutusu ile programın VIC ayarlarını görebiliriz.

watch penceresi ile sayici değişkenin değerini izleyebiliriz.

İyi eğlenceler....

Projenin bütün dosyalarına buradan ulaşabilirsiniz. Sıkıştırılma şifresi "fpganedir"

 

Anasayfa | Fpga | VHDL | VHDL Sözlüğü | Embedded Sistem | Android | Sayısal Tasarım | Simulasyon | PCB | Örnekler | Forum | İletişim
Copyright © 2010-2013 FPGAnedir. All Rights Reserved.