Fórum témák

» Több friss téma
Cikkek » WILL-I THE END (robotika és AVR kezdőknek)
WILL-I THE END (robotika és AVR kezdőknek)
Szerző: Fizikus, idő: Máj 17, 2010, Olvasva: 30588, Oldal olvasási idő: kb. 4 perc
Lapozás: OK   3 / 8

ATMega8 külső megszakítások beállítása

Elég gyakori feladat azt vizsgálni, hogy egy adott I/O láb állapota mikor változik meg. Úgy is megírhatjuk a mikrovezérlő programját, hogy időközönként megvizsgálja egy láb állapotát, de az AVR-eknél megszakításokat is beállíthatunk. A megszakításokat arra használhatjuk hogy figyelmeztesse a mikrovezérlőn futó programot, hogy egy láb állapota megváltozott.


WILL-I karjaiban lévő mikrokapcsolókat akarjuk használni, és mint korábban láttuk két módszer közül választhatunk:

  • polling: nem a legjobb megoldás, mert miközben a robot halad előre elég sok mindent kell közben a mikrovezérlőnek tennie (mérni kell az IR érzékelővel (ADC), ráadásul értékelni is kell a mért adatokat, és ezek függvényében el kell dönteni, hogy merre menjen tovább a robot).
  • Megszakítás: ezzel a módszerrel lenne elegáns megoldani a problémát, mert ez nem terheli feleslegesen a mikrovezérlőt, csak akkor kér figyelmet ha valamelyik mikrokapcsoló nekiütközik valaminek.

Az első dolgunk kideríteni, hogy az általunk használt mikrovezérlő milyen megszakításokkal rendelkezik. Ehhez meg kell nézni az Atmega8-as adatlapját:

Látható, hogy az Atmega8-as két külső megszakítással rendelkezik (INT0 és INT1). Az adatlapot tanulmányozva azt is kideríthetjük, hogy a 4-es (PD2) és az 5-ös (PD3) lábak tartoznak az INT0-hoz és INT1-hez, ezek használhatóak külső megszakítás létrehozásához.

A következő lépésben azt kell megtalálni, hogy az Atmega8 esetében melyik regiszter(ek) vezérlik a külső megszakításokat es a hozzájuk tartozó lábakat.

A lábak négyfajta különböző állapotváltozása tud megszakítást kiváltani:

  1. a láb alacsony logikai értéket vesz fel
  2. a láb bármilyen logikai értékváltozása
  3. lefutóél (a láb logikai értéke magasról alacsonyra változik)
  4. felfutóél (a láb logikai értéke alacsonyról magasra változik)

Az MCUCR regiszterben lehet beállitani, hogy a fenti állapotváltozások közül melyik aktiválja a megszakítást (INT0 esetén az ISC00 és ISC01, INT1 esetén pedig az ISC10 és ISC11 biteket kell beállitani a regiszteren belül).

Mielőtt használni tudnánk a megszakításokat, előtte engedélyezni kell őket. Az Általános Megszakítás Vezérlő Regiszter (GICR) szabályozza hogy melyik megszakítás van engedélyezve (bekapcsolva). Egy adott megszakítás engedélyezéséhez a megfelelő bitet be kell állítani a GICR regiszterben, majd engedélyezni kell az általános megszakításokat a sei() makróval.

Általános MegszakításJelző Regiszter (GICR). Ebben a regiszterben az adott külső megszkításhoz tartozó bit értékének 1-et adva a korábbi megszakítások törölhetőek (lásd később).

A megszakítások használatának főbb lépései:

  • Megszakítások beállítása és engedélyezése a megfelelő regiszterekben.
  • Megszakítás Kiszolgáló Rutin (ISR) definiálása


Sajnos nincs általános sablon, hogyan kell az ISR-t definiálni, mert a C nyelv alapból nem határozza meg, hogy a megszakítások hogyan legyenek implementálva. A különböző forditók másként kezelik a megszakításokat, más-más szintaktikát használnak, néha nem standard C utasításokat és kiterjesztéseket is. Ezért az alábbiak csak WinAVR (AVR-GCC) esetén érvényesek.

Az alábbi elméleti példa az INT0 külső megszakítás használatának főbb lépéseit mutatja be. Megszakítás akkor keletkezik, amikor a PD2-es láb állapota magasról alacsonyra vált (lefutó él esetén lesz megszakítás).

A megszakítások használatához kell az interrupt.h fejlécfájl.


  1. #include <avr/interrupt.h>
  2. int main (void)
  3. {

Először megadjuk, hogy melyik lábat (melyik külső megszakítást) fogjuk használni.


  1. // 4-es labat (PD2) hasznaljuk ebben a peldaban
  2.     GICR |= (1<<INT0);

A kapcsolásunkat figyelembe véve (a nyomógombnál a belső felhúzóellenállás be van kapcsolva), egy lefutó élre aktivált megszakítást akarunk, ezért az ISC01 bitet kell beállítani.

Ezután beállítjuk, hogy az adott láb lefutó élre adjon megszakítást.


  1. // megszakitas az INT0 labon, lefuto el eseten
  2.     MCUCR = (1<<ISC01) ;

Végül bekapcsoljuk a megszakítást

  1. // megszakitas bekapcsolasa
  2.     sei ( );
  3.      while (1)
  4.     {
  5.        // vegtelen ciklus (itt fut a program)
  6.      }
  7. }

Már csak azt kell kinyomoznunk, hogy melyik megszakításvektor hívódik meg, amikor a külső megszakításkérelem érkezik. A különböző megszakítások elnevezéseit megtalálhatjuk a WINAVR dokumentációban a <avr/interrupt.h> fejlécfájra vonatkozó részben
A PD2-es láb (INT0) esetén az INT0_vect vektor hívódik meg.

Amikor az adott megszakításkérelem érkezik, a mikrovezérlő a hozzá tartozó megszakítás kiszolgáló rutinban lévő utasítasokat hajtja végre. Egy megszakítás kiszolgáló rutint az ISR() makróval tudunk definiálni. A makróban a megszakítás nevét mint parmétert kell megadni. A kód törzsrésze tartalmazza magát az ISR kódot. Az INT0_vect jelzi, hogy ez a 0-ás külső megszakításhoz (INT0) tartozó ISR. Figyeljük meg hogy az ISR fejléc sehol máshol nincs deklarálva a programon belül.

  1. // ISR (MEGSZAKITAS_NEV) - ez fut le, ha a PD2-re kotott gombot lenyomjuk
  2. ISR (INT0_vect)
  3. {
  4.     <ISR kod>    // ide jonnek a megszakitas kiszolgalo rutin utasitasai
  5. }

Egy fontos dolgot említenék még meg a megszakításokkal kapcsolatban, egy ISR-nek a lehető leggyorsabbnak kell lennie. Sok mikrokontroller által végrehajtott feladatban kritikus az időzítés (például a soros kommunikáció), ha egy hosszú ISR rutint használunk és egy megszakítás kérelem érkezik amikor épp egy időzítésre érzékeny rutin végrehajtása történik, akkor a promramunk elszállhat. Ha nem tudjuk elkerülni, és mindenképpen hosszú ISR rutint vagyunk kénytelen használni, akkor megvédhetjük az időzítésre érzékeny programkódunkat, ha a megszakításokat letiltjuk a cli() utasítással a kritikus kód előtt, majd a megszakításokat újra engedélyezzük a sei() utasítással a kritikus kód után.

Ahhoz hogy a megszakítás jól működjön a megszakításban használt változók dekralárásához a volatile előtagot KELL használni! (mert a megszakítás bármikor bekövetkezhet aszinkron módon)
    

Ezután a rövid elméleti összefoglaló után lássuk hogyan is kell a valóságban megvalósítani a megszakításokat.
 


A cikk még nem ért véget, lapozz!
Következő: »»   3 / 8
Értékeléshez bejelentkezés szükséges!
Bejelentkezés

Belépés

Hirdetés
XDT.hu
Az oldalon sütiket használunk a helyes működéshez. Bővebb információt az adatvédelmi szabályzatban olvashatsz. Megértettem