|
Microcontroler - Intreruperi
Intreruperile sunt un mecanism a unui microcontroler ce ii permit sa raspunda la unele evenimente la momentul cand se intampla, indiferent de ce face atunci microcontrolerul. Aceasta este o parte foarte importanta, pentru ca permite conexiunea microcontrolerului cu lumea de afara. In general, fiecare intrerupere schimba debitul programului, il intrerupe si dupa executarea unui subprogram (rutine de intrerupere), continua din acelasi punct.
Registrul de
control al unei intreruperi se numeste INTCON si se gaseste
la adresa 0Bh. Rolul lui este de a permite sau interzice cererile de
intreruperi, si in caz ca nu sunt permise, inregistreaza
cererile de intrerupere singulare prin bitii lui.
Registru INTCON
bit 0 RBIF (RB Port Change Interrupt
Flag bit-bit Stegulet de Intrerupere a Schimbarii Portului RB) Bit ce
informeaza despre schimbarile de la pinii 4, 5, 6 si 7 ai
portului B.
1=cel putin un pin si-a schimbat starea
0=nu s-a intamplat nici o schimbare la vreun pin
bit 1 INTF (INT External Interrupt Flag bit-bit Stegulet de
Intrerupere Externa INT) A avut loc o intrerupere externa.
1=a avut loc o intrerupere
0=nu a avut loc o intrerupere
Daca s-a detectat un front crescator sau descrescator la pinul
RB0/INT, (ce este definit cu bitul INTEDG in registrul OPTION), bitul INTF este
setat. Bitul trebuie sa fie sters in subprogramul intrerupere pentru
a detecta urmatoarea intrerupere.
bit 2 T0IF (TMR0 Overflow Interrupt Flag bit-bit Stegulet
Depasire Intrerupere TMRO) Depasirea contorului TMRO.
1=contorul si-a schimbat starea de
0=depasirea nu a avut loc
Bitul trebuie sa fie sters in program pentru ca o intrerupere sa
fie detectata.
bit 3 RBIE (RB port change Interrupt Enable bit-bit Permite
Intreruperea schimbarii portului RB) Permite sa aiba loc
intreruperi la schimbarea starii pinilor 4, 5, 6, si 7 ai portului
B.
1=permite intreruperi la schimbarea starii
0=intreruperi interzise la schimbarea starii
Daca RBIE si RBIF au fost simultan setate, va avea loc o intrerupere.
bit 4 INTE (INT External Interrupt Enable bit-bit Permite
Intrerupere externa INT) Bit ce permite intreruperea externa de la
pinul RB0/INT.
1=intrerupere externa permisa
0=intrerupere externa interzisa
Daca INTE si INTF au fost setate simultan, va avea loc o intrerupere.
bit 5 T0IE (TMR0 Overflow Interrupt Enable bit-bit Permite
Depasire Intrerupere TMRO) Bit ce permite intreruperile in timpul
depasirii contorului TMRO.
1=intrerupere permisa
0=intrerupere interzisa
Daca T0IE si T0IF au fost simultan setate, va avea loc intreruperea.
Bit 6 EEIE (EEPROM Write Complete Interrupt Enable bit-bit Permite
Intrerupere Completa a Scrierii EEPROM) Bit ce permite o intrerupere la
sfarsitul unei rutine de scriere in EEPROM
1= intrerupere permisa
0= intrerupere interzisa
Daca EEIE si EEIF (ce este in registrul EECON1) au fost simultan
setate, va avea loc o intrerupere.
Bit 7 GIE (Global Interrupt Enable bit-bit Permite Intrerupere
Globala) Bit ce permite sau interzice toate intreruperile.
1=toate intreruperile sunt permise
0=toate intreruperile sunt interzise
PIC16F84 are patru surse de intrerupere:
1. Terminarea scrierii datelor in EEPROM
2. Intrerupere TMR0 cauzata de depasirea timer-ului
3. Intrerupere in timpul schimbarii la pinii RB4, RB5, RB6 si RB7 ai
portului B.
4. Intrerupere Externa de la pinul RB0/INT al microcontrolerului
In general, fiecare sursa de intrerupere are doi biti legati la
ea. Unul permite intreruperea, iar celalalt detecteaza cand au loc
intreruperi. Exista un bit comun numit GIE ce poate fi folosit pentru a
interzice sau permite toate intreruperile simultan. Acest bit este foarte
folositor cand se scrie un program pentru ca permite ca toate
intreruperile sa fie interzise pentru o perioada de timp, asa ca
executia unei parti importante a programului sa nu fie
intrerupta. Cand instructiunea ce reseteaza bitul GIE a fost executata
(GIE=0, toate intreruperile interzise), fiecare intrerupere ce ramane
nerezolvata trebuie ignorata.
Intreruperile ce
raman nerezolvate si ce au fost ignorate, sunt procesate cand bitul
GIE (GIE=1, toate intreruperile sunt permise) va fi sters. Cand i s-a
raspuns intreruperii, bitul GIE a fost sters, asa ca orice
intreruperi aditionale vor fi interzise, adresa de intoarcere a fost
trimisa in stiva, iar adresa 0004h a fost scrisa in contorul
programului - numai dupa aceasta incepe raspunsul la o intrerupere!
Dupa ce este procesata intreruperea, bitul a carui setare a
cauzat o intrerupere trebuie sters, sau rutina de intrerupere va fi
procesata automat tot mereu in timpul intoarcerii la programul principal.
Pastrarea continutului registrilor importanti
Doar valoarea de intoarcere a contorului programului este inmagazinata
intr-o stiva in timpul unei intreruperi (prin valoare de intoarcere a contorului
programului intelegem adresa instructiunii ce trebuie executata,
dar nu a fost executata pentru ca a avut loc intreruperea).
Pastrand doar valoarea contorului programului adesea nu este suficient.
Unii registri ce sunt in uz in programul principal pot fi de asemenea in
uz in rutina de intrerupere. Daca ei nu sunt retinuti, programul
principal va obtine valori complet diferite in acei registri in
timpul intoarcerii dintr-o rutina de intrerupere, ceea ce va cauza erori
in program. Un exemplu de asemenea caz este continutul registrului de
lucru W. Daca presupunem ca programul principal a folosit registrul
de lucru W pentru unele din operatiile sale, si ca a
pastrat in el o valoare ce este importanta pentru urmatoarea
instructiune, atunci o intrerupere ce se va intampla inainte de acea
instructiune va schimba valoarea registrului de lucru W, ce va
influenta direct programul principal.
Procedura de inregistrare de registri importanti inainte de a merge
la o rutina de intrerupere se numeste PUSH, in timp ce procedura ce
aduce valorile inregistrate inapoi, se numeste POP. PUSH si POP sunt
instructiuni ale altor microcontrolere (Intel), dar sunt atat de larg
acceptate ca o intreaga operatie este numita dupa ele.
PIC16F84 nu are instructiuni ca PUSH si POP, si ele trebuie
sa fie programate.
Datorita
simplitatii si folosirii frecvente, aceste parti ale
programului pot fi facute ca macro-uri. Conceptul unui Macro este explicat
in 'Limbaj de asamblare program'. In urmatorul exemplu,
continuturile registrilor W si STATUS sunt memorate in
variabilele W_TEMP si STATUS_TEMP inainte de rutina de intrerupere. La
inceputul rutinei PUSH trebuie sa verificam bancul selectat in
prezent pentru ca W_TEMP and STATUS_TEMP nu se gasesc in bancul 0.
Pentru schimbul de date intre acesti registri, instructiunea
SWAPF se foloseste in loc de MOVF pentru ca nu afecteaza starea
bitilor registrului STATUS.
Exemplul este un program asamblor pentru urmatorii pasi :
1. Testarea bancului curent
2. Stocarea registrului W indiferent de bancul curent
3. Stocarea registrul STATUS in bancul 0
4. Executarea rutinei de intrerupere pentru procesul de intrerupere (ISR)
5. Restaureaza registrul STATUS
6. Restaureaza registrul W
Daca mai sunt si alte variabile sau registri ce trebuie
stocati, atunci ei trebuie sa fie pastrati dupa
stocarea registrului STATUS (pasul 3), si adusi inapoi inainte ca
registrul STATUS sa fie restaurat (pasul 5).
Acelasi exemplu se poate realiza utilizand macro-uri, facand astfel programul mai eligibil. Macro-urile ce sunt deja definite, pot fi folosite pentru scrierea de noi macro-uri. Macro-urile BANK1 si BANK0 ce sunt explicate in capitolul 'Organizarea memoriei' sunt folosite cu macro-urile 'push' si 'pop'.
Intrerupere
externa la pinul RB0/INT al microcontrolerului
Intreruperea externa la pinul RB0/INT este triggerata de frontul
crescator (daca bitul INTEDG=1 in registrul OPTION<6>), sau de
frontul descrescator (daca INTEDG=0). Cand apare semnalul corect la
pinul INT, bitul INTF este setat la registrul INTCON. Bitul INTF
(INTCON<1>) trebuie resetat in rutina de intrerupere, asa ca
intreruperea sa nu aiba loc din nou in timpul intoarcerii la
programul principal. Acesta este un pas important al programului pe care
programatorul nu trebuie sa-l uite, sau programul va merge constant in
rutina de intrerupere. Intreruperea poate fi inchisa prin resetarea
bitului de control INTE (INTCON<4>).
Intreruperea in timpul depasirii contorului TMRO
Depasirea contorului TMRO (de
Intrerupere pe timpul unei schimbari la pinii 4, 5, 6 si 7
ai portului B
Schimbarea semnalului de intrare
Intreruperea la terminarea subrutinei write in EEPROM
Aceasta intrerupere este doar de natura practica. Pentru ca
scrierea intr-o locatie EEPROM dureaza cam 10ms (care este o
durata lunga in termenii microcontrolerului), nu este rentabil de a
astepta pana la capat scrierea. Este adaugat astfel
mecanismul de intrerupere ceea ce permite microcontrolerului sa continue
executarea programului principal, in timp ce scrierea in EEPROM este
facuta in plan secundar. Cand scrierea este terminata,
intreruperea informeaza microcontrolerul ca scrierea s-a terminat.
Bitul EEIF, prin care se face aceasta informare, se gaseste in
registrul EECON1. Producerea unei intreruperi poate fi interzisa prin
resetarea bitului EEIE in registrul INTCON.
Initializarea intreruperii
Pentru a folosi un mecanism de intrerupere a unui microcontroler, trebuie
facute unele sarcini pregatitoare. Aceste proceduri sunt pe scurt
numite 'initializare'. Prin initializare definim la ce va
raspunde microcontrolerul, si ce va ignora. Daca nu setam
bitul ce permite o anumita intrerupere, programul nu va executa un
subprogram intrerupere. Prin aceasta putem obtine controlul asupra
producerii intreruperii, ceea ce este foarte folositor.
Exemplul de mai
sus arata initializarea unei intreruperi externe la pinul RB0 al
microcontrolerului. Unde se vede unu setat, inseamna ca intreruperea
este permisa. Producerea altor intreruperi nu este permisa, si
toate intreruperile impreuna sunt interzise pana ce bitul GIE este
tinut in unu.
Urmatorul exemplu arata o cale tipica de a dirija intreruperile.
PIC16F84 are doar o locatie unde adresa unui subprogram intrerupere este
memorata. Aceasta inseamna ca mai intai trebuie sa
detectam ce intrerupere este la indemana (daca mai mult de o
sursa de intreruperi este disponibila), si apoi putem executa
acea parte a programului ce se refera la acea intrerupere.