luni, 15 noiembrie 2010

Întreruperea externă

Lucrarea de laborator  Nr. 4 

 

Tema: Întreruperea externă

Scopul lucrării: Obţinerea cunoştinţelor practice şi deprinderilor de a opera întreruperile într-un microcontroller din familia AVR.
Expunerea problemei:  In cadrul acestei lucrări se propune drept sarcină elaborarea  unui dispozitiv de dirijare a unui afişaj cu şapte segmente cu ajutorul butoanelor conectate la portul de intrare. În dependenţă de butonul apăsat să se reprezinte cifra corespunzătoare.

Consideraţii teoretice: O întrerupere reprezintă un semnal sincron sau asincron de la un periferic, ce semnalizează apariţia unui eveniment care trebuie tratat de către procesor. Tratarea întreruperii are ca efect suspendarea firului normal de execuţie al unui program şi lansarea în execuţie a unei rutine de tratare a întreruperii (RTI).

Fig 1. Reprezentarea schematică a mecanismului de prelucrare a întreruperii.

Întreruperile hardware au fost introduse pentru a se elimina buclele pe care un procesor ar trebui sa le facă în aşteptarea unui eveniment de la un periferic. Folosind un sistem de întreruperi, perifericele pot atenţiona procesorul în momentul producerii unei întreruperi (RTI), acesta din urma fiind liber să-şi ruleze programul normal în restul timpului şi să îşi întrerupă execuţia doar atunci când este necesar. Înainte de a lansa în execuţie o RTI, procesorul trebuie să aibă la dispoziţie un mecanism prin care să salveze starea în care se află în momentul apariţiei întreruperii. Aceasta se face prin salvarea într-o memorie, de cele mai multe ori organizată sub forma unei stive, a registrului contor de program (Program Counter), a registrelor de stare precum şi a tuturor variabilelor din program care sunt afectate de execuţia RTI. La sfârşitul execuţiei RTI starea anterioară a registrelor este refăcută şi programul principal este reluat din punctul de unde a fost întrerupt. Pentru a asocia o întrerupere cu o anumită rutină din program, procesorul foloseşte tabela vectorilor de întrerupere (TVI). Fiecărei întreruperi îi este asociată o adresă la care programul va face salt în cazul apariţiei acesteia. Aceste adrese sunt predefinite şi sunt mapate în memoria de program într-un spaţiu continuu care alcătuieşte TVI. Adresele întreruperilor în TVI sunt setate în funcţie de prioritatea lor, cu cât adresa este mai mică cu atât prioritatea este mai mare.

Fig. 2 Algoritmul unei întreruperi

Tratarea unei întreruperi pentru ATMega16, se face ca in figura de mai sus.
Se presupune că programul nostru primeşte întreruperea externă INT0 în timp ce execută instrucţiunea ldi R16,0xFF. După efectuarea instrucţiunii, registrul contor Program Counter (PC) este automat salvat în stivă şi apoi iniţializat la valoare corespunzătoare adresei lui INT0($002). Acest lucru se traduce prin saltul programului de la adresa curentă ($132) la adresa ($002). Aici, programul găseşte instrucţiunea jmp $2FF care-i permite trecerea la rutina efectivă de tratare a întreruperii. La sfîrşitul oricărei RTI trebuie să existe instrucţiunea reti care reface din stiva registrul PC (programul sare înapoi la adresa de unde rămăsese înainte de întrerupere).
Codul pentru execuţie la apariţia unei întreruperi se grupează într-o subrutină similară cu subrutina normală, diferenţa e că ea se termină cu comanda reti, care concomitent setează bitul I din registrul SREG.
Sistemul este conceput în aşa mod ca să cheme automat subrutina de prelucrare a întreruperii în cazul apariţiei ei. Adresa subrutinei se păstrează în vectorul de întreruperi, care este un segment din memoria de programe, fiecare locaţie din el păstrând adresa subrutinei asociate ei, care este accesată automat la apariţia întreruperii respective.
Pentru ca o subrutină să fie accesată sunt necesare următoarele condiţii:
  • efectul de întrerupere;
  • întreruperea trebuie să fie activă în dependenţă de modulul periferic care generează întreruperea (există biţi specializaţi pentru activarea întreruperii de la acest periferic);
  • întreruperea generală trebuie să fie permisă;
Pentru a configura întreruperile se folosesc următorii regiştri:
GICR – General Interrupt Control Register - registrul care este destinat activării sau dezactivării unei anumite întreruperi externe:


GIFR – General Interrupt Flag register – în acest registru se setează biţii în cazul apariţiei unei întreruperi. Dacă biţii sunt setaţi manual, aceasta va porni mecanismul de prelucrare a întreruperii date:

MCUCR – General Interrupt Control Register – registrul care este destinat setării momentului de reacţionare a intreruperii:



Tab.1 Setările biţilor ragistrului MCUCR

Activarea/Dezactivarea întreruperilor:
Întreruperile pot fi activate sau dezactivate de utilizator în program prin setarea individuală a biţilor de interrupt enable pentru fiecare periferic folosit şi prin setarea flagului de “Global Interrupt Enable” (I) din Status Register (SREG).

Mersul lucrării:
1) Pentru a înţelege mai bine cum funcţionează întreruperile, se pune problema scrierii unui program în baza schemei respective, pentru microcontrollerul Atmega16, care va afişa numărul butonului ce va fi apăsat, iar în restul timpului să execute o funcţie anumită de rutină.
Schema bloc a programului:



2) În baza schemei create, se construieşte schema electrică cu ajutorul programului PROTEUS, care la rândul ei va acţiona în baza programului.

Fig. 3 Schema electrică

3) Principiile programei vor fi următoarele: la apăsarea unei taste, aceasta va comunica o cădere de nivel pe pinul de intrare asociat acelui buton şi pe cel al întreruperii externe 0, aceasta din urmă va chema subrutina întreruperii în care se va verifica pe ce pin este nivelul de jos a tensiunii şi va afişa la indicatorul cu 7 segmente numărul butonului asociat acelui pin.
În programul principal va fi mereu incrementat un registru şi se va afişa valoarea sa la alt indicator.
   ...

4) Compilarea programului şi verificarea funcţionării sale (executării) pas cu pas cu scopul de a găsi şi elimina erorile.
5) Ultimul pas este simularea circuitului creat în PROTEUS, corecţia acestuia în caz de necesitate, în urma căreia ne putem convinge că programul funţionează corect şi că microcontrolerul execută toate comenzile cu exactitate, obţinînd rezultatul dorit.

Descrierea instrucţiunilor utilizate:
LD - încarcă indirect,cu sau fără postincrementare/predecrementare un octet din spaţiul de date într-un registru. Nu modifică nici un flag.
Sitaxa
   Operanzii
   Program counter
LD Rd, Y
      0≤d≤31
   PC←PC+1
LDI R1, K - încarcă în registrul R1 o constantă;
IN R1, PINx - citeşte în registrul R1 datele de intrare de la PINx;
OUT PORTx, R1 - încarcă în registrul de ieşire a potului x datele din registrul R1;
BRNE - Ramificare condiţională relativă. Testează flagul Z (flagul zero) şi dacă nu este setat programul se remifică conform PC în orice direcţie (PC-64≤destinaţia≤PC+63). Nu modifică nici un flag.
Sitaxa:
 Operanzii
     Program counter
BRNE         k
-64≤k≤+63
     PC←PC+k+1
      PC←PC+1, dacă condiţia e falsă