Megszakítás az Atmel AVR Studio AVR vezérlőjén. Képzés. A megszakítás fogalma. Hangot adunk a mikrokontrollernek _______________________________ Megszakítás _______________________________

Az AVR mikrovezérlők nagyszámú perifériás eszközt tartalmaznak (ADC, Timer/Counters, EXTI, Analog Comparator, EEPROM, USART, SPI, I2C stb.), amelyek mindegyike képes bizonyos műveleteket végrehajtani az adatokon/jeleken és egyéb információkon. Ezeket az eszközöket a mikrokontrollerbe integrálták, hogy javítsák az alkalmazás hatékonyságát és csökkentsék a költségeket mindenféle AVR mikrokontrolleren alapuló eszköz fejlesztésekor.

A processzor az adatmemóriában található I/O regisztereken keresztül kommunikál/vezérli a perifériás eszközöket, lehetővé téve ezek használatát, mint a szokásos változókat. Minden eszköznek saját I/O regisztere van.

Minden I/O regiszter három csoportra osztható: adatregiszterekre, vezérlőregiszterekre és állapotregiszterekre.

A Vezérlőregiszterek segítségével az eszközt úgy konfigurálják, hogy bizonyos frekvenciával, pontossággal stb. egy vagy másik üzemmódban működjön, az adatregiszterek segítségével pedig kiolvassák az eszköz működésének eredményét (analóg-digitális átalakítás, fogadás). adatok, időzítő/számláló érték stb.). Úgy tűnik, nincs itt semmi bonyolult (sőt, itt tényleg nincs semmi bonyolult :)), bekapcsolta a készüléket, jelezte a kívánt üzemmódot, majd csak a kuponok levágása, a kész adatok elolvasása van hátra. és használja őket a számításokhoz. A teljes kérdés az, hogy ezeket az adatokat „mikor” kell kiolvasni (befejezte-e a készülék a munkáját, vagy még folyamatban van az adatok feldolgozása), mert minden periféria párhuzamosan működik a mikrokontroller maggal, sőt különböző frekvenciákon. Felmerül a kommunikáció megvalósításának kérdése valamint a processzor és a perifériák közötti szinkronizálás.

Amint valószínűleg már sejtette, az eszköz és a processzor közötti kommunikáció és szinkronizálás megvalósításához „Állapotregisztereket” használnak, amelyek tárolják egy adott eszköz aktuális működési állapotát a regiszter állapota” (zászló), amelynek aktuális értéke „beszél” a jelen eszköz aktuális állapotáról vagy egyedi funkciójáról (befejezett/nem befejezett munka, adatfeldolgozási hiba, regiszter üres stb.).

A processzor és a periféria közötti kommunikációs mechanizmus zászlólekérdezéssel valósul meg, amelyek az eszköz bizonyos funkcióiért felelősek. Egy adott zászló értékétől (eszköz állapotától) függően módosíthatja a program végrehajtásának menetét (elágazás). Például:

Annak ellenőrzése, hogy be van-e állítva egy bizonyos zászló (történt valamilyen esemény):

if (RegX & (1<< Flag) ) // ha a RegX regiszter jelzője be van állítva
{
// csinálj valamit
}

Várakozás egy művelet (esemény) befejezésére:

while(!(RegX & (1<

A zászlók lekérdezése meglehetősen erőforrás-igényes feladat, mind a programméret, mind a program sebessége szempontjából. Mivel az AVR mikrokontrollerek összes jelzőszáma meglehetősen nagy (előny), a processzor és az eszköz közötti kommunikáció megvalósítása zászlók lekérdezésével az írott program hatékonyságának (kódsebességének / kódméretének) csökkenéséhez vezet, ráadásul a program nagyon zavaróvá válik, ami hozzájárul olyan hibák megjelenéséhez, amelyeket még a kód részletes hibakeresése esetén is nehéz észlelni.

Az AVR mikrokontrollerek programjainak hatékonyságának növelése, valamint a programok létrehozásának és hibakeresésének megkönnyítése érdekében a fejlesztők minden perifériás eszközt „megszakítási forrásokkal” láttak el ( Források megszakítása), egyes eszközöknek több megszakítási forrása is lehet.

Megszakítási források felhasználásával valósul meg szinkronizálási mechanizmus, a processzor és a periféria között, vagyis a processzor csak akkor kezdi meg az adatok fogadását, lekérdezési zászlókat és egyéb műveleteket a perifériás eszközön, ha az eszköz készen áll erre (jelzi az adatfeldolgozás befejezését, hibát jelez adatkezelés, a nyilvántartás üres, stb.) stb.), „megszakítási kérelem” generálásával ( Megszakítási kérés), valamely jelző értékétől függően (eszköz/funkció/eseményállapot).

A szakirodalomban nagyon gyakran az események teljes láncolatát, a „megszakításkéréstől” (IRQ) a „megszakítási szolgáltatási eljárásig” (ISR) megszakításként rövidítik. Megszakítás).

Mi az a megszakítás?


A megszakítás egy jel, amely értesíti a processzort egy esemény bekövetkezéséről. Ebben az esetben az aktuális parancssorozat végrehajtása felfüggesztésre kerül, és a vezérlés átkerül az ennek az eseménynek megfelelő megszakításkezelési eljárásra, amely után a kódvégrehajtás pontosan attól a ponttól folytatódik, ahol megszakadt (vezérlés visszatérése). (Wiki)

A rutin megszakítása Az (Interrupt Service Routine) nem más, mint egy függvény/alprogram, amelyet egy bizonyos esemény bekövetkeztekor végre kell hajtani. Az „eljárás” szót fogjuk használni, hogy hangsúlyozzuk az összes többi funkciótól való különbségét.

A fő különbség az eljárás és az egyszerű függvények között az, hogy a szokásos „visszatérés a funkcióból” (RET összeállítási parancs) helyett a „return from interrupt”-t (RETI összeállító parancs) használja. RETurn from Interrupt".

Az AVR megszakítás tulajdonságai:

  • Az AVR mikrovezérlők részét képező minden perifériaeszköz rendelkezik legalább egy megszakítási forrással. Mindezen megszakítások között szerepelnie kell a reset megszakításnak is, amelynek célja eltér az összes többitől.
  • Minden megszakításnak van egy szigorúan hozzárendelt vektora (hivatkozás), amely az Interrupt szolgáltatási rutinra mutat. Minden megszakítási vektor a programmemória legelején található, és együtt alkotják a „megszakítási vektorok táblázatát”.
  • Minden megszakításhoz egy adott „Megszakítás engedélyezése” bit tartozik. Mértékegység. Továbbá, függetlenül attól, hogy engedélyezett-e bizonyos megszakításokat vagy sem, a mikrokontroller nem kezdi el feldolgozni ezeket a megszakításokat, amíg a SREG állapotregiszterben a „Global Interrupt Enable bit”-be nem ír egy logikait. Továbbá, hogy letiltson minden megszakítást (an határozatlan idő), egy napló nullát kell írni az általános megszakítás engedélyezési bitre.

A Reset megszakítás, ellentétben az összes többivel, nem tiltható le. Az ilyen megszakításokat nem maszkolható megszakításoknak is nevezik.

  • Minden megszakításnak szigorúan meghatározott prioritása van. Egy megszakítás prioritása a „megszakítási vektortáblázatban” elfoglalt helyétől függ. Minél kisebb a vektorszám a táblában, annál magasabb a megszakítás prioritása, vagyis a reset megszakítás a legmagasabb a táblában, és ennek megfelelően a memóriaprogramokban Az INT0 külső megszakítás a Reset megszakítást követően a „megszakítási vektortáblázatban” alacsonyabb prioritású, mint a Reset, de magasabb, mint az összes többi megszakításé, stb.

A megszakítási vektor táblázat a Reset vektor kivételével a Flash memória Boot szakaszának elejére mozgatható az IVSEL bit beállításával a GICR regiszterben. A visszaállítási vektor a Flash memória Boot szakaszának elejére is áthelyezhető a biztosíték bit - BOOTRST programozásával.



1. ábra ATmega16 megszakítási vektor táblázat

Megszakítási rutin prototípus


Ahhoz, hogy egy függvényt megszakításkezelési rutinként deklarálhasson, bizonyos prototípus-szabályozási szabályokat kell követnie, hogy a fordító/linker helyesen azonosíthassa és társítsa a szükséges megszakítást a kezelési rutinjával.

Először is, a szolgáltatásmegszakítási rutin semmit nem fogadhat el argumentumként (void), és nem adhat vissza semmit (void). Ennek oka az a tény, hogy az AVR-ben minden megszakítás aszinkron, így nem tudni, hol szakad meg a program végrehajtása, kitől kapjuk és kinek adjuk vissza az értéket, valamint hogy minimalizáljuk a belépési időt, ill. kilépés a megszakításból.

void isr(void)

Másodszor, a függvény prototípusa előtt jeleznie kell, hogy ez egy megszakításkezelési eljárás. Mint ismeretes, a C nyelvben csak a fő függvényben használt kód kerül végrehajtásra. Mivel a főfüggvényben lévő megszakításkezelési eljárást sehol nem alkalmazzák, hogy a fordító ne „dobja ki” szükségtelenül, az eljárás prototípusa előtt jelezni kell, hogy ez a funkció egy megszakításkezelő eljárás.

A megszakításkezelési eljárás prototípusa AVR Studio környezetben

#beleértve

ISR (XXX_vect)
{

}

Az AVR Stúdióban (AVR GCC) minden megszakítási rutin egy ISR makró definícióval kezdődik, amelyet a következő konstrukció követ zárójelben:

XXX_vect

ahol az „XXX” a megszakítási vektor neve egy adott AVR mikrokontrollerhez tartozó összes vektornév megtalálható a mikrokontroller adatlapjának „megszakítási vektortáblázatában” vagy a fejlécfájljában. Például az ATmega16 mikrokontroller „megszakítási vektortáblázata” az 1. ábrán látható, ahol a Forrás oszlopban az összes megszakítási vektor neve megtalálható :\Program Files\Atmel\AVR Tools\AVR Toolchain\avr\include\avr\iom16.h), lásd a 2. ábrát. Nincs más dolgunk, mint megkeresni a táblázatban a kívánt vektor nevét, és hozzáadni az utótagot. „_vect”-et.


2. ábra ATmega16 fejlécfájl az AVR Studio számára

Például írjunk egy megszakításkezelési eljárást egy bájt USART-n keresztüli fogadására (USART, Rx Complete):

ISR (USART_RXC_vect)
{
// Megszakításkezelő törzse
}

Mellesleg: mielőtt bármilyen megszakítást használna az AVR Stúdióban, vegye fel a projektbe az io.h és interrupt.h fejléc fájlokat:

#beleértve
#beleértve

Az AVR Studio (AVR GCC) megszakításkezelőiről a Bevezetés az avr-libc megszakításkezelésébe részben olvashat.

Megszakításkezelési eljárás prototípusa ImageCraft környezetben

#pragma interrupt_handler : iv_XXX
üres< handler_name>(üres)
{
// Megszakításkezelő törzse
}

Az ImageCraft környezetben a prototípus megszakítási rutin így néz ki:

üres< handler_name>(üres)

Ahol , ez az a név, amit a megszakításkezelőnek szeretne adni. A megszakításkezelési eljárások deklarálásának egyik követelménye, hogy a függvény prototípusa előtt jelezni kell, hogy az egy megszakításkezelő. Ez egy pragma direktíva segítségével történik interrupt_handler :

#pragma interrupt_handler : iv_XXX

Ahol ez a megszakításkezelőként használt függvény neve, az „iv_XXX” konstrukció pedig a megszakítási vektor neve (XXX) az „iv_” előtaggal, mint az AVR Studio esetében, minden vektornév egy adott AVR mikrokontroller esetében az adott mikrokontroller adatlapjának „megszakítási vektortáblázatában” vagy a fejlécfájljában található (lásd 3. ábra).


3. ábra ATmega16 fejlécfájl az ImageCraft IDE-hez

Például egy bájt USART-n (USART, Rx Complete) keresztül történő fogadására vonatkozó megszakítás kezelésének eljárása az ImageCraft környezetben így fog kinézni:

#pragma interrupt_handler usart_rxc_isr: iv_USART_RXC
void usart_rxc_isr(void)
{
// Megszakításkezelő törzse
}

Az ImageCraft IDE megszakításkezelési eljárásairól a fejlesztői környezet Súgó->AVR programozása->Megszakításkezelők menüjében talál további információt.

Néha, ha több megszakításkezelőnek ugyanazt a dolgot kell megtennie, akkor a programmemória megtakarítása érdekében több megszakítási vektort irányíthat ugyanahhoz a megszakítási rutinhoz.

Az AVR Stúdióban így néz ki:

ISR (INT0_vect)
{
// Csinálj valamit
}
ISR(INT1_vect, ISR_ALIASOF(INT0_vect) );

Először egy adott vektor megszakítási feldolgozási eljárása következik, ebben az esetben az INT0. Az összes többi eljárás bármely megszakításkezelőre hivatkozhat a konstrukciót használó:

ISR (YYY_vect, ISR_ALIASOF(XXX_vect) ) ;

ahol YYY annak a megszakítási vektornak a neve, amely a XXX vektor korábban deklarált megszakításkezelőjére utal.

Az ImageCraftban így néz ki:

#pragma interrupt_handler : iv_XXX : iv_ÉÉÉ
üres< handler_name>(üres)
{
// Megszakításkezelő törzse
}

#pragma interrupt_handler : iv_XXX
#pragma interrupt_handler : iv_ÉÉÉ
üres< handler_name>(üres)
{
// Megszakításkezelő törzse
}

ahol az XXX és YYY vektorok ugyanarra a megszakításkezelőre utalnak .

Hogyan működik a megszakítás az AVR mikrokontrollerekben?

1. Tegyük fel, hogy " megszakítási kérés”(IRQ).

Apropó: ha több megszakítás-feldolgozási kérés történik egyidejűleg, akkor a legmagasabb prioritású megszakítás kerül feldolgozásra először, az összes többi kérés a magas prioritású megszakítás befejezése után kerül feldolgozásra.

2. Vizsgálat.

Ha ennek a megszakításnak az engedélyezési bitje be van állítva (Interrupt enable bit), és a processzorállapot-regiszter (SREG) I-bitje (általános megszakítás engedélyezési bit) be van állítva, akkor a processzor megkezdi a megszakítás szolgáltatási rutin előkészítését, míg az általános megszakítás engedélyezése bit (az SREG regiszter I-bitje) alaphelyzetbe áll, ezzel letiltva az összes többi megszakítást. Ez azért történik, hogy semmilyen más esemény ne szakítsa meg az aktuális megszakítás feldolgozását.

Apropó: ha a megszakításkezelési eljárásban az I-bitet napló állapotba állítod. egység, akkor bármely aktivált megszakítás megszakíthatja az aktuális megszakítás feldolgozását. Az ilyen megszakításokat beágyazott megszakításoknak nevezzük.

3. Készítmény.

A processzor befejezi az aktuális összeállítási utasítás végrehajtását, majd elhelyezi a következő utasítás címét a veremben (PC->STACK). Ezt követően a processzor ellenőrzi, hogy melyik megszakítási forrás küldött „megszakítási kérelmet” (IRQ), majd ennek a forrásnak (hivatkozásnak) a vektortáblából (amely minden megszakítási forráshoz szilárdan hozzá van rendelve) vektorával továbblép a megszakítási feldolgozási eljárás (JMP utasítás) Ez minden, a processzor legalább 4 órajelet tölt (a kérés megjelenésének pillanatától és az aktuális utasítás végrehajtásának időtartamától függően). más gyártók mikrokontrollerei.

Apropó: ha a mikrokontroller alvó üzemmódban IRQ történik, akkor az IRQ-ra adott válaszidő további négy órajellel növekszik, plusz a SUT1 és SUT0 (Start-Up Time) biztosítékbitekben tárolt idő.

A verem egy memóriaterület, amelyet a CPU a szubrutinok visszatérési címeinek tárolására és visszaállítására használ.
Szinte minden AVR mikrokontrollerben van egy köteg az SRAM-ban. Az aktuális elem (a verem teteje) megcímzéséhez az SP (Stack Pointer) veremmutatót használjuk. Ez egy egybájtos RVV SPL a legfeljebb 256 bájt adatmemória kapacitású modellekhez, vagy egy kétbájtos SPH:SPL (SPH - magas bájt, SPL - alacsony bájt).

Amikor a mikroprocesszor találkozik az rcall/call/ecall/icall/eicall hívási utasítások egyikével, a programmemóriában a következő szó címét a hardver a verembe másolja. Amikor a ret parancs kilép az alprogramból, a visszatérési cím visszaáll a veremből a programszámlálóba. A 128 és 256 kwords programmemória kapacitású modellekben a számítógép verembe mentéséhez 3 bájtra, az összes többi esetében 2 bájtra lesz szükség. Az egyes bájtok tárolásakor az SP tartalma eggyel csökken, visszaállításkor pedig ennek megfelelően nő.

9. ábra Verem helye az adatmemóriában

A programozónak önállóan kell meghatároznia a verem helyét a program elején. A maximális mélysége szempontjából a verem tetejét az SRAM legvégére kell helyezni, ahogy az a 9. ábrán látható:

Tartalmazza az "m8def.inc" ldi temp,low(RAMEND) ;set SP = RAMEND out SPL,temp ;az ATmega8 SP = 0x045F ldi temp,high(RAMEND) out SPH,temp

A szabványos m8def.inc fejlécfájlból származó RAMEND konstans az utolsó SRAM cella címét tartalmazza.

Az alkalmazásprogram változói az RBB és az aktuális SP pozíció közötti SRAM-címtartományban találhatók. Ezért nagyon fontos először megbecsülni a maximális veremméretet (veremmélységet). Előfordulhat, hogy a verem teteje túl magasra emelkedik, és elkezdi "felülírni" a felhasználói adatokat, és ez az egyik legnehezebben észlelhető hiba!

Az AVR-veremnek a visszatérési címek tárolása mellett van egy másik nagyon fontos célja is. Lehetővé teszi bármilyen adat mentését a kifejezetten erre a célra kialakított push Rr (betöltés a verembe) és pop Rd (rakás a veremből) parancsokkal. Minden alkalommal, amikor egy push Rr végrehajtódik, az Rr tartalma a verembe másolódik, majd az SP eggyel csökken. A pop Rr végrehajtásakor az SP által mutatott veremcella tartalma visszaáll Rr-re, és magának az SP-nek az értéke növekszik. Ez a fajta verem egy Last In First Out szervezettel rendelkezik: az utolsó push parancs által elmentett regiszter az első pop paranccsal visszaáll:

; SP Stack szint a push parancs után R16 ;mentés R16 0x045F R16 ? ? push R17 ;mentse R17 0x045E R16 R17 ? push R18 ;mentés R18 0x045D R16 R17 R18 ̣̣̣̣̣̣̣ pop R18 ;restore R18 0x045D R16 R17 ? pop R17 ;restore R17 0x045E R16 ? ? pop R16 ;restore R16 0x045F ? ? ?

A verem segítségével nagyon egyszerűen cserélheti a regiszterek tartalmát:

; Csere R16<->R17 SP Stack szint a push parancs után R16 ;mentés R16 0x045F R16 ? push R17 ;mentés R17 0x045E R16 R17 pop R16 ;visszaállítás R16 0x045E R16 ? pop R17 ;restore R17 0x045F ? ?


10. ábra Példa a verem működésére

A 10. ábra egy kis kódrészletet mutat be, amely lépésről lépésre mutatja be a verem megváltoztatásának folyamatát a kapcsoló szubrutinba való belépéskor és kilépéskor, valamint az R17 regiszter mentését és visszaállítását. Ez egy tipikus példa, ahol push/pop utasításokra lehet szükség. A toggle szubrutin RON R17-et használ az igényeihez, de ugyanez a regiszter használható a főprogram során is. Ezért az adatok sérülésének elkerülése érdekében az R17 a módosítás előtt betöltődik a verembe, és visszaállítja onnan a ret parancs előtt.


Beszéljünk a megszakításokról. A megszakítás szó önmagáért beszél, a folyamat egy ideig leáll, hogy további műveleteket hajtson végre. A megszakítások lehetnek külsőek vagy belsőek. Hadd mondjak egy egyszerű példát, amit a barátomtól hallottam...

Mosogatni készült a konyhában, izgatottan kezdett, feltűrte az ingujját... de az edények zsírosak lettek, és kénytelen volt megállni, hogy az egyik polcról zsíros edények mosogatására alkalmas tisztítószert keressen. a konyhai egységet, ami után ismét folytatta a feladatát. De valamikor megcsörrent a telefon, és ismét szünetet tartott a munkájában, felvette a telefont, anyósa felhívott, és azt mondta, hogy látogatóba jön, ezért el kell mennie a boltba élelmiszert vásárolni, mielőtt ő megérkezett. Elmentem a boltba és csak utána mosogattam.

Ez a példa kétféle megszakítást mutat be, az első a fő munka végrehajtásához kapcsolódik - mosogatószer keresése zsíros edényekhez - belső megszakítás, a második - telefonhívás - külső megszakítás.
Egy mikrokontrollerben a külső megszakítások más forrásból érkező jelek miatt, a belső megszakítások a mikrokontrollerbe épített eszközök miatt keletkeznek. Miért olyan vonzóak a megszakítások?
Az első az, hogy leállíthatjuk a fő folyamatot valamilyen más funkció végrehajtásához, majd folytathatjuk ezt a folyamatot.
A második, és valószínűleg sok esetben a fő, az összes funkció végrehajtási folyamatának felgyorsítása, a belső kiegészítő eszközök miatt. Térjünk vissza példánkhoz. Mondjuk a barátom akkor kezdett el mosogatni, amikor a felesége már hazaért. A zsíros edényeket látva megkéri, hogy keressen mosogatószert, és amíg ő mos, már hozza is neki ezt a folyadékot. De ekkor csörgött a telefon, a feleségem felvette a telefont, beszélt az anyjával és elment a boltba. Együtt minden nagyon gyorsan megtörtént!
És még könnyebb elakadni – i.e. nincs fő program.
A barátom a kanapén ül, és nem csinál semmit, a házvezetőnő látva a koszos edényeket, elmondja neki, és miután megkapta az engedélyt, mosogatni kezd. Amikor csörög a telefon, azt mondja a feleségének, hogy vegye fel a telefont, a feleség beszél telefonon, és a beszélgetés a boltba megy... Szépség! Ebben az esetben több I/O eszköz működik egyszerre a mikrokontrollerben (a modern mikrokontrollerekben elég sok lehet), és a teljes processzorteljesítmény sokszorosára nő, de az eszközökből érkező megszakításokat egymás után (nem egyszerre) dolgozzák fel. ), a prioritástól függően (példánkban a feleségnek magasabb prioritása van, mint a házvezetőnőnek).

Számos regiszter felelős a megszakítások kezeléséért
SREG – állapotregiszter(Államok). Megnézzük a bemeneti-kimeneti eszközök táblázatát. A SREG regiszter hetedik bitje az az I (megszakítás) jelző, amelyet globális megszakítás engedélyezési jelzőnek neveznek. Ha a jelzőt kihagyjuk (a hetedik bit nulla), akkor minden megszakítás le van tiltva. Ha a zászló fel van emelve (I-re állítva 1), engedélyezzük a megszakításokat.

Az I zászló beállítása és alaphelyzetbe állítása a következő parancsokkal történik:
SEI - engedélyezze a megszakításokat
CLI - megszakítások letiltása
Hogy melyik megszakítás működjön, azt a - megszakító maszkok.
A megszakítási maszkok a következők:
TIMSK,..,..,.. – időzítők és egyéb beépített eszközök által okozott megszakítások kezelése.
GIMSK (GIKR a Mega családban) - minden külső megszakítás kezelése.
A megszakítási maszkok a megszakításjelzőktől függenek:
TIFR és GIFR(nem tévesztendő össze a globális megszakítás engedélyezése jelzővel).

Megszakítási végrehajtási sorrend:
A mikrokontroller bekapcsolásakor az összes megszakítási jelző 0-ra áll vissza. A megszakítások engedélyezéséhez a programnak a SREG regiszter I jelzőjét 1-re kell állítania. Ezt követően regisztrálja a maszk regisztereket helyi megszakításokkal (azok a megszakítások, amelyekre szükségünk van) .
Amikor megszakítási kérés (jel) érkezik, felemeli a megszakítási jelzőt (még ha a megszakítás le van tiltva is, a beágyazott megszakítások és a különböző megszakítások közötti prioritás megszervezése érdekében). Ha a megszakítások nincsenek letiltva, a vezérlő kapcsolatba lép a megfelelővel (Megszakítási vektorok) - megszakítási vektor, az aktuális program szüneteltetése.
Megszakítási vektor egy fix vonal a programterületen, ahová a program megy, ha megszakítás történik.
A megszakítási vektorok teljes listáját hívjuk megszakítási vektor táblázat, amely található a programkód elején.
Tehát a megszakítási vektor elérésekor a SREG regiszter I jelzője és a megszakítást okozó jelző 0-ra áll vissza, letiltva a többi megszakítást. Ha a megszakítás végrehajtása közben más megszakítási kérések is előfordulnak, akkor az adott megszakításokhoz tartozó jelzők továbbra is fel vannak emelve. Az aktuális megszakítás befejeztével a SREG regiszter I jelzője felemelkedik, lehetővé téve a következő megszakítás végrehajtását. Ha több kérés érkezik és azok jelzőjeit felemeljük, akkor először az a megszakítás hajtódik végre, amelynek vektora kisebb a táblázatban szereplő címen, közelebb a memória elejéhez. A második következik, és így tovább. Ezenkívül a programozó ún. beágyazott megszakítást is tud szervezni, amikor a megszakító program végrehajtása során újabb megszakítás következik be. Ezután az aktuális megszakítás végrehajtása leáll, és egy újat hajtanak végre, amely után a leállított megszakítás végrehajtása folytatódik.

Példaként adjuk meg az ATtiny2313 megszakítási vektorainak táblázatát

Az Atmega16 megszakítási vektortáblázata a következő:

Összehasonlítva a táblázatok egyáltalán nem egyeznek.
Az ATtiny családban a megszakítási vektorsor 16 bitet foglal el, a Mega családban pedig 32 bitet (ügyeljen a megszakítási vektorok címére; hadd emlékeztessem Önöket arra, hogy a programterületen lévő címsort egy 16-os jelöli -bit szó).

Az ATtiny2313 programkódja így nézhet ki:
.cseg .org 0 rjmp visszaállítása rjmp INT_0 rjmp INT_1 rjmp Timer1_capt1 rjmp Timer1_comp1 rjmp Timer1_OVF1 rjmp Timer0_OVF0 rjmp UART_RX rjmp UART_UDRE rjmp UART_TX rjmp_time PCINT_COMPcomp_rjmp ANA jmp Timer0_compB rjmp USI_START rjmp USI_OVERFLOW rjmp EE_READY rjmp WDT_ OVERFLOW

Mint látható, a megszakítási vektor relatív ugrást hoz létre a megszakítási program címkéihez. Az alábbi táblázat a lehetőségeket mutatja; 1. Amikor nincs fennakadás; 2, 3. külső megszakítással az INT_1 bemeneten.
Ha a címkék „üresek” (nincs program a címke alatt), akkor nem történik semmi, és a program egymás után „átfut” a fennmaradó címkéken, és biztonságosan eléri a parancsot. RETI- Interrupt return – kilépés a megszakításkezelőből a táblázat első oszlopában látható módon.

A megszakító program végrehajtásához, például az INT_1 bemeneten, el kell távolítania az INT_1: címkét a listáról. Ez vázlatosan látható a táblázat második oszlopában.
A programozónak azonban kényelmetlen minden megszakítást és külön címkét írni nekik, különösen a legújabb modellekben, ahol a tábla meglehetősen nagy, könnyebb azonnal beírni a RETI parancsot a megszakítási vektor sorába megszakítás nem használatos. Ekkor a program a táblázat harmadik oszlopában látható módon fog kinézni.

Az AVR vezérlők típustól függően 1-8 bemenettel rendelkezhetnek külső megszakítások.
Tekintsük a külső megszakításkezelő rendszert. Ebből a célból az I/O regiszterek következő kombinációi állnak rendelkezésre a modelltől függően (lásd a megfelelő adatlapot):
- GIMSK, EIFR, PCMSK, MCUCR;
- GIKR, GIFR, MCUCR;
- EIMSK, EICR, EIFR;
GIMSK, GIKR, EIMSK - megszakítási maszkok,
EIFR, PCMSK, GIFR, EIFR – megszakítási jelzők
Engedélyre vagy tiltásra külső megszakítások vezérlőregiszterek célja: GIMSK (Általános megszakítási maszk regiszter) (Tiny), GICR- (Általános megszakításvezérlő regiszter) (Mega), MCUCR – (MCU vezérlőregiszter)




EIFR- External Interrupt Flag Register: 1 - engedélyezve, 0 - letiltva. Minden bit (jelző) lehetővé teszi, hogy a megfelelő láb megszakítási forrásként működjön.

GIMSK regiszter vezérlőbitek:
7. bit – INT1: External Interrupt Request 1 Enable – INT1 megszakítás engedélyezése bit: 1 – engedélyezve, 0 – letiltva. A megszakítás akkor is létrejön, ha az INT1 láb kimenetként van konfigurálva. Az INT1 bit megszakításra van beállítva az EIFR jelzőregiszterben. Az INT1 érintkező szinkronizálva van az óragenerátorral.

6. bit – INT0: Külső megszakítási kérelem 0 Engedélyezve – megszakítás engedélyezése bit INT0: 1 – engedélyezve, 0 – tiltva. A megszakítás akkor is létrejön, ha az INT0 láb kimenetként van konfigurálva. Az INT0 bit megszakításra van beállítva az EIFR jelzőregiszterben. Az INT10 érintkező szinkronizálva van az óragenerátorral.

5. bit – PCIE: Pin Change Interrupt Enable – megszakítás engedélyező bit a PCINT0…7 lábakon: 1 – engedélyezve, 0 – letiltva. A PCINT0...7 érintkezők bármelyikének módosítása megszakítást generál. A PCINT0...7 lábak megszakításra külön-külön, a PCMSK jelzőregiszter bitjeivel vannak beállítva.

PCMSK- Pin Change Mask Registrer - zászlólajstrom PCMSK: 1 - engedélyezett, 0 - letiltott. Minden bit (jelző) lehetővé teszi, hogy a megfelelő láb megszakítási forrásként működjön. A PCINT0...7 lábak nincsenek szinkronban az óragenerátorral, pl. megszakítás történik, ha változás történik bármelyik érintkezőn.

Mega8

és a megfelelő zászlóregiszter


7. bit

6. bit – INT0: Külső megszakítási kérelem 0 Engedélyezve – megszakítás engedélyezése bit INT0: 1 – engedélyezve, 0 – tiltva. A megszakítás akkor is létrejön, ha az INT0 láb kimenetként van konfigurálva. Az INT0 bit megszakításra van beállítva a GIFR flags regiszterben



GIFR – General Interrupt Flag Register: 1 – engedélyezve, 0 – letiltva. Minden bit (jelző) lehetővé teszi, hogy a megfelelő láb megszakítási forrásként működjön.

GICR regiszter vezérlőbitek:
7. bit– : 1. külső megszakítási kérelem engedélyezése – megszakítás engedélyezése bit INT1: 1 – engedélyezett, 0 – tiltott. A megszakítás akkor is létrejön, ha az INT1 láb kimenetként van konfigurálva. Az INT1 bit megszakításra van beállítva a GIFR flags regiszterben

6. bit – INT0: Külső megszakítási kérelem 0 engedélyezése - megszakítás engedélyezése bit INT0: 1 – engedélyezett, 0 – tiltott. A megszakítás akkor is létrejön, ha az INT0 láb kimenetként van konfigurálva. Az INT0 bit megszakításra van beállítva a GIFR flags regiszterben

5. bit – INT2: 2. külső megszakítási kérelem engedélyezése - megszakítás engedélyezése bit INT2: 1 – engedélyezett, 0 – tiltott. A megszakítás akkor is létrejön, ha az INT2 láb kimenetként van konfigurálva. Az INT2 bit megszakításra van beállítva a GIFR flags regiszterben

Az INT0 és INT1 bemenetek funkcióit minden vezérlőben az MCUCR regiszter alacsony rendű bitjei vezérlik.

MCUCR – MCU vezérlőregiszter
Vezérlő bitek:
1., 0. bitek – ISC01, ISC00 (Megszakításérzékelő vezérlés 0, 1. bit és 0. bit) – ezeknek a biteknek az állapota határozza meg az eseményt az INT0 lábon, amely INT0 megszakítást generál:
ISC01=0, ISC00=0 – logikai nulla szint;
ISC01=0, ISC00=1 – a logikai állapot bármilyen változása;
ISC01=1, ISC00=0 – lefutó élen;
ISC01=1, ISC00=1 – felfutó élen.

3., 2. bit – ISC11, ISC10 (Interrupt Sense Control 1, 1. bit és 0. bit) – ezeknek a biteknek az állapota határozza meg a jelszintet az INT1 lábon, amely az INT1 megszakítást generálja:
ISC11=0, ISC10=0 – logikai nulla szint;
ISC11=0, ISC10=1 – a logikai állapot bármilyen változása;
ISC11=1, ISC10=0 – lefutó élen;
ISC11=1, ISC10=1 – felfutó élen.

Nos, úgy tűnik, minimum beszéltünk a külső megszakításokról.
Nyilvánvaló, hogy a megszakítások működéséhez ezeket megfelelően regisztrálni kell.
Adjuk hozzá a megszakítás inicializálását az INT1-en, amely a jel felfutó élén lévő apróra indult:

Ldi r16.0x80 ; írja be az r16-ba a 0b10000000 ldi r17.0x0C számot; írja be az r17-be a 0b00001100 számot az MCUCR,r17-be; a megszakítás a felfutó élen jön létre ISC11=1, ISC10=1 out GIMSK,r16 ; állítsa a maszkot INT0 sei-re
Egyébként a tiny2313-on generálhatsz megszakítást bármely PCINT0…7 tűn, Mega 48-as sorozatig ezek a funkciók nem érhetők el...
Vannak olyan műveletek, amelyek során olyan megszakítások fordulhatnak elő, amelyek a program összeomlását okozhatják. Ilyenkor a művelet megkezdése előtt CLI-t írunk, utána pedig SEI-t. Az ilyen műveleteket - atom.
Kívánatos, hogy a megszakító programok kompaktak legyenek és maximális sebességgel fussanak, mert minden megszakítás célja egy esemény rögzítése. Ha különböző okok miatt a program lassan fut, akkor elég az eseményt rögzíteni és egy kicsit később feldolgozni.

Annak érdekében, hogy a bemutatott anyagot ne zsúfolják el felesleges információkkal, javaslom az olvasóknak, hogy használjanak adatlapokat, és ha minden nem világos, akkor gyakrabban tegyenek fel kérdéseket a fórumokon.
Ezután részletesen megvizsgáljuk a beépített időzítőkön alapuló belső megszakításokat. olvasók. A szavazásban való részvételhez regisztráljon és jelentkezzen be az oldalra felhasználónevével és jelszavával.

A megszakítási rendszerek minden vezérlőrendszer fontos részét képezik.

Az, hogy a mikroprocesszoros rendszer mennyire hatékonyan látja el feladatait, nagyban függ a működésétől. Az MK-51 megszakítási rendszer általános felépítését az ábra mutatja. 14.3.

Az MK-51 család mikrovezérlői öt megszakítási forrást támogatnak:

* két külső megszakítás, amely az INT0 és INT1 bemeneteken keresztül érkezik (P3 portvonalak: P3.2 és P3.3);

* két megszakítás a T/C0 és T/C1 időzítők/számlálók által;

* soros port megszakítás.

A megszakítási kérelmeket a mikrokontroller speciális funkcióregiszterei rögzítik: az IE0, IE1, TF0, TF1 jelzők az INT0, INT1, T/C0 és T/C1 megszakítási kérelmeket a TCON vezérlőregiszterben (14.4. táblázat), valamint az RI jelzőket tartalmazzák. és a TI megszakítást kér a soros portról - az SCON regiszterben a soros port vezérlésére.

14.4. táblázat. TCON regisztrációs formátum

0 IT0 A megszakítás típusának beállítása INT0

1 IE0 megszakítási kérelem jelző INT0

2 IT1 A megszakítás típusának beállítása INT1

3 IE1 megszakításkérés jelző INT1

4 TR0 Időzítő/számláló engedélyezése 0

5 TF0 túlcsordulás jelző (megszakítási kérelem) időzítő/számláló 0

6 TR1 Időzítő/számláló engedélyezése 1

7 Az 1. időzítő/számláló TF1 túlcsordulási jelzője (megszakítási kérés).

A TF0 és TF1 jelzőket hardver állítja be, amikor a megfelelő időzítő/számláló túlcsordul (pontosabban, amikor a T/Cx „minden egyes” állapotból „minden nulla” állapotba vált át).

Az IE0 és IE1 jelzőket hardver állítja be a külső IT0 és IT1 megszakításokból. Külső kérés hatására a jelző beáll, ha a megfelelő bemenet jelszintje alacsony, vagy amikor ez a jel magasról alacsonyra vált (az MK külső órafrekvenciájának felét meg nem haladó frekvenciával).

A kérés típusát a szoftver a TCON vezérlőregiszterben az IT0 és IT1 bitek beállításával konfigurálja. Az ITx = 0 beállítása a megszakítási rendszert úgy konfigurálja, hogy alacsony jelszintet kérjen, ITx = 1 - a megszakítást úgy állítja be, hogy alacsony jelszintet kérjen.

A TI és RI jelzőket a soros interfész hardvere állítja be az adás vagy a vétel befejezése után.

Az összes megadott megszakítási kérés jelzője programozottan elérhető beállításhoz és visszaállításhoz. A megszakításkérés jelzőjének szoftverben történő beállítása ugyanazt a választ eredményezi a mikrokontrollertől, mint a hardverben.

A TF0 és TF1 jelzőket hardver alaphelyzetbe állítja, amikor a vezérlést átadják a megfelelő megszakítási rutinnak.

Az IEx jelzők alaphelyzetbe állítása hardverben történik a megszakítás kiszolgálása során, ha a megszakítást úgy konfigurálták, hogy érzékelje az INTx jel esését. Ha a megszakítás úgy van konfigurálva, hogy érzékelje a kérésjel szintjét, akkor az IEx jelző visszaállítását a megszakítási szolgáltatási programnak kell végrehajtania, a megszakítási forrásra hatva a kérés eltávolítása érdekében.

A TI és RI jelzők csak szoftverrel állíthatók vissza.

Minden megszakítástípus külön-külön engedélyezhető vagy letiltható az IE megszakítás engedélyező regiszter megfelelő bitjeinek beállításával vagy törlésével. Ez a regiszter egy általános tiltóbitet is tartalmaz minden megszakításhoz. Az IE regiszter formátumát a táblázat tartalmazza. 14.5.

14.5. táblázat. IE regiszterbitek hozzárendelése

Pozíció regisztrálása

Kis mnemonika

Funkció

Az összes forrásból származó megszakítások letiltása

Nem használt

Nem használt

Megszakítás letiltása innen soros port

T/C1 időzítő/számláló megszakítás letiltása

Az INT1 külső forrásból származó megszakítás letiltása

Az időzítő/számláló T/C0 megszakításának letiltása

Az INT0 külső forrásból származó megszakítás letiltása

Mindegyik megszakítástípushoz programozottan hozzárendelhető a két lehetséges prioritás egyike: 0 – legalacsonyabb vagy 1 – legmagasabb.

A prioritások konfigurálása az IP megszakítási prioritási regiszter megfelelő bitjének beállításával vagy törlésével történik. Ennek a regiszternek a formátuma a táblázatban található. 14.6.

Ha egyidejűleg megszakítási kérelmek érkeznek különböző prioritású forrásokból, akkor először a magasabb prioritású forrásból származó kérés kerül feldolgozásra.

Több, azonos prioritású megszakítási kérelem egyidejű vétele esetén azok feldolgozási sorrendjét a mikrokontroller hardvere határozza meg, és szoftverrel nem módosítható. Ez a sorrend megfelel a lekérdezési megszakításkérés jelzők sorrendjének, amely így néz ki:

IT0 -> TF0 -> IT1 -> TF1 -> (RI, TI)

14.6. táblázat. IP-regiszter bit hozzárendelései

Regisztrálás pozíciója Bit mnemonikus funkció

7 - Nem használt

6 - Nem használt

5 - Nem használt

4 PS Soros port megszakítási prioritás

3 PT1 időzítő/számláló megszakítás prioritása T/C1

2 PX1 Megszakítási prioritás külső forrásból INT1

1 PT0 időzítő/számláló megszakítás prioritása T/C0

0 PX0 Megszakítási prioritás külső forrásból INT0

A hardverrel megvalósított megszakításkezelő hívás a következő műveletekből áll:

* a programszámláló értékének mentése a verembe;

Az egyes megszakítási források megszakításkezelő belépési pontjai hardverben vannak rögzítve. Értékeiket a táblázat tartalmazza. 14.7.

14.7. táblázat. A megszakításkezelők belépési pontjainak címei

Forrás megszakítása

A megszakításkezelők belépési pontjainak címei

Külső megszakítás( ITO)

Időzítő számláló (TFO)

Külső megszakítás (IT1)

Időzítő számláló (TF1)

Soros port (R1 vagy T1)

A megszakításkezelő első parancsának a megadott címen kell lennie. Általában egy ilyen parancs egy olyan parancs, amely feltétel nélkül ugorhat arra a helyre a programban, ahol a kezelő ténylegesen található.

A megszakításkezelő rutinra való váltáskor automatikusan, az IE regiszter állapotától függetlenül minden olyan megszakítás letiltásra kerül, amelynek prioritási szintje megegyezik a kiszolgált megszakítás prioritási szintjével - vagyis az azonos prioritású beágyazott megszakítások letiltásra kerülnek. . Így egy alacsony prioritású megszakítás (amelynek az IP-regiszter megfelelő bitje "0") megszakítható egy magas prioritású megszakítással (amelynek az IP-regiszter megfelelő bitjében "1" van), de nem alacsony prioritású. A magas prioritású megszakítás kiszolgálását nem szakíthatja meg más forrás.

A megszakításkezelőből való visszatérés a RETI utasítással történik, amely visszaállítja a veremből a megszakításkezelő hívásakor ott tárolt PC-programszámláló értékét és a megszakítási prioritás logikáját.

Mire használhatók a külső megszakítások?

A megszakítás olyan esemény, amellyel a fő programkód (például a fő funkció) végrehajtása megszakad, és a vezérlés átkerül a funkció megszakításkezelőjéhez. Ennek megfelelően a külső megszakítások bizonyos külső események, amelyek megszakítják a fő programkód végrehajtását.

A külső megszakítások lehetővé teszik, hogy gyors, garantált választ kapjon a külső eseményekre. Ezért a külső megszakítások legelterjedtebb alkalmazása az impulzusszámlálók megvalósítása, a frekvencia vagy impulzus időtartamának mérése, az uart, egyvezetékes, i2c, spi szoftveres megvalósítása, valamint a külső perifériákról érkező jelek feldolgozása.

A külső megszakítások működési elve az AVR-ben

Annak érdekében, hogy a mikrokontroller megismerje a külső eseményeket, diszkrét bemeneteket használnak INT0 INT1 stb. A diszkrét azt jelenti, hogy logikai szintekkel működnek: 0 és 1.
A 0 a bemeneten nincs feszültség
1 — feszültség jelenléte a bemeneten, amely megegyezik a mikrokontroller tápfeszültségével.

A külső megszakítások két típusra oszthatók:

  • külső megszakítások szint szerint
  • külső él megszakítja

Külső megszakítások szint szerint

A külső megszakítás trigger konfigurálható alacsonyra vagy magasra. Például, ha a megszakítás logikai alacsonyra van állítva, akkor ez akkor következik be, amikor az INT bemenet feszültsége nulla. Ha a megszakítás magas szintre van állítva, akkor ez akkor következik be, ha a bemenet logikai 1.
Amikor szintalapú megszakításokkal dolgozik, ne feledje, hogy amíg az INT bemenet megfelelő szinttel rendelkezik, a megszakítás folyamatosan történik. Azok. ha egy megszakítás történik például alacsony szinten, és a program feldolgozza, de ha a megszakításkezelőből kilépve a bemenet alacsony marad, akkor a megszakítás újra tüzel, és a megszakításkezelő újra meghívásra kerül, és ez addig folytatódik, amíg a bemeneti magas szint meg nem jelenik. Ennek elkerülése érdekében le kell tiltania az ilyen típusú megszakításokat a kezelőben, vagy át kell állítania egy másik szintre.

Külső él megszakítás

Egy felfutó él megszakítása, vagy ahogy néha mondják, egy emelkedő jel akkor következik be, amikor az INT bemenet jelszintje 0-ról 1-re változik. Lefutó él megszakítása (eső jel) akkor következik be, amikor a jelszint a Az INT bemenet 1-ről 0-ra változik.
A megszakítást úgy is konfigurálhatjuk, hogy az INT bemeneten bekövetkező bármilyen változásra reagáljon, pl. a bevezető és a lefutó él mentén egyaránt előfordul.

Külső megszakítások konfigurálása az AVR-ben

Külső megszakítások be avr atmega8 bitekkel konfigurálva ISCxx Regisztráció MCUCR .

Az INT0 külső megszakítás triggerelési feltételének függése az avr atmega8 MCUCR regiszterének ISC0x bitjétől

Külső megszakításhoz INT1 , a beállítás ugyanúgy történik, csak biteket használnak ISC11 ISC10 .

Példaavr atmega8 külső megszakítási beállításai:

//visszaállítja az összes ISCxx bitet MCUCR &= ~( (1 <<ISC11) | (1<<ISC10) | (1<< ISC01) | (1<< ISC00) ) MCUCR |= (1 <<ISC01) | (1 << ISC00);

//minden bit alaphelyzetbe állítása ISCxx MCUCR &= ~((1<

Külső megszakítások engedélyezése az avr atmegában

A külső megszakítások működéséhez engedélyezni kell azokat a regiszter megfelelő bitjeinek 1-re állításával GICR .

Bit INT0 felelős a külső megszakítások engedélyezéséért/letiltásáért INT0 , és kicsit INT1 , illetve külső megszakításra INT1 .

Ezenkívül be kell állítani a globális megszakítás engedélyezése jelzőt.

Példakód az INT0 külső megszakítás engedélyezésére az avr atmega8 számára:

//külső megszakítás engedélyezése INT0 GICR |= (1<

Példa külső megszakítások használatára az AVR atmegában

Példaként adok egy pulzusszámláló programot. A program megszámolja az INT0 bemeneten lévő impulzusok számát, és másodpercenként egyszer megjeleníti a számlálás eredményét az uartban.

#beleértve #beleértve #beleértve #beleértve //számláló változó volatile unsigned long int0_cnt = 0 ; //az INT0 külső megszakítás beállítása void int0_init( void ) ( //beállítása az INT0 aktiválására egy felfutó élen MCUCR |= (1 << ISC01) | (1 << ISC00); //külső megszakítás engedélyezése INT0 GICR |= (1 <<INT0) ; ) //függvény külső megszakításkezelő INT0 ISR( INT0_vect ) ( int0_cnt++; ) //UART beállítás void uart_init( void ) ( //cseresebesség beállítása UBRRH = 0; UBRRL = 3; //115200 kvarcnál 7,3728 MHz //8 adatbit, 1 stopbit, nincs paritás UCSRC = ( 1 << URSEL ) | ( 1 << UCSZ1 ) | ( 1 << UCSZ0 ) ; //adatfogadás és adatátvitel engedélyezése UCSRB = ( 1 << TXEN ) | ( 1 << RXEN ) ; ) //byte átvitel UART-on keresztül int uart_putc( char c, FILE * fájl ) ( //várja meg az előző bájt átvitelének végét while ( ( UCSRA & ( 1 << UDRE ) ) == 0 ) ; UDR = c; return 0 ; ) FÁJL uart_stream = FDEV_SETUP_STREAM(uart_putc, NULL, _FDEV_SETUP_WRITE ) ; int main( ) ( //ideiglenes változó aláírás nélküli hosszú tmp; stdout = & uart_stream; int0_init() ; uart_init() ; sei(); míg (1) ( //megszakítások letiltása a számláló értékének másolása közben cli() ; tmp = int0_cnt; //megszakítások engedélyezése sei(); printf("int0_cnt = %lu \r\n", tmp ) ; //szünet 1 másodperc _delay_ms( 1000 ) ; ) return 0 ; )

#beleértve #beleértve #beleértve #beleértve //számláló változó volatile unsigned long int0_cnt = 0; //az INT0 külső megszakítás beállítása void int0_init(void) ( //Az INT0 konfigurálása felfutó élen történő aktiváláshoz MCUCR |= (1<