Sunteți pe pagina 1din 8

5.

ntreruperi
5.1 Introducere
Pentru a nelege mai bine facilitile oferite de ntreruperi vom ncepe acest capitol cu exemplul potaului. Potaul este nsrcinat cu distribuia scrisorilor la adresele destinatarilor. O serie de scrisori i colete sunt aduse personal la ua fiecruia, ns de cele mai multe ori, potaul va utiliza csua potal corespunztoare fiecrei locuine. Aceast metod este mult mai convenabil potaului pentru distribuia scrisorilor dect livrarea la u dac lum n considerare faptul c ntr-un singur cartier pot exista mai multe mii de locuine. n plus, cutia potal permite primirea scrisorilor chiar dac destinatarul nu este acas. Cu toate aceste faciliti oferite de existena cutiei potale, fiecare dintre noi trebuie s verifice la anumite intervale de timp dac s-a primit vre-o scrisoare. Aceast metod poate fi destul de frustrant dac se ateapt primirea unei scrisori importante, sau dac locuina respectivului se afl la un etaj nu tocmai aproape de cutia potal (e.g. etajul X). Viaa ar fi poate mult mai simpl dac potaul ne-ar putea anuna (e.g. prin interfon) c s-a primit o scrisoare. Lsnd deoparte potaul, s ne concentrm puin atenia ctre domeniul microcontrollerelor. Pn acum, ne-am obinuit c pentru a verifica starea unui periferic, trebuie testat n mod repetat perifericul respectiv (i.e. un anumit bit sau registru ntreg). Din aceast cauz, implementarea unor programe cu o complexitate ridicat poate fi problematic. Poate ar fi mult mai uor dac programul ar putea fi anunat de modificarea strii perifericului, ceea ce ar face ca ntre timp programul n cauz s se poat ocupa de o alt parte a problemei. Procesul de anunare se realizeaz prin ntreruperi. Mecanismul de suspendare a firului de execuie la apariia unui eveniment, se numete ntrerupere. Microcontrollere au deja implementat un mecanism de ntrerupere, prin care se permite execuia unei rutine de tratare a ntreruperii. Pentru tratarea ntreruperilor, n cazul seriei 16F exist un singur vector (0x04) iar n cazul seriei 18F exist doi vectori (0x08 i 0x18). Vectorul de ntrerupere reprezint de fapt o adres de program la care se face salt n momentul apariiei unei ntreruperi. Astfel, singurul vector pentru seria 16F este utilizat pentru deservirea tuturor ntreruperilor. Fa de aceast serie, microcontrollere din seria 18F permit setarea unei prioriti pentru fiecare ntrerupere, vectorul 0x08 avnd o prioritate mare (en. high), pe cnd vectorul 0x18 are o prioritate mic (en. low). n continuare vom vorbi despre configurarea i utilizarea ntreruperilor valabile doar pentru seria 18F. Aplicarea acestor concepte se va face similar n cazul celorlalte serii.

5.2 Activarea/dezactivarea ntreruperilor


Controlul operaiei fiecrei ntreruperi se realizeaz prin teri bii: Un bit de flag pentru a indica apariia unui eveniment ntrerupere; Un bit de activare care permite selectarea individual a surselor de ntrerupere utilizate; Un bit de prioritate.

Dac nu se utilizeaz prioriti, activarea/dezactivarea tuturor surselor de ntrerupere se realizeaz prin setarea/resetarea bitului GIE al registrului INTCON. Dac prioritile sunt utilizate, ntreruperile cu prioritatea high se pot activa independent de ntreruperile cu prioritatea low prin bitul GIEH al registrului INTCON. Aceeai afirmaie este valabil i n cazul prioritilor low, care se pot controla prin bitul GIEL al aceluiai registru. Aceast serie de microcontrollere permite dezactivarea utilizrii prioritilor prin resetarea bitului IPEN al registrului RCON. n cazul acesta, vectorul de ntrerupere va fi 0x08 pentru toate sursele. ntruct sursele de ntrerupere includ att perifericele microcontrollerelor ct i o serie de componente interne, seria 18F ofer posibilitatea activrii/dezactivrii ntreruperilor provenite de la periferice prin bitul PEIE al registrului INTCON (valabil doar n cazul n care prioritile nu sunt folosite). GIEH GIEL GIE PEIE IPEN 1/0 1/0 x x 1 x X 1/0 1/0 0 Tabelul 5.1. Biii care trebuie configurai dac se utilizeaz sau nu prioriti de ntrerupere

5.3 Configurarea ntreruperilor


De regul, paii care trebuie urmai pentru configurarea ntreruperilor sunt urmtorii: Activarea/Dezactivarea prioritilor (IPEN=1/0, registrul RCON); Activarea/Dezactivarea ntreruperilor provenite de la periferice (PEIE=1/0, registrul INTCON); Setarea prioritii pentru sursa de ntrerupere utilizat (dac IPEN=1); tergerea flag-ului corespunztor sursei de ntrerupere configurate; Activarea ntreruperii corespunztoare sursei configurate; Setarea bitului global de ntrerupere (GIE=1 sau GIEH/GIEL=1, registrul INTCON).

5.4 Tratarea ntreruperilor


n momentul apariiei unei ntreruperi, bitul global de configurare este resetat pentru a dezactiva alte ntreruperi. Dac IPEN=0 (i.e. nu exist mai multe prioriti de ntrerupere) acest bit este GIE. Dac se utilizeaz i prioriti de ntrerupere, acesta va fi GIEH sau GIEL. ntreruperile low pot fi ntrerupte de alte ntreruperi cu prioriti high, iar ntreruperile low nu sunt tratate atta timp ct exist ntreruperi high netratate. La apariia unei ntreruperi, adresa de revenire este pus pe stiv iar numrtorul de program este ncrcat cu 0x08 sau 0x18. n cazul n care se utilizeaz mai multe ntreruperi, sursa care a generat ntreruperea se poate determina prin testarea flagurilor. La revenirea din ntrerupere flag-ul corespunztor trebuie resetat. Revenirea dintr-o ntrerupere se realizeaz prin instruciunea RETFIE, care seteaz bitul GIE (GIEH sau GIEL n cazul n care se utilizeaz i prioriti).

Exemplul 5.1. Pentru a exemplifica modalitatea de configurare i implementare a ntreruperilor se va utiliza secvena urmtoare de program n cadrul cruia s-a considerat generarea unei ntreruperi corespunztoare Timerului 0 (avnd flag-ul T0IF):
#include P18F4455.INC ORG GOTO 0x00 MAIN

; 0x008 dac nu se utilizeaz BOOT-LOADER ; 0x808 dac se utilizeaz BOOT-LOADER ORG 0x008 ; Salt la rutina de tratare a ntreruperii GOTO Interrupt_Service_Routine ; Alte rutine ; Interrupt_Service_Routine: ; Se testeaz dac s-a generat ntreruperea care ; ne intereseaz BTFSS INTCON, TMR0IF RETFIE ; Alte instruciuni ; ; Resetarea flagului BCF INTCON, TMR0IF ; Revenire din rutin RETFIE MAIN: ; Resetare flag Timer 0 BCF INTCON, TMR0IF ; Dezactivarea prioritilor BCF RCON, IPEN ; Activare ntrerupere Timer 0 BSF INTCON, TMR0IE ; Activarea ntreruperilor BSF INTCON, GIE ; END

n secvena anterioar de program, s-a considerat o ntrerupere provenit de la un overflow al Timerului 0. Configurarea propriuzis a Timerului a fost lsat la latitudinea cititorului.

Exemplul 5.2. Secvena urmtoare de program exemplific utilizarea vectorilor de ntrerupere cu mai multe prioriti.
#include P18F4455.INC ORG GOTO 0x00 MAIN

; ISR-high ; 0x008 dac nu se utilizeaz BOOT-LOADER ; 0x808 dac se utilizeaz BOOT-LOADER ORG 0x08 ; Salt la rutina de tratare a ntreruperii GOTO Interrupt_Service_Routine_HIGH ; ISR-low ; 0x018 dac nu se utilizeaz BOOT-LOADER ; 0x818 dac se utilizeaz BOOT-LOADER ORG 0x018 ; Salt la rutina de tratare a ntreruperii GOTO Interrupt_Service_Routine_LOW Interrupt_Service_Routine_HIGH: ; RETFIE Interrupt_Service_Routine_LOW: ; RETFIE MAIN: ; END

5.5 Problem rezolvat


Utilizarea ntreruperilor poate simplifica foarte mult rezolvarea unei probleme numai n cazul n care exist o proiectare sistematic iniial care s pun n eviden paii care trebuie urmai de la stabilirea cerinelor i pn la implementare. Vom exemplifica o asemenea proiectare utiliznd problema urmtoare: S se modifice viteza de plpire alternativ a dou LED-uri legate pe PORTD<2:3> utiliznd un buton legat pe PORTD<0>. ntruct starea pinului la care este conectat butonul este 0 la apsare, se va considera modificarea vitezei de plpire la fiecare front descresctor detectat. Numrul de viteze maxime permise este 4. Dac se apas butonul conectat pe PORTD<1>, viteza se va reseta. Din specificaia informal a problemei se pot distinge urmtoarele cerine: 2 LED-uri legate pe PORTD<2:3>; 2 butoane legate pe PORTD<0:1>; Definirea a 4 viteze de plpire; Modificarea vitezei la fiecare apsare a butonului D0;

Resetarea vitezei la apsarea butonului D1. Din aceast specificaie va rezulta diagrama de stare din Figura 5.1.

Figura 5.1. Diagrama de stare pentru modificarea vitezei de plpire a LED-urilor utiliznd butoanele B0 i B1 n urmtorul pas trebuie stabilite temporizrile din fiecare stare. Dac ne reamintim puin problema prel-ului din capitolul alocat descrierii porturilor, identificm o temporizare unic pentru toate strile alocate eliminrii prel-ului butoanelor. Fa de aceast temporizare, viteza de plpire a LED-urilor difer ns de la o stare la alta, de unde va rezulta i o variaie a temporizrii utilizate. Eliminarea prel-ului se poate realiza prin utilizarea unei rutine de ntrziere bazate pe instruciuni sau Timere. Pe de alt parte, problema se simplific foarte mult dac temporizarea plpirii LED-urilor se implementeaz utiliznd un Timer i ntreruperi. Dac verificm posibilitile de configurare a Timerului 0, vom observa c prin simpla modificare a valorii divizorului se poate influena timpul de incrementare. Aceast observaie permite identificarea strilor n funcie de valoarea divizorului i trecerea de la o stare la alta prin simpla incrementare a divizorului. n Figura 5.2 se poate vedea diagrama de activitate a programului principal (a) i diagrama de activitate a rutinei de tratare a ntreruperii (b). Pentru implementarea plpirii LED-urilor se va utiliza Timer 0 pe 16 bii, a crui iniializare este realizat de secvena urmtoare de program:
BCF BCF BCF BCF BSF BCF BCF T0CON, T0CON, T0CON, T0CON, T0CON, T0CON, T0CON, TMR0ON T08BIT T0CS PSA T0PS2 T0PS1 T0PS0

Dup iniializarea porturilor i a vitezei iniiale (ceea ce reprezint cteva instruciuni MOVxx) configurarea ntreruperii generate de Timer 0 la resetarea acestuia:
BCF RCON, IPEN

BCF BCF BSF BSF

INTCON, INTCON, INTCON, INTCON,

PEIE TMR0IF TMR0IE GIE

a) b) Figura 5.2. Diagrama de activitate pentru: a) Funcionalitatea principal a modificrii vitezei; b) Rutina de ntrerupere pentru controlul strii LED-urilor Dup aceste configurri, Timer 0 trebuie pornit (BSF T0CON, TMR0ON), urmnd testarea butoanelor. Testarea butonului B1 este urmat, n cazul n care se detecteaz o apsare, de resetarea vitezei de plpire (MAIN_LOOP este o etichet indicnd nceputul buclei de test principale):

MAIN_LOOP: BTFSS CALL

PORTD, 1 Reset_Speed

unde Reset_Speed este rutina de resetare a vitezei de plpire, din care se apeleaz rutina de setarea a divizorului (i.e. rutina Set_Prescaler):
Reset_Speed: MOVLW B'00000100' MOVWF SPEED MOVFF SPEED, PORTB CALL Set_Prescaler RETURN

; afiarea vitezei curente ; setarea divizorului

Set_Prescaler: BCF T0CON, TMR0ON ; Oprirea Timerului BCF BCF BCF MOVF IORWF T0CON, T0PS2 T0CON, T0PS1 T0CON, T0PS0 SPEED, W T0CON, F ; Stergerea biilor divizorului

; Setarea noului divizor

BSF T0CON, TMR0ON ; Pornirea Timerului RETURN

Testarea apsrii butonului D0 trebuie s ia n calcul i prel-ul butonului, rezultnd urmtoarea secven de cod:
BTFSC GOTO CALL BTFSC GOTO PORTD, 0 MAIN_LOOP Delay_10_Millis PORTD, 0 MAIN_LOOP

Dup aceasta, urmeaz rutina de incrementare a vitezei:


Increment_Speed: INCF SPEED, F MOVFF SPEED, PORTB BTFSC CALL CALL RETURN SPEED, 3 Reset_Speed Set_Prescaler ; Se testeaz dac s-a atins viteza maxim

; Setarea noului divizor

ntr-un final, urmeaz secvena de cod prin care se ateapt eliberarea butonului D0:

WAIT_RELEASE_BUTTON: BTFSS PORTD, 0 GOTO WAIT_RELEASE_BUTTON GOTO MAIN_LOOP

n contextul secvenelor de program prezentate anterior, programul va intra n rutina de tratare a ntreruperii generate de Timer 0 la fiecare resetare a acestuia. Timpul n care are loc acest reset este dat de configuraia Timerului, care se schimb pe prcursul execuiei n funcie de viteza de lucru. Astfel, secvena de tratare a ntreruperii, este urmtoarea:
ORG GOTO ; S-a considerat existena unui ; BOOT-LOADER Interrupt_Service 0X808

Interrupt_Service: BTFSS INTCON, TMR0IF ; Se testeaz dac este o ntrerupere RETFIE ; generat de Timer 0 BTG BTG BCF RETFIE PORTD, 2 PORTD, 3 ; Se modific starea LED-urilor

INTCON, TMR0IF ; Se terge flag-ul Timerului

Problem. Se consider dou butoane PORTD<0:1>, dou LED-uri PORTD<2:3> i un ventilator legat pe PORTB<0>. S se realizeze diagrama de stare i de activitate pentru urmtoarele funcionaliti, dup care s se implementeze prin program: ntr-o prim faz, LED-urile plpie cu o modificare a strilor n fiecare secund; Dac se apas D0 (i.e. se detecteaz un front cztor), s se porneasc ventilatorul a crui rulare trebuie s dureze un timp de 5 secunde; Atta timp ct ventilatorul este pornit, LED-urile plpie la intervale de 100 milisecunde; Dac n timp ce ventilatorul este pornit se detecteaz o apsare a butonului D1, ventilatorul se va opri, iar LED-urile vor plpi n fiecare secund. NOT: Se recomand implementarea diferitelor viteze de plpire prin simpla modificare a divizorului timerului. Totodat, funcionalitatea de plpire se va separa de restul programului i se va implementa n rutina de ntrerupere (pentru resetarea Timerului 0).