kategória | ||||||||||
| ||||||||||
| ||
|
||||||||||
Matlab - Megszakítások
Tartalom
Bevezetö a megszakításokba
A PIC megszakításai általában
A Timer megszakítás
Kezdjük az alapvetö kérdéssel: mi is az a megszakítás? Nevéböl adódóan az az esemény, amikor a programunkat megszakítjuk. A megszakítás során a programunk nem áll le végleg, mindössze a futása felfüggesztödik, és egy különálló rutin kapja meg a vezérlést. Ha a rutin lefutott, akkor a program folytatódhat. Egyelöre semmi különlegeset nem látunk, hiszen ugyanezt a hatást váltja ki a CALL utasítás is. Azonban a megszakítás akármikor bekövetkezhet, a program bármely soránál. Ennek megfelelöen a megszakítási rutinnak (vagyis annak a rutinnak, ami a megszakításkor meghívódik) észrevétlennek kell lennie, nehogy megbolygassa a program müködését. Ez annyit jelent, hogy meghíváskor el kell mentenie minden kritikus regiszternek az értékét (akkumulátor, STATUS, stb.), visszatérés elött pedig ezeket vissza kell állítania. Na de miért is jó nekünk egy olyan rutin, ami akármikor meghívódhat? Nos, az "akármikor" egész pontosan bizonyos eseményeket jelöl. Úgy, mint:
- Megváltozott a PORTB tartalma
- Lefutott az idözítö
- Az EEPROM írás befejezödö 858g61i tt.
Most már az "akármikort" definiáltuk, csak még mindig nem tudjuk, hogy mire is jó ez az egész. Vegyük példának a PC-k müködését, és azon belül is az egereket, melyek szintén megszakításokkal dolgoznak. Amikor megmozdítjuk az egeret, az egér jelzi a számítógép felé, hogy megszakítást kér. A processzor ilyenkor felfüggeszti az éppen futó programot és meghívja az egér megszakításához tartozó rutint. Ez nem más, mint az egér meghajtóprogramja (drivere). Ez a rutin ekkor kiolvassa az egérböl az elmozdulás adatait, letárolja a számítógép memóriájába további felhasználás céljára (pl. kurzor mozgatása), majd vissza is adja a vezérlést a megszakított programnak. Bár meg lehetne oldani a problémát a megszakítás teljes kikerülésével is, vagyis hogy bizonyos idöközönként megnézzük az egeret, hogy van-e valami mondanivalója. Ez azonban sokkal nagyobb terhelést jelentene a processzor számára, mintha nem is kellene foglalkoznia az egérrel, csak ha az szól. A PIC esetében is hasonlóan fontos szerepe van a megszakításnak. Minthogy a PORTB változása kiválthat megszakítást, az elözö számban készített programunkat megírhatjuk akár úgy is, hogy a gombokra oda sem figyelünk, csak a léptetésre. Majd a gombok lenyomására magától meghívódik a gombkiértékelö rutin. Sajnos azonban a PORTA-ra nincs megszakítási lehetöség, ezért a gombokat majd fizikailag át kell helyeznünk a PORTB-re.
Eddig programjainkat csak úgy "beleömlesztettük" a memóriába, a 0-dik memóriacímtöl kezdve. (Ezt jelezte az ORG 0 sor) PIC-eknél azonban követelmény, hogy a megszakítási rutin mindig a 4-es memóriacímtöl kezdödjön, mert bármi is okozta a megszakítást, ez a cím hívódik meg. Ez annyit jelent, hogy az ORG direktívával jeleznünk kell majd, hogy a program ne a 0-dik címtöl induljon, valamint a megszakítási rutin a 4. memóriacímtöl kezdödjön. Továbbá fontos dolog még, hogy a megszakításokat be kell kapcsolni, különben az egyes események nem fogják meghívni a megszakítási rutint. Megszakításoknál az egyik legfontosabb regiszter, amit használni fogunk, az INTCON. Részletes leírást az INTCON-ról a dokumentáció 17-ik oldalán találunk. Hasonlóan a STATUS-hoz, itt is mindegyik bit valamilyen speciális szereppel rendelkezik, és saját nevük van. Egyik ilyen bit a GIE (General Interrupt Enable), mely a megszakítások "fökapcsolója". Ha ez nulla, akkor semmiféle megszakítás nem müködhet a PIC-ben. A továbbiakban két megszakítást veszünk nagyító alá, a TIMER0-t és az RB-t. Mindkét megszakítás az INTCON regiszterben a T0IF, ill. az RBIF 1-re állításával jelzi, ha megszakítást generált. Ezzel tudjuk kitalálni, hogy tulajdonképpen melyik megszakítási esemény (RB vagy TIMER0) miatt került a vezérlés a 4. címre. Na de vegyük konkrétan magukat a megszakítási eseményeket, amiket a PIC16F84 ismer. Ezzel valamivel tisztábban láthatjuk majd a dolgokat.
A timer (idözítö) egy beépített áramköre a PIC-nek. Feladata, hogy egy TMR0 nevü regisztert bizonyos idöközönként növeljen eggyel. Mindezt persze a programunkkal párhuzamosan. Ha a TMR0 regiszter túllépte a maximálisan elérhetö 255-öt, (vagyis túlcsordul), akkor keletkezik egy TIMER megszakítás. A PIC16F84 mindössze egy TIMER-rel rendelkezik (amit TIMER0-nak hívnak), fejlettebb PIC-eknek több is van, melyek egymással párhuzamosan dolgozhatnak.
Hogy mire jó a TIMER megszakítás, azt talán már ki is találhattuk: ezzel gyakorlatilag írhatunk olyan rutinokat, amelyek megadott idöközönként mindenképpen meghívódnak, a program aktuális állásától függetlenül. Ez akkor tud hasznos lenni, ha pl. a programunk - egyéb funkciók mellett - a pontos idöt is méri. Ilyenkor a föprogram csinálhat bármit, a századmásodperceket tároló regisztert léptetö rutin mindenképpen meghívódik század-másodpercenként.
Mi most azonban nem órát írunk, (próbapanelünk alkalmatlan rá) hanem a bevitelkezeléskor tárgyalt programot írjuk meg újra, majd hozzáadunk egy idözítöt. Írjuk meg a következö programot:
LIST P=16F84 #INCLUDE "P16F84.INC"
__CONFIG _XT_OSC&_CP_OFF&_WDT_OFF
ORG 0
START BSF STATUS,RP0 ;BANK1
MOVLW B'00011111'
MOVWF TRISA
MOVLW B'00000000'
MOVWF TRISB
BCF STATUS,RP0 ;BANK0
CLRF PORTB
VISSZA BTFSS PORTA,0 ;
Bekapcs teszt
BSF PORTB,0
BTFSS PORTA,1
BSF PORTB,1
BTFSC PORTA,0 ;
Kikapcs teszt
BCF PORTB,0
BTFSC PORTA,1
BCF PORTB,1
GOTO VISSZA
END
Ez a program, mint láthatjuk, nem ugyanaz, mint amit a bevitelkezelésnél vettünk, (bár ugyanazt csinálja) ezért egy kissé átbeszéljük, hogy hogy is müködik. A VISSZA címkéig a már megszokott port ki- és bemenet beállítás található, azzal a plusz utasítással, hogy PORTB-t teljesen lenullázzuk. (CLRF PORTB) A VISSZA címkétöl indul aztán a tényleges program. A "Bekapcs teszt" és a "Kikapcs teszt" négy-négy utasítása ellenörzi a gombok lenyomott ill. felengedett állapotát. A lenyomás tesztnél BTFSS PORTA,x utasításokkal megnézzük az x-edik gomb állapotát, a BSF PORTB,x-szel pedig PORTB egy adott bitjét (azaz az x-edik LED-et) 1-re állítjuk. A felengedés tesztnél pedig pont fordítva, vagyis BCF PORTB,x utasításokkal kioltjuk azt a LED-et, amelyiknek a gombja fel van engedve. A müködés pontosabb megértése végett érdemes ezt a programot az MPLAB debug üzemmódjában végignézni, egy stimulus fájllal. (Úgy, ahogyan a második számban vettük)
Programunkat égessük is be a PIC-be és nézzük meg, hogy mit csinál! Semmi extra nem lesz benne, a gombokkal ki- és bekapcsolhatjuk az elsö két LED-et. Most a programot viszont kiegészítjük egy TIMER megszakítással. Például csinálja programunk mostantól azt, hogy a gombok figyelése és a LED-ek gyújtogatása mellett az 5. LED-et folyamatosan villogtatja. Jó pár sort szúrunk majd a programba, kezdjünk is neki! Amint fent is említettük, a megszakításoknak mindig a 4. címtöl kell kezdödniük. A PIC a föprogram futtatását azonban mindig a 0. címtöl kezdi. Minthogy a 0-3-ig terjedö címtartomány édeskevés ahhoz, hogy bármi értelmes programot odategyünk, (hisz ez mindössze 4 sort jelent) a programot egy GOTO utasítással kell kezdeni, ami átugorja a megszakítás területét, így a megszakítás után lesz böven "helyünk" a föprogramnak. Ennek megfelelöen szúrjunk be egy GOTO START utasítást az ORG 0 direktíva után:
LIST P=16F84 #INCLUDE "P16F84.INC"
__CONFIG _XT_OSC&_CP_OFF&_WDT_OFF
ORG 0
GOTO START
START BSF STATUS,RP0 ;BANK1
Most már elkezdhetjük írni a 4. címtöl a megszakítási rutint. Szúrjuk be a következö rutint a GOTO START utasítás és maga a föprogram START címkéje közé!
ORG 0
GOTO START
ORG 4
BCF INTCON,T0IF
MOVLW b'00010000'
XORWF PORTB,F
RETFIE
START BSF STATUS,RP0 ;BANK1
Lássuk sorban, hogy mit is csináltunk! Elöször is az ORG 4 direktívával megjelöltük, hogy a rutinnak a 4. címre kell kerülnie. A TIMER0 megszakítás esetén nem csak simán a 4. címre kerül a vezérlés, hanem az INTCON T0IF jelzöbitje 1-re vált. A PIC ezzel jelzi, hogy a TIMER0 miatt keletkezett megszakítás és nem pl. a PORTB miatt. Elöször is egy BCF INTCON,T0IF-fel töröljük a T0IF értékét, mert sajnos ezt a PIC magától nem teszi meg, viszont ha 1-en hagyjuk, akkor megdöglik a program. A következö két utasítással (MOVLW és XORWF) egy kizáró vagy müveletet végzünk PORTB tartalma és b'00010000' között. Ezzel azt érjük el, hogy az ötödik LED az éppen aktuális állapotának az ellenkezöjét veszi fel. (Magyarul kigyullad, ha még nem égett, ill. kialszik, ha már égett) Emlékeztetöül: Ha egy bit és 0 között kizáró vagy müveletet végzünk (szakbarbárosabban: egy bitet 0-val "XOR-olunk"), akkor azzal a bittel nem történik semmi. Azonban ha 1-gyel XOR-oljuk, akkor az adott bit invertálódik. Vagyis:
Elsö bit |
Második bit |
Eredmény |
0 |
0 |
0 |
0 |
1 |
1 |
1 |
0 |
1 |
1 |
1 |
0 |
Ezért van, hogy a b'00010000' érték csak az ötödik LED-et fogja invertálni (PORTB 5. bitjét). Miután invertáltuk a bitet, vissza is térhetünk a megszakításból. Ellentétben a hagyományos, CALL utasítással hívott rutinokkal, a megszakítási rutinoknak mindig a RETFIE utasítással kell visszatérniük, és nem RETURN-nel!
Programunkban már szinte minden benne van, mindössze el kell helyeznünk a megszakítások bekapcsolását végzö utasításokat a föprogram elején. (Ahol a többi dolgokat is beállítjuk.)
START BSF STATUS,RP0 ;BANK1
MOVLW B'00011111'
MOVWF TRISA
MOVLW B'00000000'
MOVWF TRISB
MOVLW B'10000111'
MOVWF OPTION_REG
BCF STATUS,RP0 ;BANK0
CLRF PORTB
BSF INTCON,GIE
BSF INTCON,T0IE
VISSZA BTFSS PORTA,0 ; Bekapcs teszt
Na ezt a négy új sort bizony elég szépen belekevertük a programba! Az OPTION_REG, - melyröl eddig még nem volt szó - a BANK1-ben helyezkedik el, így még a BANK0-ra való váltás elött kell értéket adni neki. (A regiszterek egy részét csak a BANK0-ban, másik részét a BANK1-ben, harmadik részét pedig mindkettöben elérhetjük. Hogy éppen melyik BANK tartományt érhetjük el, azt a STATUS regiszter RP0 bitjén adhatjuk meg. Az egyes regiszterek hollétéröl a dokumentum 13. oldalán találunk egy táblázatot.) Az OPTION_REG regiszter amolyan kiegészítö beállításokat tartalmaz a megszakításokhoz. Az RBPU bitet (lásd képen) majd az RB megszakításnál vesszük, (addig is elég annyit tudni, hogy 1-re kell mindig tenni) minket most elsösorban a PS2-PS0 bitek érdekelnek. Ezek az ún. "elöosztó" bitek, amik megmondják, hogy hány órajel-ciklusonként növekedjen egyet a TMR0 regiszter. (Emlékeztetöül: a TMR0 regiszter magától növekszik, és ha túllép a 255-ön, akkor keletkezik TIMER megszakítás) Minél gyakrabban növekszik a TMR0 értéke, annál gyorsabban következik be a megszakítás. A három elöosztó bittel egy 0-7-ig terjedö bináris számot tudunk kirakni, ahol '000'-tól lesz a leggyorsabb a számlálás (minden második ciklusnál növekszik a TMR0), '111'-töl pedig a leglassabb (256 ciklus után növekszik egyet.)
A teljesség kedvéért az alábbi léptetési értékeket adhatjuk meg az idözítönek az OPTION_REG-en keresztül:
OPTION_REG elsö három bitje |
Késleltetés mértéke (Hány órajel-ciklus után növekedjen egyet a TMR0) |
000 |
2 |
001 |
4 |
010 |
8 |
011 |
16 |
100 |
32 |
101 |
64 |
110 |
128 |
111 |
256 |
Fordítsuk le a programot és égessük be a PIC-be, hogy lássuk az eredményt. Aztán kielemezzük részletesebben a látottakat. A kész programot letölthetjük innen is. Amint áramot adunk a PIC-nek, láthatjuk, hogy az ötödik LED veszettül villódzik. Ha pedig nyomogatjuk a gombokat, akkor azt is láthatjuk, hogy a programunk eredeti funkcióját is megtartotta, vagyis kigyújtja az elsö két LED-et a gombok állásának megfelelöen. Bizony, ez már valódi multitaszk program, vagyis egyszerre több funkció lát el párhuzamosan. (Villogtat, és a gombokat is kezeli.)
Most térjünk vissza az MPLAB-hoz és nézzük meg, hogy mi is történik ilyenkor a programban! A Watch ablakba vegyük fel a TMR0 regisztert! (Ha nem lenne nyitva a Watch, akkor a Window/Watch window/New watch window menüponttal vehetünk elö egyet. Regisztert a Watch ablak kijelölésével és az INS billentyü megnyomásával adhatunk hozzá.) Továbbá, ha nem lenne a Watch ablakban, akkor tegyük még hozzá a PORTA és PORTB regisztereket is, esetleg még a W-t. Minthogy programunk éppen a leglassabb idözítésre van beállítva, (256 ciklusonként növeli a TMR0-t) az OPTION_REG-et beállító MOVLW utasítás értékét állítsuk B'10000111'-röl B'10000000'-ra! (Vagyis a leggyorsabbra, különben megöregszünk, mire egyet lép a TMR0 a szimulációban.) Fordítsuk újra a programot, és kezdhetjük a vizsgálatot! Nyomjunk F6-ot a program emulált indításához. Mint láthatjuk, a program a GOTO START sorral indul, vagyis a 0. címtöl. Következönek helytelenül a megszakítási rutinra futna rá, ezért kell elugrani. Lépjünk tovább F8-cal a VISSZA címkéhez! Mint láthatjuk, lépkedés közben a TMR0 nem növekedett, mert a megszakítás még nincs bekapcsolva. Azonban a VISSZA-tól kezdve növekedni fog, mert a BSF utasítások engedélyezik az általános és a TIMER megszakítást az INTCON regiszterben. Most ha nyomogatjuk az F8-at, akkor azt láthatjuk, hogy a program csak a billentyütesztelö részben fut, ki se lép belöle. Azonban a TMR0 majd minden lépésnél növekszik egyet. Futtassuk a programot addig, amíg TMR0 el nem éri a 255-öt! (Vagy a H'FF'-et! Lenyomva is tarthatjuk az F8-at, így igen gyorsan lépkedhetünk, csak aztán a végsö érték közelében lassítsunk!) Amint TMR0 túllépi a 255-öt, láthatjuk, hogy bármely sornál is állt a program, a vezérlés a 4. címen levö megszakítási rutinra kerül. Futtassuk végig a megszakítási rutint! Láthatjuk, ahogyan a XORWF utasítás átbillenti PORTB 5. bitjét, majd a RETFIE utasítás hatására visszakerül a vezérlés arra a pontra, ahol a gombtesztelö megszakadt. Közben a számlálás is elölröl kezdödik. Tehát nem kellett bonyolult feltételeket és speciális DELAY rutinokat írnunk arra, hogy a gombok tesztelése mellett az 5. LED villogjon, a két feladat párhuzamosan tudott futni, bele sem nyúltunk a gombtesztelö programrészbe!
Most lássunk egy példát arra, hogy hogyan lehet a megszakítási rutin és a föprogram között összhangot teremteni! Írjuk meg az elözö számban levö gombokra váltó futófényt TIMER megszakítással! A föprogram mindössze a gombokra figyeljen, és ennek megfelelöen állítsa be az IRANY regiszter értékét 1-re vagy 0-ra! A megszakítás feladata legyen, hogy IRANY értékének megfelelöen a fényt jobbra vagy balra lépteti! Kezdjük az elején, az IRANY regiszter deklarációjával és a megszakítási rutinnal!
LIST P=16F84 #INCLUDE "P16F84.INC"
__CONFIG _XT_OSC&_CP_OFF&_WDT_OFF
CBLOCK 0X0C
IRANY
ENDC
ORG 0
GOTO START
ORG 4
BCF INTCON,T0IF
BTFSC IRANY,0
GOTO BALRA
JOBBRA RRF PORTB,F
RETFIE
BALRA RLF PORTB,F
RETFIE
Nagyon magyaráznivaló nincs ebben. A követelménynek megfelelöen töröljük az INTCON T0IF bitjét, majd az IRANY regiszter elsö bitjének megfelelöen (minthogy ténylegesen csak az elsö bit fog változni az IRANY regiszterben) az RRF vagy RLF forgatóutasításra ugrunk, aztán visszatérünk a rutinból. Folytassuk a rutint a föprogram inicializációs részével!
START BSF STATUS,RP0 ;BANK1
MOVLW B'00011111'
MOVWF TRISA
MOVLW B'00000000'
MOVWF TRISB
MOVLW B'10000111'
MOVWF OPTION_REG
BCF STATUS,RP0 ;BANK0
CLRF IRANY
CLRC
MOVLW 01
MOVWF PORTB
BSF INTCON,GIE
BSF INTCON,T0IE
A szokásos TRISA és TRISB regiszterek után beállítjuk az OPTION_REG-et, hogy a leglassabb legyen a számlálás. Töröljük az IRANY értékét (mégis csak így a leggyorsabb kezdöértéket adni neki), valamint a C jelzöbitet is. (Lásd elözö számban, hogy miért) PORTB-n beállítjuk, hogy az egyik LED világítson, a késöbbiekben majd ezt kell csak jobbra-balra tologatni. Miután mindezzel megvagyunk, bekapcsolhatjuk a megszakítások fökapcsolóját jelképezö GIE bitet és a TIMER0-t jelképezö T0IE-t. Most jöhet maga a föprogram, mely mindössze csak az IRANY értékét változtatja, a két gomb állásának megfelelöen.
VISSZA: MOVFW IRANY
BTFSS PORTA,0
MOVLW 00
BTFSS PORTA,1
MOVLW 01
MOVWF IRANY
GOTO VISSZA
END
Ez a rutin gyakorlatilag ugyanaz, mint az elözö számban lévö program tesztelö rutinja, annyi a különbség, hogy IRANY beállítása után nem ugrik a jobbra, ill. balra forgató rutinra, hanem elölröl kezdi a tesztelést. A kiértékelés és forgatás már a megszakítás dolga, itt nem kell vele foglalkoznunk! Készen is vagyunk, égessük be a PIC-be, majd futtassuk a programot! (Illetve letölthetjük elöször innen
Programunk pont úgy müködik, akár az elözö számban levö változat: ha az egyik gombot nyomjuk, akkor balra fut a fény, ha a másik gombot, akkor meg jobbra. Csak a fene vigye el, miért ilyen gyors? Különösen, hogy a Timer0-t a leglassabbra állítottuk az OPTION_REG regiszterben! A Timer0 állításával nem tudunk ezen segíteni, mert valóban ez a leglassabb fokozata az idözítönek. Azonban egy kis trükkel megoldhatjuk a problémát! Késleltetést nem tanácsos használni a megszakításon belül, mert kiszámíthatatlan következményekkel járhat. Illetve nagyon is kiszámíthatókkal: ugyanis a TIMER0 következö megszakításakor még mindig nem léptünk ki a megszakítási rutinból. Ugyan a rutin lefutásának idejére le vannak tiltva a megszakítások, de nem tudjuk pontosan idözíteni, hogy a rutin kilépése után mikor lesz a következö TIMER0 megszakítás. (No meg a megszakítások lebénítása egyébként sem szerencsés, az RB és a TIMER megszakítások kombinálásánál majd látni fogjuk.) A megoldás sokkal egyszerübb: mindössze úgy kell megírnunk a megszakítási rutint, hogy az elejére teszünk egy számlálót. A számláló egy adott regiszter tartalmát csökkenti eggyel, és ha a számláló értéke 0, akkor engedi lefutni a rutint, egyébként meg azonnal visszatér. Tehát ha pl. 9 az említett regiszter értéke, akkor minden 9-dik megszakításnál fut csak le a megszakítási rutin, a többinél pedig visszatér. Egészítsük ki rutinunkat ezzel a számlálós megoldással!
Elsönek vegyük fel a számláláshoz szükséges új regisztert (IDOZIT), valamint egy WSAVE nevü regisztert!
LIST P=16F84 #INCLUDE "P16F84.INC"
__CONFIG _XT_OSC&_CP_OFF&_WDT_OFF
CBLOCK 0X0C
IDOZIT
WSAVE
IRANY
ENDC
ORG 0
GOTO START
A WSAVE regiszterre mindjárt láthatjuk, hogy miért van szükség. Nézzük, hogy hogyan kell módosítani a megszakítási rutint!
ORG 4
BCF INTCON,T0IF
DECFSZ IDOZIT ;COUNTER
RETFIE
MOVWF WSAVE
MOVLW 9
MOVWF IDOZIT ;COUNTER END
MOVFW WSAVE
BTFSC IRANY,0
GOTO BALRA
JOBBRA RRF PORTB,F
RETFIE
BALRA RLF PORTB,F
RETFIE
Elöször ugye törölnünk kell T0IF-et. Utána egy DECFSZ utasítással csökkentjük a számlálónkat. Ha a számláló még nem nulla, akkor a RETFIE utasítással ki is lépünk a rutinból. Ha pedig nulla, akkor átugorja a RETFIE-t. Ezután az akkumulátort betöltjük a WSAVE regiszterbe. Mint fent említettük, a megszakítás bármikor meghívódhat, akár egy értékadás közepén is. Már pedig ha pl. egy MOVLW 01 - MOVWF PORTB páros közepén szakad meg a futás és a megszakítási rutin elállítja a W-t, akkor biztosra vehetjük, hogy nem 1 fog kerülni PORTB-be, amikor visszatér a föprogramra a futás. Az eddigi megszakításos példákban a nem használtuk egyszerre a föprogramban és a megszakításban is az akkumulátort, most viszont jelen van mindkettöben, tehát el kell mentenünk W értékét, hogy ne zavarja meg a föprogram futását. (Azért érdemes kipróbálnunk a programot úgy is, hogy nem mentjük el a W-t!) Az akkumulátor elmentése után már nyugodtan használhatjuk azt, így az IDOZIT regisztert újra feltölthetjük 9-cel a következö megszakítás számára. Minthogy többször nem fog kelleni az akkumulátor, vissza is tölthetjük az elmentett értéket a MOVFW WSAVE utasítással. Innentöl a megszakítási rutin a régi kerékvágás szerint folytatódik. Az inicializációs részhez még adjuk hozzá az IDOZIT regiszter kezdeti feltöltését!
....
MOVLW 01
MOVWF PORTB
MOVLW 9
MOVWF IDOZIT
BSF INTCON,GIE
BSF INTCON,T0IE
A kész program letölthetö innen. A programot PIC-be égetve láthatjuk, hogy a sebesség most már megfelelö. Mi több, a gombok sokkal érzékenyebben reagálnak, mint a nem megszakításos megoldásban. Ez azért van, mert a nem megszakításos változatban amíg késleltettünk, a PIC nem csinált semmit, még a gombokat sem nézte. A gombok állását csak akkor figyelte, ha éppen átváltott egyik LED-röl a másikra. Itt viszont kihasználjuk a várakozást, és közben is vizsgáljuk a gombokat.
A következö számban folytatjuk a megszakításokat, mégpedig a PORTB által kiváltott RB megszakítással.
Találat: 541