Sunteți pe pagina 1din 5

Lab 3 - ntreruperi (pe Atmega32)

1) Introducere
ntreruperile sunt indispensabile n proiectarea unui sistem care s reacioneze corect i eficient n raport cu lumea
exterioar. Faptul c au suport hardware ofer un timp de rspuns i overhead minimal.
n acelai timp, din punct de vedere software, ntreruperile au un neajuns intrinsec. n primul rnd ele nu sunt
portabile pe diferite procesoare i chiar pe diferite compilatoare. n al doilea rnd, ntreruperile pot determina
numeroase erori software greu de identificat.

2) Noiuni
O ntrerupere are dou nelesuri apropiate:
transferul hardware al controlului (saltul firului de execuie) ctre un vector de ntrerupere pe baza
nregistrrii unui fenomen exterior procesorului
funcia de tratare a ntreruperii secvena de cod la care se ajunge din vectorul de ntrerupere

Figura Lab 3 - ntreruperi (pe Atmega32)-1

n general, un vector de ntrerupere este o locaie n memorie ce conine adresa unde firul de execuie ar trebui s
sar n cazul ntreruperii. n cazul microprocesorului Atmega32 un vector de ntrerupere conine nu o adres ci o
instruciune de salt la adresa funciei de ntrerupere.
O ntrerupere este n ateptare dac condiia de ntrerupere a avut loc i acest lucru a fost nregistrat de platforma
hardware, ns nc nu s-a realizat saltul firului de execuie ctre rutina de ntrerupere. O ntrerupere este pierdut dac
condiia de ntrerupere a avut loc, ns acest lucru nu a fost nregistrat la nivel hardware.
De obicei o ntrerupere este pierdut dac fenomenul declanator are loc n timp ce ntreruperea este n ateptare.
O ntrerupere este dezactivat dac s-a utilizat un suport hardware pentru a preveni declanarea ntreruperii.
Suportul hardware este dat de 2 bii: unul specific fiecrui tip de ntrerupere i unul ce se refer la toate ntreruperile.
ntreruperea de Reset face o abatere de la aceast regul prin faptul c nu proate fi prevenit. Saltul ctre un vector
oarecare de ntrerupere poate avea loc doar dac cei doi bii au valoarea 1.
Pentru Atmega32, bitul ce se refer la toate ntreruperile se numete I i se afl n registrul de stare al
microprocesorului (bitul 7 din SREG). Pentru a-l modifica se pot utiliza urmtoarele instruciuni consacrate:

Funcii
Mnemonic Descriere Operaie Numr de cicli
IAR
SEI Global Interrupt Enable I1 1 sei()
CLI Global Interrupt Disable I0 1 cli()

Pentru a modifica bitul individual de validare a ntreruperii, acesta trebuie cutat pentru fiecare tip de ntrerupere.
De exemplu, pentru ntreruperea extern INT0, acesta se regsete n registrul GICR, pe poziia 6.
Astfel, pentru a admite ntreruperi de tip INT0, pe frontul cresctor al semnalului extern (a se vedea i alte varinte),
putem utiliza urmtorul cod:
Cod surs 1:
#include <avr/io.h>
#include <avr/interrupt.h>

int main(void)
{
// initialization
MCUCR |= ((1 << ISC01) | (1 << ISC00)); /* select the rising edge */
GICR |= (1 << INT0); /* external interrupt request 0 enable */
sei(); /* global interrupt enable */
// end of initialization

// next to do
}

Se remarc faptul c ultimul lucru din procedura de iniializare a ntreruperilor este validarea ntreruperilor la nivel
global (ordine bottom-up).
Pentru fiecare tip de ntrerupere exist un bit ce este setat ori de cte ori platforma hardware nregistreaz
producerea fenomenului cauz specific i, de regul, este pus pe 0 de ctre microprocesor la intrarea n rutina de
ntrerupere. De exemplu, n cazul ntreruperii INT0 acest bit se numete INT0 i afl n registrul GIFR pe poziia 6.
Observaie: Pentru a reseta bitul ce semnific producerea fenomenului de ntrerupere se va asigna acestui bit
valoarea 1 (a se vedea manualul de utilizare pentru ntrebri).
Prioritatea ntreruperilor are justificare n cazul n care mai multe ntreruperi se gsesc n ateptare. ntreruperea
cu numrul de ordine cel mai mic va fi urmtoarea tratat (a se vedea tabelul vectorilor de ntreruperi).
O funcie de ntrerupere n curs nu poate fi ntrerupt la rndul ei de ctre o ntrerupere cu prioritate mai nalt.
Latena ntreruperii reprezint practic timpul de rspuns al microprocesorului. Se definete ca find intervalul de
timp dintre:
momentul de timp n care condiia de ntrerupere a avut loc, i
momentul de timp n care s-a intrat n rutina de ntrerupere

De regul, latena ntreruperii nu este o mrime constant i se poate vorbi despre cea mai defavorabil laten.
O funcie de ntrerupere se termin cu instruciunea RETI (return from interrupt). Aceast instruciune realizeaz
de fapt o revenire n program n punctul n care acesta a fost ntrerupt. Adresa de revenire (4 octei) este stocat (pe stiv,
de regul) nainte de a se efectua saltul ctre vectorul de ntrerupere (deci n momentul n care ntreruperea se afl n
stare de ateptare i s-a decis tratarea ei).
n general, ntreruperile pot fi sau nu reentrante. Se spune despre o ntrerupere c este reentrant dac execuia ei
poate fi ntrerupt la apariia unei ntreruperi cu o prioritate mai mare.
ntreruperile de pe microprocesorul Atmega32 nu sunt reentrante.

3) Probleme
Corectitudinea concurenial
ntreruperile pot provoca un comportament neateptat al microprocesorului dac nu s-au prevzut toate aspectele
legate de concuren.
Se presupune c o ntrerupere poate avea loc oricnd. Deci o funcie de ntrerupere va avea structura urmtoare:

1 F o copie a tuturor regitrilor ce vor fi eventual modificai n


corpul funciei de ntrerupere

2 Realizeaz toate operaiile proprii rutinei de ntrerupere

3 Ref toi regitrii referii la pasul 1

Tabelul Lab 3 - ntreruperi (pe Atmega32)-1

ntr-o funcie de ntrerupere scris n C nu se specific paii 1 i 3, deoarece compilatorul are grij s studieze ce
regitri sunt modificai n corpul funciei de ntrerupere i s-i salveze. Oricum, estimrile compilatorului pot fi altele dect
cele fcute de programator (compilatorul va lua cel mai probabil nite precauii mai mari dect cele necesare), astfel
nct, la un moment dat, s apar dorina de a scrie funcia de ntrerupere n limbaj de asamblare.

Depirea stivei
Se presupune c o rutin de ntrerupere are nevoie de un spaiu propriu peste stiva programului. Dimensiunea
acestui spaiu reflect un consum de memorie i, poate cel mai important, existena unor instruciuni de scriere-citire ce
se execut n ntrerupere. Din acest motiv, n rutinele de ntrerupere se evit apelurile de funcie.
Ceea ce rmne de fcut din partea proiectantului este s scrie rutine de ntrerupere care s utilizeze ct mai
puin stiv i (vezi modelul de memorie) s dimensioneze stiva astfel nct s nu se ajung la coruperea ei.

Suprancrcarea procesorului
La proiectarea unui sistem se va lua n consideraie frecvena de ntrerupere i timpul utilizat de ctre rutinele de
tratare a ntreruperilor.
De exemplu, conectarea direct a unui buton la un pin de ntrerupere extern ar putea nsemna generarea unui
numr mare de ntreruperi inutile (din cauza fenomenului de bouncing).

4) Tipuri: hard i soft


Att timp ct fenomenul cauz al ntreruperii este de natur extern ntreruperea este de tip hard. Exist i
posibilitatea ca printr-o metod software s se satisfac condiia de ntrerupere. O ntrerupere declanat pe aceast cale
va fi de tip soft.
De exemplu, dac o ntrerupere extern este activat (INT0, INT1, INT2) i pinul corespunztor este setat ca ieire,
atunci ntreruperea poate fi declanat prin scrierea pinului.
O alt cale prin care se poate genera software o ntrerupere este de a seta bitul folosit de ctre platforma
hardware pentru nregistrarea satisfacerii condiiei de ntrerupere.

5) Vectori de ntrerupere
Vectorii de ntrerupere sunt definii n fiierul iom32.h, dup cum urmeaza :

#define INT0_vect _VECTOR(1)


#define INT1_vect _VECTOR(2)
#define INT2_vect _VECTOR(3)
#define TIMER2_COMP_vect _VECTOR(4)
#define TIMER2_OVF_vect _VECTOR(5)
#define TIMER1_CAPT_vect _VECTOR(6)
#define TIMER1_COMPA_vect _VECTOR(7)
#define TIMER1_COMPB_vect _VECTOR(8)
#define TIMER1_OVF_vect _VECTOR(9)
#define TIMER0_COMP_vect _VECTOR(10)
#define TIMER0_OVF_vect _VECTOR(11)
#define SPI_STC_vect _VECTOR(12)
#define USART_RXC_vect _VECTOR(13)
#define USART_UDRE_vect _VECTOR(14)
#define USART_TXC_vect _VECTOR(15)
#define ADC_vect _VECTOR(16)
#define EE_RDY_vect _VECTOR(17)
#define ANA_COMP_vect _VECTOR(18)
#define TWI_vect _VECTOR(19)
#define SPM_RDY_vect _VECTOR(20)

6) Definiia unei funcii de ntrerupere n limbajul C


Pentru a defini o funcie de ntrerupere pentru, de exemplu, fenomenul de Timer0 Compare Match, n limbajul C,
se vor crea fiierele driver_interrupt.h i driver_interrupt.c dup cum urmeaz:
Cod surs 2:

driver_interrupt.h

#ifndef driver_interrupt_h
#define driver_interrupt_h

#include "Global.h" // always include this first!!!


#include <avr/io.h>
#include <avr/interrupt.h>

void init_Timer0_int(void);
extern int GLOBAL_VARIABLE;

#endif

driver_interrupt.c

#include "driver_interrupt.h"
ISR(TIMER0_COMP_vect)
{
// to do
}

Se poate observa de mai sus c asocierea dintre o funcie i un vector de ntrerupere se face cu ajutorul directivei
ISR(vector, [attributes]), unde vectorul ntreruperii este dat sub forma unui simbol definit de regul ntr-un fiier
header aflat n biblioteca compilatorului.

7) Timer
Timerul/Counterul, dupa cum i spune i numele ofer facilitatea de a msura intervale fixe de timp i de a genera
ntreruperi la expirarea intervalului masurat. Un timer, odat iniializat va funciona independent de unitatea centrala
(core P). Acest lucru permite eliminarea buclelor de delay din programul principal.

Principiul de funcionare a unui Timer poate fi descris n linii mari de cele trei uniti din figura de mai jos:

- Registrul numarator (Timer Counter, TCNT) - msoar efectiv intervalele de timp i este incrementat automat cu o
frecven dat.

- Prescaler-ul - are rolul de a diviza n funcie de necesitile aplicaiei frecvena de ceas i odat cu divizarea s
incrementeze registrul TCNT.

- La fiecare incrementare a TCNT are loc o comparaie ntre acest registru i o valoare stocat n registrul OCRn.
Aceast valoare poate fi ncarcat de ctre programator prin scrierea registrului OCRn. Dac are loc egalitatea se
genereaz o ntrerupere, n caz contrar incrementarea continu.

Registri
Timer Registri Rol

TCNT0 Registrul contor al timer-ului 0 (cel care numr)


Timer0 TCCR0A,TCCR0B Registru de control ale timer-ului 0 (aici vei activa diveri bii pentru
configurarea timer-ului)
8 bii
OCR0A,OCR0B Registru prag pentru timer-ul 0 (prag al numrtorii la care stuff happens,
n funcie de configurare)

TIMSK0,TIFR0 Registru cu bii de activare ntreruperi timer 0 / flag-uri de activare (aici


activai ntreruperile)

Timer1 TCNT1H/L = Registrul contor al timer-ului 1 (la fel ca la timer0, doar c pe 16 bii)
TCNT1H + TCNT1L

TCCR1A , TCCR1B,TCCR1C Registru control ale timer-ului 1 (la fel ca la timer0)

16 bii OCR1AH/L , OCR1BH/L Registru prag pe 16 bii ale timer-ului 1 (la fel ca la timer0)

TIMSK1, TIFR1 (la fel ca la timer0)

ICR1H/L Registru folosit pentru a reine valoarea contorului la apariia unui


eveniment extern pe pin-ul ICP ( nu vom folosi la laborator, poate folosii
voi la proiect)

Timer2 aceiasi registri ca la Timer0 Diferena fa de Timer-ul 0 este posibilitatea folisirii unui oscilator extern
separat pentru Timer-ul 2,
8 bii pe pinii TOSC1 i TOSC2

ASSR, GTCCR Registri ce in de funcionarea asicron a acestui timer fa de restul


sistemului

Probleme
1. Afisati pe Byte Display anii bisecti, incepand cu 1900, cate 5 ani simultan, cu o rata de update de 30ms.

2. Construiti un program care sa afiseze pe Byte Display un ceas.

S-ar putea să vă placă și