Documente Academic
Documente Profesional
Documente Cultură
Raport
Lucrare de laborator Nr.4
La disciplina Microprocesoare
Tema :„Intreruperea externă . Prelucrarea tablourilor.”
Chișinău – 2016
Expunerea problemei: Să se realizeze o aplicație pe MCU care va calcula și va afișa suma
elementelor unui tablou de 10 elemente a câte 8biți. Calculul sumei și afișarea rezultatului se va
realiza la fiecare a 11-a apăsare a butonului, iar primele zece apăsări vor introduce pe rând în tablou
numărul citit de pe un PORTx al microcontroller-ului completând astfel tot tabloul cu elemente noi
de fiecare dată.
În acest scop se va realiza o subrutină care va realiza doar suma elementelor tabloului și va fi apelată
din cadrul subrutinei de prelucrare a întreruperii externe care, la rândul său, va realiza completarea
tabloului cu un element nou la fiecare apăsare nouă a butonului, dar și apelul subrutinei de sumare
atunci când tabloul este completat.
Intreruperi.
Întreruperea reprezintă suspendarea procesului normal de execuţie a programului pentru rezolvarea unei
probleme prioritare.
Întreruperea de regulă este generată ca răspuns la un efect fizic intern sau extern al unui modul
periferic. Efectul fizic în sine va reprezenta situaţia de întrerupere sau excepţie care necesită o
tratare neintârziată. Asemenea situaţii de întreruperi pot fi ca de exemplu: schimbarea nivelului
logic la un pin, sfârşitul unei perioade de timp sfârşitul unei operaţii de transmisie sau recepţie,
sfârşitul unei conversii etc.
Majoritatea modulelor periferice pot genera una sau mai multe întreruperi.
Tratarea situaţiei de întrerupere presupune existenţa unei subrutine definite în acest scop. Odată
cu apariţia situaţiei de întrerupere, microcontrollerul va seta într-un registru de stare a perifericului
un flag de întrerupere IF, care va fi pastrat pâna la prelucrarea intreruperii date. Pentru ca
întreruperea de la situaţia de întrerupere să fie generată va fi nevoie ca în registrul de control al
perifericului întreruperea în cauză să fie activată prin setarea unui bit de activare IE. Mecanismul de
chemare a subrutinei de prelucrare a întreruperii va fi iniţiat doar în cazul în care:
Vector de întreruperi
Odată ce o întrerupere a fost generată sistemul va executa un apel hardware a subrutinei de prelucrare a
întreruperii (ISR), care presupune un salt la o adresă unde este realizată această subrutină. Deoarece o
asemenea chemare nu este una explicită, ca şi în cazul unui apel clasic cu o instrucţiune de tip CALL unde
adresa de salt este parametru al comenzii, apelul hardware presupune existenţa în memoria de programe a
unei zone de memorie alocate pentru subrutinele de prelucrare a întreruperilor. Această zonă de memorie de
program este numită vector de întreruperi.
Deci vom spune că vectorul de întreruperi reprezintă o zonă de memorie de program rezervată adreselor
de referinţă a subrutinelor de prelucrare a întreruperilor.
Vectorul de întreruperi, pentru arhitectura AVR, este localizat la începutul memoriei de program, începând
cu adresa $0000. Pentru fiecare subrutină de prelucrare a întreruperilor de la o anumită sursă de întrerupere îi
este rezervat un spaţiu de 2 comenzi (pentru versiunile mai vechi a nucleului AVR o comanda).
În mod evident că acest spaţiu de cele mai deseori nu este destul pentru a implementa o subrutină de
prelucrare a întreruperii însă suficient pentru a executa o redirecţionare către implementarea subrutinei cu o
instrucţiune de salt necondiţionat de tip JUMP. În cazul în care am dori să protejăm programul de la apeluri
accidentale a unei ISR la locaţia respectivă se va înregistra o comandă de returnare din subrutină. Deoarece
avem la dispoziţie tocmai două locaţii de program am putea utiliza una din ele pentru tratarea apelurilor
nedorite a ISR prin setarea unui indicator, aprinderea unui beculeţ, sau chiar un apel de subrutină special
definită în acest scop.
Putem vedea ca pentru ca sa fie apelata subrutina de prelucrare a intreruperii este necesara
satisfactia urmatoarelor conditii:
- GICR (GIMSK) - General Interrupt Control service pentru activarea unui modul de intrerupere
exetrna prin inscrierea valorii "1" logic in locatia specifca din acest registru. respectiv pentru
dezactivare se inregistreaza "0" logic
de notat ca pentru ca ca intreruperea sa aiba loc este necesar ca bitul global de activare a
intreruperii sa fie activ.
de exemplu, pentru activarea intreruperii de la sursa INT0 se va executa urmatoarea secventa
de cod, de obicei plasata in secveta de inializare a progamului principal:
ldi R16, 1<<INT0 // incarcarea valorii 0b10000000 in R16
out GICR, R16 // Activarea intreruperii Int0
După cum am spus mai sus, generarea unei întreruperi va implica un apel hardware a unei ISR.
Mecanismul de chemare a unei ISR este identic cu cel de chemare a unei subrutine obişnuite cu
excepţia ca pe durata executării ISR bitul global de permisiune a întreruperilor va fi resetat, I=0,
fapt care va interzice chemarea unei alte ISR pe durata executării ISR. Deci mecanismul de
chemare a unei ISR va fi realizat în mai multe etape.
La detectarea situaţiei de întrerupere se va evalua o relaţie de tip IF & IE & I (vezi mai sus).
Dacă această relaţie va fi adevărată se va declanşa mecanismul de apel hardware al ISR. În
cazul în care Întreruperea a fost detectată în timpul execuţiei unei comenzi, se va aştepta pînă
la terminarea execuţiei comenzii curente, după care se va declanşa mecanismul de chemare a
ISR.
Se va executa apelul hardware al ISR echivalent cu o comandă de forma CALL ISR_Addr
unde ISR_Addr va fi adresa de referinţă din Vectorul de întreruperi pentru Întreruperea dată. În aşa
mod se va realiza un salt necondiţionat la adresa ISR_Addr, localizată în vectorul de întreruperi,
însoţit de o salvare a Contorului de Program (PC) în stiva (Stack), PC+1->Stack.
Concomitent cu saltul la vectorul de întreruperi se va reseta bitul global de permisiune a
întrerulerilor, I = 0, un echivalent a comenzii CLI, fapt ce va interzice întreruperea execuţiei ISR de o
altă ISR detectate în acest timp.
Execuţia secvenţei de instrucţiuni din cadrul ISR. Pentru ISR sunt valide recomandările pentru
subrutinele obişnuite referitor la păstrarea stării globale a regiştrilor de uz general utilizaţi în cadrul ISR,
ce se realizează prin salvarea lor în stivă la începutul subrutinei şi restabilirea acestora înainte de
returnarea din subrutină.
Returnarea din ISR realizată cu comanda RETI. Această comandă este echivalentă cu comanda de
returnare din subrutina obişnuită RET, cu excepţia ca concomitent se va seta bitul de permisiune globală
a întreruperilor, I = 1. Putem spune ca RETI este echivalent cu RET+SEI. Deci, returnarea din ISR va
implica restabilirea adresei Contorului de Program din stivă, care fusese salvat în procesul de chemare a
ISR, PC->Stack şi execuţia programului va continua exact din locul unde a fost suspendat de către
întrerupere.
Principiul ca o ISR nu poate fi întreruptă de o altă Întrerupere se datorează faptului că pe durata execuţiei
acesteia bitul global de permisiune al întreruperilor I este resetat (I=0). Însă această regulă poate fi anulată
odată cu setarea în cadrul ISR a bitului de permisiune a Întreruperilor cu comanda SEI (I=1). Această acţiune
va permite ca o ISR sa fie întreruptă de o altă întrerupere.
Intreruperea Reset
Majoritatea sistemelor digitale, printre care se enumeră şi Microcontrollerul, presupun existenţa unui
semnal RESET prin intermediul căruia sistemul se readuce o stare iniţială. Semnalul de RESET ca regulă este
aplicat la regiştrii interni, readucînd sistemul la o stare predefinită. În modul normal de funcţionare a
dispozitivului semnalul se menţine într-o stare predefinită fie 0 sau 1 menţinută din interiorul sistemului sau
din exterior. Îniţierea unui RESET presupune generarea unui puls de o durată anumită de valoare inversă
celei din starea normală de funcţionare pe semnalul de Reset.
Microcontrollerul din seria AVR are în interior un modul specializat pentru generarea semnalului intern de
RESET. Acest modul permite generarea pulsului intern de reset în mai multe situaţii cum ar fi aplicarea
alimentării circuitului POWERON RESET, căderea nivelului sursei de alimentare a circuitului, expirarea
timpului de time-out de la modulul WATCHDOG (Timer de veghe), sau aplicarea unui puls negativ la pinul
extern RESET al microcontrollerului.
Pe lîngă faptul ca semnalul de RESET intern iniţializează toţi regiştrii interni al microcontrollerului, se
generează o situaţie de întrerupere RESET, care va implica prelucrarea acestei întreruperi.
Întreruperea RESET are cea mai mare prioritate şi deci adresa de referintă a ISR se va plasa în capul
Vectorului de Întreruperi, adică la adresa $0000.
Mai mult decât atât Intreruperea RESET este o întrerupere nemascată, fapt ce îi dă posibilitatea să fie
prelucrată chiar dacă întreruperile sunt interzise prin bitul de permisune a întreruperilor (I=0). Deci această
întrerupere va putea suspenda o alta întrerupere.
Mersul lucrării :
1. Realizez schema bloc a programului :
INT0_ISR SumTab
Start
NU DA PUSH R22
R21!
reset =TAB__SI
ZE
INT0_ISR YL=LOW(TabA) YL=LOW(TabA)
YH=HIGH(TabA) YH=HIGH(TabA)
PortInit
NU DA CLR R22
StackInit R22=0
INT0_Init
TabInit
IN R18, PINA R21<-TAB_SIZE
R21<-TAB_SIZE ST Y+, R18
Counter->R21
Activarea PUSH R18<-Y+
Intreruperii Call SumTab Dec R21 ADD R19,R18
Externe POP ADC R20,R22
R19<-result
R20<-result+1
OUT PORTB POP R21 R22--
OUT PORTC POP R20
SBI PORTD,0 POP R19 NU DA
Delay1 POP R18
CBI PORTD,0 R21==0
Delay2
reti R19<-result
R20<-result+1
reti
2. Pentru a scrie programul, folosesc programa Atmel Studio 6,
-creez noul proiect folosind shablonul pentru limbajul de programare assembler,
-selectez microcontrolerul în memoria căruia va fi înregistrat programul, în acest caz noi folosim
microcontroller ATMEGA 32.
.org 100 ;urmatoarele rinduri de cod vor fi scrise incepind cu adresa 0x100
;in afara vectorului de intreruperi
LDI R16,0b00000000
OUT PORTC,R16 ; de aceea ii putem ;atribui orice valoare in cazul dat 0x00
LDI R16,0b11111110
OUT PORTD,R16 ; setam spre intrare pull-up si spre iesire 0 logic
OUT MCUCR,R16
LDI R16,(1<<INT0) ;activarea modulului de intrerupere externa
OUT GICR,R16
end_INT0_Init: ;sfirsitul intreruperii externe
Delay1:
Dec R16 ;Se decrementeaza registrul R16 pina cind nu devine 0*
BRNE Delay1 ;Daca nu este egalitate la eticheta Delay1
PUSH R18
PUSH R19
PUSH R20
PUSH R21
POP R21
POP R20 ;prelucrare a intreruperii INT0
POP R19
POP R18 ;restabilirea are loc dupa principiul LIFO(LAST IN FIRT OUT)
VerCounter:
LD R18,Y+ ;Se selecteaza datele din tablou
ADD R19,R18 ;Se aduna elementul la suma totala(baitul Low)
ADC R20,R22 ;Se aduna elementul la suma totala(baitul high)
Dec R21 ;Se decrementeaza counterul
BRNE VerCounter ;Daca counterul este 0 atunci sare la VerCounter
STS result,R19 ;Incarca in R19 valoarea Low a rezultatului
STS result+1,R20 ;Incarca in R20 valoarea High a rezultatului
end_Sum_Tab:
3.Dupa realizarea părții de programare, realizez partea elecronică și anume schema circuitului.
Schema o realizam in Proteus,penru aceasta creem noul proiect in ISIS Sample desigh template.
Concluzie :
Realizînd schemei bloc, programul,circuitul electronic și verificarea rezultatelor, am constatat ca la
aparitia intreruperii are loc stoparea executiei normale a programului pentru executarea unei
probleme prioritare(inscrierea elementelor in tablou,si suma lor).In cazul cind avem o intrerupere
experna alte intreruperi sunt interzise deoareace are loc resetarea bitului global de permesiune a
inreruperilor I=0.