WebElektronika

Interrupt a PIC32MX130F064B mikrovezérlőnél I.

person access_time 2015.01.26.
Megnézzük most egyszerű példák segítségével, hogy hogyan tudunk az INT0-hoz megszakítást rendelni. Ahogy általában eddig is, most is inkább a makrohasználatot preferáljuk a konfigurációs regiszterek közvetlen írása helyett.


Folytatjuk a PIC32MX család megismerését a PIC32MX130F064B-t tartalmazó tesztpanel segítségével. Elkezdjük áttekinteni a megszakítások használatát, de most is a konfigurációs regiszterek közvetlen írása helyett makrókat használunk az interrupt tulajdonságainak beállítására. Hasonlóan járunk el az IT flagek figyelésénél és törlésénél is, szintén makrókkal fogjuk ezeket megoldani.

Amikor egy IT Handler-t készítünk, amely egy speciális "C" függvény, annak a következő tulajdonságokkal kell rendelkeznie :

  • nincs visszatérési értéke (nincs tehát "return"), a függvény szignatúrájában "void" szerepel
  • a függvény paraméterlistája üres
  • más függvények nem hívják meg
  • a handler sem hív meg más függvényt

 

Mielőtt megnéznék a példákat, ismerjük meg az Interrupt Handler-nek milyen megadási lehetőségei vannak.

 

1. lehetőség

Az első táblázatban látjuk, hogy az "Elmélet" résznél lévő függvény megfelel az első két elvárásnak, nincs visszatérési érték, illetve a paraméterlista is üres. Az "attribute" helyére írjuk be az "ISR"-t, ez látható a "Példa" résznél.

Elmélet Példa
void __attribute__ (( interrupt(ipl1),vector(0)))
InterruptHandler( void)
{
      // kód
}
void __ISR( 0, ipl1) InterruptHandler (void)
{
    // IT kód
}
 

 

2. lehetőség

Használhatjuk az első megoldás helyett a "#pragma"-t is, a következő demo ezt mutatja :

#pragma interrupt InterruptHandler ipl1 vector 0
void InterruptHandler( void)
{
      // kód
}

 

1. példa

Először definiáljuk a LED0-t és a LED1-et. Ezután létrehozzuk az interrupt függvényt, amelyben figyelni fogjuk egy makróval, hogy kinek volt megszakítási kérése. Tekintettel arra, hogy mi csak az INT0-ra kötött nyomógomb állapotváltására bekövetkezett megszakítást használjuk, ezért ebben az esetben a "mINT0GetIntFlag()" vizsgálata elhagyható.

Ha megszakítás történik, amelyet az INT0 állapotváltása okozott, akkor a LED0 és a LED1 állapotot vált, illetve nagyon fontos, hogy az INT0-hoz tartozó IT flag-et töröljük. A megszakítás flag-eket mindig szoftveresen kell törölnünk.

#include <p32xxxx.h>
#include <plib.h>

#define    LED0    LATBbits.LATB0
#define    LED1    LATBbits.LATB1

void __ISR(0, ipl1) InterruptHandlerINT0(void)
{
    if(mINT0GetIntFlag())
    {
        LED0 = ~ LED0;
        LED1 = ~ LED0;
        mINT0ClearIntFlag();
    }
}

main()
{
    mPORTBSetPinsDigitalOut(BIT_0 | BIT_1 );
    mPORTBSetPinsDigitalIn(BIT_7);

    mINT0SetIntPriority(1);
    INTEnableSystemSingleVectoredInt();
    mINT0IntEnable(1);

    while( 1);
}

A "main()" függvényben először beállítjuk makróval a "B" port 0. és 1. bitjét kimenetre, majd a "B" port 7. bitjét bemenetre, Ezt a makrók használata helyett megtehettük volna akár ezzel az utasítással is :

TRISB = 0B10000000;

A következő makróhívással a megszakításunk prioritását állítjuk be, majd engedélyezzük a "Single" IT módot. Ezután már csak az engedélyezés maradt, majd a vezérlés a végtelen ciklushoz kerül és innen fogunk mindig "elugrani" a megszakításkor az IT handler-hez.

 

2. példa

Ez a példa az előzőtől csak abban különbözik, hogy az IT handler másképp került megvalósításra, itt a második módszert, a "#pragma" alkalmaztuk.

#include <p32xxxx.h>
#include <plib.h>

#define    LED0    LATBbits.LATB0
#define    LED1    LATBbits.LATB1

#pragma interrupt InterruptHandlerINT0 ipl11 vector 0
void InterruptHandlerINT0(void)
{
    if(mINT0GetIntFlag())
    {
        LED0 = ~ LED0;
        LED1 = ~ LED0;
        mINT0ClearIntFlag();
    }
}

main()
{
    mPORTBSetPinsDigitalOut(BIT_0 | BIT_1 );
    mPORTBSetPinsDigitalIn(BIT_7);

    mINT0SetIntPriority(1);
    INTEnableSystemSingleVectoredInt();
    mINT0IntEnable(1);

    while( 1);
}

 

3. példa

Ez a példa is nagyon hasonlít az elsőre, itt a különbség az IT handler "belseje", a nyomógomb (INT0) lenyomásakor növeljük eggyel a "B" port értékét. Természetesen az IT flag szoftveres törlése itt sem marad el.

A végtelen ciklus most nem egy pontosvesszővel került lezárásra, hanem tartlamazza a ciklusmagot is, ahová írhatunk kódot. Innen csak akkor kerül ki a vezérlés, ha történik megszakítás.

#include <p32xxxx.h>
#include <plib.h>

void __ISR(0, ipl1) InterruptHandlerINT0(void)
{
    if(mINT0GetIntFlag())
    {
        LATB++;
        mINT0ClearIntFlag();
    }
}

main()
{
    DDPCONbits.JTAGEN = 0;    // tiltjuk a JTAG-et
    TRISB = 0B10000000;           // B port 7. bemenet, többi kimenet
    LATB = 0x0000;                       // töröljük a kimenetet

    mINT0SetIntPriority(1);
    INTEnableSystemSingleVectoredInt();
    mINT0IntEnable(1);

    while(1)
    {
            // egyéb kódrészlet
    }
}