Documente Academic
Documente Profesional
Documente Cultură
Microcontrolere si sisteme
integrate
Microchip AVR 8 biți:
• Inițializarea hardware (Reset-ul),
• Ceasul de gardă (watchdog timer),
• Intrări-ieşiri numerice (porturile I/O),
• Metode generale pentru a realiza accesul la intrări -
ieșiri (arhitecturi de calcul)
• Sistemul de întreruperi (partea 1)
1
Inițializarea AVR 8 biti (reset)
• După o inițializare hardware (un reset), la fel ca la orice alt
microprocesor/microcontroler, şi cel puţin o parte din resurse au o
stare inițială precizată, astfel:
– Toate registrele I/O sunt setate la anumite valori iniţiale (implicite),
descrise in foaia de catalog/manual
– Prima instrucțiune executată este cea din vectorul de Reset, de la
adresa respectivă- 0x0000; cu alte cuvinte valoarea initiala a
numaratorului program PC este 0x0000
• Instrucțiunea memorată în vectorul de reset este de obicei o instrucțiune de salt absolut
(JMP) la prima instrucțiune din programul propriu-zis.
• Daca vorbim de initializarea hardware, pentru orice
microcontroler exista doua tipuri de baza de reset hardware:
– Un reset generat de conectarea si reconectarea sursei de
alimentare (power down + power up), numit reset la rece (cold
reset)
– Un reset generat de orice altceva (de exemplu prin intermediul
unui pin de reset), numit reset la cald (warm reset)
• După un reset la cald conținutul memoriei SRAM de date
rămâne nemodificat!
• După un reset la rece, conținutul RAM-ului de date (SRAM),
deci si al registrelor de uz general, este neprecizat (SRAM-ul
este o memorie volatila)! 2
Inițializarea AVR 8 biti (reset)
• Valori inițiale (initial value) ale biților unui registru I/O, după reset,
asa cum apar in foaia de catalog.
• Dacă programul nu activează şi nu utilizează întreruperile, vectorii
de întrerupere nu vor fi folosiți, şi codul programului poate scris şi la
aceste adrese- vezi sistemul de intreruperi.
– Acest lucru este, de asemenea, posibil şi în cazul în care vectorul de
reset este în zona de aplicaţie în timp ce vectorii de întrerupere sunt în
zona de bootloader sau invers.
• După ce „sursa externă” care a generat semnalul de reset devine
inactivă, intră în acțiune un numărător intern care va genera o
întârziere (time-out) cu scopul măririi perioadei cât reset-ul, intern
de data aceasta (internal reset), este activ.
– Aceasta va permite, de exemplu, tensiunii de alimentare să ajungă la o
valoare nominală stabilă înainte de se executa instrucţiuni.
– Acest timp de întârziere este definit si poate fi programat de utilizator
prin fuzibilele CKSEL.
3
Schema bloc a sistemului de generare a
reset-ului AVR 8 biti (AVR clasic)
4
Schema bloc a sistemului de generare a
reset-ului AVR 8 biti (AVR modernizat )
6
Reset-ul la conectarea tensiunii de alimentare
(POR)
• Un impuls de reset va fi generat la conectarea tensiunii de alimentare de
un circuit specializat (POR - Power On Reset) atunci când VCC va atinge
nivelul de prag VPOT atât în sens crescător cât şi descrescător.
• Circuitul POR garantează că microcontrolerul va fi resetat corect la
conectarea alimentării (Power-on).
• Atingerea tensiunii de prag în sens crescător declanşează numărătorul de
întârziere care va stabili durata de prelungire a reset-ului intern (tTOUT), după
dispariţia condiţiei.
• Reset-ul intern este activat (si mentinut) fără nici o întârziere atunci când
VCC coboară sub nivelul de detectare.
• Această variantă de reset este valorificată în practică prin conectarea
pinului RESET direct la tensiunea de alimentare Vcc: VPOT=VRST .
7
Reset-ul extern
• Un reset extern este generat practic de un nivel “0” pe pinul /RESET,
impuls care durează mai mult decât o lăţime de impuls minimă (din foaia de
catalog), chiar dacă ceasul CPU este oprit.
• Când semnalul aplicat pe /RESET atinge tensiunea de prag (VRST) pe
frontul crescător, pinul va fi considerat în „1”, condiția a dispărut şi un
numărător intern de întârziere va genera perioada suplimentară de reset
intern tOUT.
• În figuri sunt prezentate cele două situații relevante pentru activarea intrării
RESET: imediat după Power-up şi oricând în timpul funcționării.
8
Dacă nu utilizăm un reset de
Utilizare Reset extern tip extern, pinul respectiv
poate fi folosit ca intrare /ieşire
de uz general (in ex. PA2)
9
Reset-ul la scăderea temporară a tensiunii de
alimentare (Brown-out)
• Unele microcontrolere AVR (ATMega, XMEGA si cateva ATTiny) au un circuit de
detecţie numit BOD- Brown Out Detection, pentru a monitoriza nivelul VCC în
timpul funcţionării, comparând-ul cu un nivel fix de declanşare.
• Nivelul de declanşare pentru BOD poate fi selectat cu fuzibilul BODLEVEL la
valoarea 2.7V (BODLEVEL neprogramat), sau la valoarea 4.0V (BODLEVEL
programat), funcţie de valoarea utilizată pentru tensiunea de alimentare.
• Nivelul de declanșare are asociat şi un histerezis VHYST pentru a garanta o detecţie
sigură şi a discerne între evoluţia crescătoare (V+ ) şi cea descrescătoare(V- ):
– VBOT+ = VBOT + VHYST /2 şi VBOT- = VBOT - VHYST /2.
• Circuitul BOD poate fi activat sau dezactivat prin intermediul unui fuzibil numit
BODEN.
• Când BOD este activat (fuzibilul BODEN programat) şi VCC scade la o valoare sub
nivelul de declanșare (VBOT - în figura), reset-ul intern este activat imediat.
– Când VCC crește deasupra nivelului de declanşare (VBOT+ în figura) numărătorul de
întârziere va genera perioada suplimentară de reset intern tOUT.
– Circuitul BOD va detecta o scădere a VCC numai dacă tensiunea se menţine sub nivelul de
declanșare mai mult decât un interval minim tBOD.
10
Conceptul de ceas de gardă (watchdog) si
utilizarea lui
• Un temporizator de tip ceas de gardă (watchdog timer) este un
subsistem hardware/software al unui sistem de calcul care declanșează
un Reset - o inițializare hardware- (sau o altă acţiune corectivă de aceiași
natură) atunci când programul aplicației, datorită apariției unei stări de
defect temporar sau permanent (având ca efect tipic gen programul se
“agață”, nu mai răspunde, se “înțepenește”, etc.), nu mai reușește să
“trateze” (tipic să inițializeze) acest temporizator in mod periodic si
regulat (la intervale previzibile de timp)
• Scopul final este de a readuce sistemul într-o stare cunoscută si, dacă
este posibil, o stare de funcționare normală sau sigură
– De regula aceasta stare este starea după reset (inițializare hardware)
• Un temporizator de tip ceas de gardă poate fi de asemenea utilizat pentru a
aduce un sistem de calcul utilizat pentru control (controler) de tip fail-safe
într-o stare sigură, de exemplu, cu motoarele oprite, cu ieșirile de înaltă
tensiune si cu alte sub-sisteme periculoase similare oprite/inactive.
– Un sistem fail-safe este un sistem zis cu securitate incorporată, care in cazul
apariției unui defect ajunge într-o stare sigură, prescrisă anterior
– Utilizarea acestor sisteme fail-safe este esențială in aplicațiile critice din
avionică, transport feroviar, industria automobilului sau domeniul medical
11
Ceasul de gardă (watchdog)
• Pentru toate sisteme incorporate (embedded systems) care nu
pot fi supravegheate in mod constant de un operator uman si
care trebuie să fie auto-suficiente, utilizarea unei astfel de
tehnologii este obligatorie (nu există nimeni care să apese pe
butonul de reset dacă sistemul nu mai reacționează!)
• In mod riguros(si din considerente de fiabilitate), un temporizator de
tip ceas de gardă trebuie să fie exterior sistemului (să nu fie realizat
pe acelaşi microcircuit cu unitatea centrala), reducând probabilitatea
ca același defect să afecteze sistemul de calcul si temporizatorul
simultan
• Atunci când el este inclus ca un periferic dedicat, ca in cazul multor
microcontrolere (inclusiv AVR), soluţia este una de compromis preţ
de cost-siguranţă in funcţionare
• Oricum ar fi implementat, mărimea lui de “ieşire” trebuie să
controleze direct intrarea de reset (iniţializare hardware) a sistemului
de calcul (microcontroler, microprocesor, etc. )
• In varianta sa cea mai simplă el este un temporizator/numărător
care, dacă nu este reîncărcat/resetat/rearmat periodic, ajunge la
depăşire (Overflow, Time-Out), aceasta condiție ducând la Reset-ul
12
CPU
AVR 8 biti: Temporizatorul ceasului de gardă
• Watchdog Timer (WDT) AVR este de fapt un numărător care are un semnal de ceas care
provine de la un oscilator RC separat on-chip (intern, independent de ceasul sistem)
de 128 kHz (asta la ATiny 2313, la alte variante poate avea alte valori).
• WDT va genera un reset sau o întrerupere dacă numărătorul ajunge la valoarea maximă
(la depășire).
• In funcționarea normală utilizatorul (aplicația software) trebuie să folosească
instrucțiunea WDR - Watchdog Timer Reset – pentru a reporni numărătorul de la 0 înainte
ca acesta să ajungă la valoarea maximă, in caz contrar el generând un reset sau o
întrerupere
• Pentru o evita a dezactivare/oprire accidentală a acestui sub-sistem trebuie utilizate
secvențe speciale de operații in momentul in care se lucrează cu biții din registrul
WDTCR- Watchdog Timer Control Register
13
Reset-ul prin ceasul de gardă (Watchdog Reset)
• Cu ajutorul divizorului (watchdog prescaler) se pot programa (alege)
intervale pentru declanșarea ceasului de garda (durată totală a ciclului de
numărare) intre 16msec si 8 sec.
• Dacă se dorește utilizarea acestui sub-sistem fuzibilul WatchDog
always ON (WDTON), trebuie să fie programat (in caz contrar acest
temporizator poate genera doar o cerere de întrerupere)
– Atunci când ceasul de gardă generează o depășire (Time-out, ca urmare a ne
reîncărcării/repornirii lui în timp util), el va genera un impuls scurt de reset cu durata de un
ciclu de ceas (1CK), iar pe frontul căzător al acestuia va fi declanșat numărătorul de
întârziere reset care la rândul lui va genera perioada suplimentară de reset intern tOUT.
14
Fuzibile Reset ATTiny2313-
Proteus VSM
Modelele AVR nu au
toate fuzibilele, de ex.
lipsesc fuzibilele
BODLEVEL!
15
Fuzibilul RSTDSBL si utilizarea pinului
/RESET
• Pentru variantele de microcontrolere AVR 8 biți la care
pinul /RESET poate avea si funcții alternative de intrare-
ieșire (ca parte a unui port), cum ar fi:
– ATTiny2313: /RESET si PA2
– ATMEGA48, ATMEGA88: /RESET si PC6
– ATMEGA329: /RESET si PG5,
– etc.
in setul de fuzibile există un fuzibil numit RSTDSBL
(external Reset Disable) care trebui să fie programat
(Programmed) pentru ca pinul respectiv să poată fi
programat si utilizat ca un pin de intrare/ieșire obișnuit;
altcumva el poate fi utilizat eventual doar ca intrare de
reset extern!
16
Intrările și ieșirile numerice (porturile de
intrare/ieșire)
• Toate microcontrolerele AVR 8 biți au un număr oarecare de intrări- ieșiri
numerice de uz general, grupate din punct de vedere funcțional în “porturi” de
intrare/ ieșire (I/O ports).
• Denumirea lor (Microchip/Atmel) este PORTA, PORTB, PORTC, PORTD, etc.
– Ele permit realizarea de cicluri de acces de tip Read-Modify-Write (citește –
modifică - scrie).
• Toti pinii asociați acestor porturi sunt bidirecționali
• Direcția unui pin (intrare si/sau ieșire) al portului poate fi schimbată individual,
fără a schimba şi direcția oricărui alt pin din același port
– Direcția, adica utilizarea sa ca intrare sau ieșire, este programabilă individual
pentru fiecare pin din port
• Dacă un pin este programat ca fiind de tip ieșire, tipul de ieșire este si el
programabil, prin activarea sau dezactivarea rezistoarelor de sarcină interne
Rpu= x10KOhmi:
– De tip cu drenă în gol (fără rezistență internă de sarcină) sau
– Normală, cu rezistență interna de sarcină, către Vcc(Rpu pull-up)
Deși par a exista porturile A, B, C, D, etc. ele nu sunt “egale” intre ele:
nu au același număr de pini disponibili (biţi)- la fel ca si in cazul unor alte variante de
AVR cu număr relativ redus de pini, pentru acest tip de AVR anumite porturi sunt
implementate doar parțial, adică nu au toți cei 8 biți
18
Pin-out (conexiunile externe) pentru ATMega
328 (capsula PDIP28)
Deși par a exista porturile A, B, C, D, etc. ele nu sunt “egale” intre ele:
nu au același număr de pini disponibili (biţi)- la fel ca si in cazul unor alte variante de
AVR cu număr relativ redus de pini, pentru acest tip de AVR anumite porturi sunt
implementate doar parțial, adică nu au toți cei 8 biți
Obs. ATMega 328 este microcontrolerul utilizat de Arduino Uno. 19
Pin-out (conexiunile externe) pentru ATMega
2560 (capsula TQFP100)
In capsula de mai sus (TQFP100) sau in cea de tip CBGA100 de mai sus are 10 porturi:
PA…PL, din care doar portul PG este implementat incomplet (are doar 6 biti). 20
Obs. ATMega 2560 este microcontrolerul utilizat de Arduino 2560.
Intrările și ieșirile numerice (porturile I/O) –
caracteristici electrice
• Intrările sau ieșirile AVR 8 biti sunt compatibile TTL sau LVTTL (funcție si de
tensiunea de alimentare Vcc)
• Buffer-ele de ieșire au capacitatea de a absorbi/debita un curent IOL/IOH de
până la 20mA (la Vcc=5V) putând comanda astfel direct un LED sau optocuplor
• Capacitatea de a absorbi/debita curent depinde însă de tensiunea de
alimentare, de exemplu la Vcc= 3 V curentul maxim absorbit/debitat scade la
10mA.
• Toți pinii de port pot avea rezistoare de sarcină individuale interne, cu o
rezistență care nu depinde de tensiunea de alimentare (Rpu=20..50kOhmi).
• De asemenea toți pinii au diode de protecție atât către Vcc cât și către masă
după cum se observă în figură
– In figura de mai jos Cpin (xpF) este capacitatea parazită asociată pinului, are
conteaza in regim dinamic
Schema electrică
echivalentă a unui “pin”
21
Intrările şi ieșirile numerice AVR 8 biti
(porturile I/O) - caracteristici electrice (de cc)
Tiny2313
Mega32
Atenție: Suma dintre IOL si/sau IOH de pe toate porturile existente nu trebuie să
depășească 200mA, iar de pe un singur port (de exemplu portul A) 100mA (valorile
depind însă si de tipul de încapsulare)
22
Intrările şi ieșirile numerice AVR 8 biti
(porturile I/O)- configurarea
• Referitor la notațiile utilizate în continuare (notatii Microchip/Atmel):
cu “x” s-a notat litera care identifică portul de 8 biţi (x= A, B, C, …), şi
cu “n” numărul bitului din port (n=0..7).
• Notația generala ar fi PORTxn, iar ca un exemplu particular bitul 6
din portul A va fi notat cu PORTA6 sau PA6
• Pentru fiecare din porturile existente sunt alocate trei locații de
memorie (trei registre) în spațiul I/O:
– registrul de date de ieşire – notat PORTx,
– registrul pentru stabilirea direcţiei datelor – notat DDRx (Data
Direction Register),
– şi pinii portului (registrul de date de intrare) – notat PINx.
• Locațiile corespunzătoare pinilor de intrare ai portului PINx pot fi
numai citite, în timp ce registrul de date PORTx şi registrul pentru
direcția datelor DDRx pot fi scrise şi citite.
• Majoritatea acestor pini de port au şi funcții alternative relevante
pentru perifericele microcontrolerului, existând un mecanism de
multiplexare adecvat.
– Activarea şi utilizarea funcțiilor alternative pe unii dintre pinii portului nu
influențează folosirea celorlalţi pini din port ca intrări/ieşiri de uz general.
23
Bitul PUD: exemplu ATTiny2313 si ATMega
328
ATTiny2313
ATMega 328
Portul B
este
complet -
8 pini/biţi
26
Porturile I/O ca intrări/ieșiri de uz general –
comutarea intrare-ieșire si invers
• Dacă PORTxn este =“1” când pinul este configurat (cu DDRxn) ca
ieșire, pinul portului va fi şi el în “1”.
• Dacă PORTxn este =“0” când pinul este configurat ca ieșire, pinul
portului va fi şi el în “0” .
– Când se trece de la o stare tip intrare High-Z ({DDxn, PORTxn} = 0b00)
la o stare tip ieşire în „1” ({DDxn, PORTxn} = 0b11), apare o stare
intermediară, fie cu rezistoarele de sarcină activate ({DDxn, PORTxn}
= 0b01) fie cu ieşirea in „0” ({DDxn, PORTxn} = 0b10).
• În mod normal, starea cu rezistoarele de sarcină activate este
complet acceptabilă, deoarece in cazul unei intrări având o
impedanță mare nu se va observa diferența între un pin in starea “1”
şi prezența rezistoarelor de sarcină.
– Dacă este însă cazul ieşirii „0”, bitul PUD din registrul SFIOR poate fi
setat pentru a dezactiva toate rezistoarele de sarcină .
• Când se trece de la o stare cu intrarea cu rezistoare de sarcină la o
ieșire în „0” apare aceeași problemă.
– Utilizatorul trebuie să folosească starea tri-state ({DDxn, PORTxn} =
0b00) sau ieșire “1” ({DDxn, PORTxn = 0b11) ca un pas intermediar.
27
Porturi I/O: configurația implicită (după
reset), intrare, fără Rpull-up
Vcc
DDx
0 R Pull-Up
PORTx
? ?
Direcţia: INTRARE
R Pull-Up: DECONECTATA (OFF)
Porturi I/O: intrare, cu RPull-Up conectat
DDx Vcc
0 RPull-Up
PORTx
? 1
Direcţie: INTRARE
RPull-Up: CONECTATA (ON)
Porturi I/O: ieşire, in “1”
Vcc
DDx
1 RPull-Up
PORTx
1 1
Direcţie: IEŞIRE
RPull-Up: DECONECTATA (OFF)
Exemple elementare de cod, porturi I/O
31
Exemple de cod: programare porturi
In limbaj de asamblare AVR (asamblor AVR Studio 4):
Operatorul “<<” este cel de deplasare (shift) stânga, iar “ | “ este un SAU
logic la nivel de bit, identici cu operatorii bitwise din C 32
Exemple de cod: programare porturi
In limbaj C (WinAVR):
unsigned char i;
/* Definirea rezistenţelor de sarcina şi setarea ieşirii
in 1. */
/* Definirea direcţiei pentru pinii portului */
PORTB =(1 << PB7) | (1 << PB6) | (1 << PB1) | (1 << PB0);
DDRB = (1 << DDB3) | (1 << DDB2) | (1 << DDB1) | (1 <<
DDB0);
/* Inserarea unei instrucţiuni NOP */
_nop();
/* Citirea pinilor portului */
i = PINB
34
Exemple de cod, manipulare biţi
35
Exemple de cod, măşti
PB0 IF
“0” LED
PD0
Comutator
LED-ul se va aprinde când
PB0=“0”, pinul PB0 absorbind
Masa (Gnd) curentul de conducţie directă
IF al LED-ului
39
Ce facem cu pinii I/O neutilizați / “neconectați”
46
Întreruperi si rutine de tratare a
întreruperilor
• Modalitatea programată de intrare/ieșire este afectată in primul
rând de faptul ca participanții la o astfel de tranzacție I/O pot avea
viteze de acces la informație mult diferite si diverse
– Luând ca exemplu tastatura, bănuim că un sistem de calcul (un CPU)
poate citi de mii si mii de ori mai rapid decât un operator poate tasta
(fie el si un Speedy Gonzalez…)
• Astfel, “partenerul” rapid va trebui să aștepte după “partenerul”
lent, ducând la o irosire masivă de resurse (de exemplu putere
computațională): astfel intre 2 prelucrări succesive nu se face
nimic, doar se așteaptă, irosindu-se timpul unității centrale
•
• Asincronismul dintre un sistem de calcul, sincron prin natura
lui, si lumea exterioară lui, cu care interacționează, necesită
de cel mai multe ori soluții mai eficiente.
Întoarcere din
întrerupere
Citeşte/prelucrează
Face tot felul de
datele provenind
lucruri utile.. de la tastatura
Întrerupere
Programul “principal”:
Alte activităţi ale CPU DA
Am terminat?
NU
(Sub)rutina de tratare a
întreruperilor 49
Observații cheie legate de utilizarea
întreruperilor
• Deoarece unitatea centrală nu mai trebuie să execute
bucla/buclele de așteptare, ea poate realiza, in marea
majoritate a timpului, alte sarcini utile, până când va fi
întreruptă din nou.
• Aceasta îmbunătățește utilizarea resurselor CPU si
a sistemului/timpului de calcul in ansamblu, având
ca efect si un timp mai bun de răspuns pentru toți
“utilizatorii”
• Prelucrarea I/O se poate realiza astfel intr-un mod
total asincron, fără a face nici o ipoteză legată de
momentul apariției evenimentelor legate de
intrări/ieșiri
• Orice microprocesor sau microcontroler modern are
un sub-sistem de întreruperi hardware, care la
rândul lui are si propria interfață de programare, cu
registre de stare si control / comanda
50
Multiplicitatea surselor de întreruperi
• Întreruperile pot proveni de la mai multe dispozitive de intrare/ieșire (de la mai
multe surse de întreruperi )
• Intr-un sistem tipic de calcul cereri de întrerupere ar putea fi cauzate de (doar
câteva exemple):
– Defecte ale surselor de alimentare: cădere iminenta a sursei de alimentare
– Sisteme de temporizare/numărare: depășiri
– Dispozitive de intrare/ieșire, convertor analog - numeric, interfață serială
asincronă: terminarea operațiilor de conversie sau transfer
– Apariția unor erori de natura hardware: eroare de paritate memorie, etc.
– Apariția unor erori de natura software: împărțire la zero, etc.
• In acest context rezulta probleme specifice:
– Care sunt prioritățile acestor întreruperi: dacă mai multe cereri de
întreruperi apar simultan care va fi procesata prima, o întrerupere poate fi la
rândul ei întreruptă?
– Cum se face identificarea (individualizarea) întreruperilor: funcție de
natura specifică a întreruperii vor exista rutine de tratare diferite, care din
ele se va fi selectată si se va executa?
• Cum știm de fapt cine a generat de fapt cererea de întrerupere?
51
Prioritățile întreruperilor
• Când putem să-i permitem unei întreruperi să întrerupă la rândul
ei rutina de tratare a unei alte întreruperi? De ce? Care
întrerupere va fi tratată următoarea?
– In mod tipic prioritățile pot fi asignate de proiectant si programator
diverselor surse de întreruperi conform unor criterii funcționale cum ar
fi: care sunt penalitățile dacă nu se reacționează in timp util, utilitatea
valorilor returnate de rutina de tratare a unei întreruperi specifice, etc.
– Astfel următoarea ordonare a priorităților, de la mai mare la mai mic, ar
putea fi tipică:
• Defect sursă alimentare; Temporizări; Erori; I/O;
• Alocarea priorităților se poate face de programator prin
intermediul unor biți dintr-un registru de comanda sau este
impusă de arhitectura sistemului de întreruperi
• Eventual fiecare sub-clasă de priorități ar putea avea drept
corespondent un bit intr-un registru de stare al unui semnal
transmis către CPU.
– Aceasta ar fi o cerere de întrerupere specifică pentru această sub-clasă
de priorități.
52
Identificarea întreruperilor
• Selecția rutinei de tratare a întreruperii adecvate poate fi
rezolvată in mai multe feluri
• In general, CPU trebuie să identifice sursa întreruperii
(eventual începând cu cea având mai mare prioritate)
pentru a o trata corespunzător
• Identificarea poate fi realizată folosind o interogare
software (software polling) a întreruperilor: rutina de
tratare a întreruperii este cea care “caută” prin interfeţele
de intrare/ieșire (registrele de stare asociate), începând cu
cea mai prioritară interfață
• Odată ce a ajuns la prima interfață care are o cerere de
întrerupere activă, va selecta rutina de tratare a
întreruperii corespunzătoare acelui dispozitiv (interfețe)
• Sincronizarea cu dispozitivul care a generat întreruperea
este facuta pe baza un semnal / unei condiții provenind de
la CPU indicând ca CPU este gata să proceseze
întreruperea (Interrupt Acknowledge ), astfel încât
acesta să o identifice, eventual sub forma unui vector de
întrerupere (interrupt vector).
53
Vectorii de întrerupere
• Un vector de întreruperi face parte dintr-o tabela de
vectori de întrerupere care este o structură de date
care asociază o listă de rutine de tratare a întreruperilor
cu o listă de cereri de întreruperi
– Vectorul de întrerupere este primit de CPU care îl va utiliza ca un
pointer (indicator)/ sau adresa a punctului de început a rutinei de
tratare a întreruperilor, funcție de natura si sursa întreruperii.
• O tabelă de vectori de întrerupere, o tabelă care conține
mai mulți vectori de întrerupere, reprezintă modalitatea
tipică de a asocia fiecare sursă de întrerupere cu o
(sub)rutină de tratare specifică a întreruperii (RTI)
• Conținutul/valoarea acestor vectori indică (direct -
adresa sau indirect - adresa adresei, funcție de familia
concretă de microcontrolere/ microprocesoare) adresa
de început a rutinei de tratare a întreruperii dorite (de
unde se execută prima instrucțiune a RTI)
• Si AVR 8 biți folosește o astfel de tabelă de vectori de
întrerupere
54
Activarea si dezactivarea
întreruperilor (interrupt enable/disable)
• Deși utilizarea priorităților, intr-un anume sens, deja
dezactivează întreruperile de priorități mai mici
nepermițându-le să întrerupă o rutină de tratare a
întreruperii a unei întreruperi mai prioritare, de multe ori este
necesară si o dezactivare dinamică (pe parcursul
execuției programului) sau statică (de la începutul
execuției programului in cazul in care întreruperile
respective nu sunt utilizate )
• Un exemplu activare/dezactivare dinamica ar fi existenţa a
două procese, unul de intrare si unul de ieşire, de exemplu:
– Procesul de intrare citește un caracter de la tastatură si procesul de
citire afișează acest caracter pe o consolă.
– Intrarea si ieșirea trebuie realizate aici in secvență, alternativ
– Pentru a sincroniza cele doua procese s-ar putea utiliza activarea/
dezactivarea întreruperilor pentru cele două surse asociate celor
doua procese.
55
Activarea si dezactivarea întreruperilor(2)
57
Care ar fi dezavantajele utilizării
întreruperilor?
• Întreruperile sunt asincrone si “eliberează” CPU de alte sarcini, dar
numai dacă este realizată comutarea corectă si eficientă a contextului
• Comutarea contextului este prețul plătit (ca timp de calcul si resurse
de memorie) la fiecare procesare a unei întreruperi: trebuie sa se
scrie si sa se citească informație in/din memorie
• Dacă întreruperile sunt foarte “dese” aceasta comutare a
contextului s-ar putea să consume mai mult timp decât
activitățile utile!
• Ce alternative avem:
– De ce nu am putea elibera (aproape) total CPU de activitatea de tratare a
intrărilor/ieșirilor efectuată de rutinele de tratare a întreruperilor?
– In practică aceasta se poate realiza cu ajutorul unui mecanism
(hardware) de acces direct la memorie (DMA- Direct Memory Acces)
– DMA este utilizat tipic când se dorește un transfer masiv de date de
intrare/ieșire
– Un subsistem DMA este prezent la majoritatea microcontrolerelor de 32 de
biti
– In cadrul familiilor AVR de 8 biți un astfel de mecanism este disponibil la
familia AVR XMEGA si la noile variante AVR Microchip (seriile 0,1,2)
– Daca va interesează subiectul DMA:
https://en.wikipedia.org/wiki/Direct_memory_access
58
Exemplu de interogare cu bucla de așteptare.. In
limbaj C
Cum s-ar realiza interogarea: Dacă programul mai are si alte sarcini de
realizat:
main () main ()
{ {
while(1){/*bucla fara sarcina1();
sfarsit*/ Interogheaza_Tast
Interogheaza_Tast(); sarcina2();
Interogheaza_Tast ();
} …
}
Cum s-ar realiza interogarea tastaturii: Efortul de calcul suplimentar:
• Citim registrul de stare ca să vedem • Efort = “cat de des trebuie să
dacă o tastă e apăsată, dacă este o interogăm” × “ce presupune
citim din registrul de date interogarea ca prelucrări”
• Trebuie să o facem la fiecare N Cat este de uşor de programat? :
msec, intervalul minim de timp in • Este dificil de “combinat” codul pentru
care o tastă poate fi apăsată, interogare/bucla de aşteptare cu
altcumva apăsarea de tastă de către sarcinile normale de prelucrare:
utilizator poate fi pierdută! depinde de cate bucle avem, de
natura sarcinilor de prelucrare normale
59
Întreruperi…. in C
char input_buffer[1024]; void
rutina_tratare_intrerupere_tas
main() tatura(void)
{ {
initializeaza_intreruperi (); Interogheaza_Tast ();
/* scrie in input_buffer*/
while (1){ …….
sarcina1(); }
sarcina2();
Detaliile depind si de natura sistemului de
calcul:
/* prelucreaza ce gasesc in • PC: Tipic sistemul de operare gestionează
input_buffer */ întreruperile
………. • Sisteme incorporate, controlere: daca nu
/* multe alte sarcini..*/ există un sistem de operare, aplicaţia
…….. trebuie să trateze întreruperile
}
}
60
Un model generic de programare utilizând
întreruperile
Aşteaptă
Întoarcere -I Întoarcere -I Întoarcere -I
evenimente
Procesare
Memorie
61
Sistemul de întreruperi la AVR 8
biți
• Arhitectura AVR 8 biți permite tratarea cererilor de întrerupere
provenind de la mai multe surse diferite, acestea fiind tipic
asociate unor periferice, cu ajutorul unor vectori de
întrerupere care aici sunt adrese fixe de tratare.
– De exemplu, pentru ATMega64 există 34 de surse potențiale de
întrerupere, ATTiny2313 are “doar” 19.
• Există şi posibilitatea ca un eveniment extern să declanșeze
o cerere de întrerupere: exista posibilitatea tratării unor
întreruperi externe.
• În mod convențional si reset-ul (iniţializarea) hardware pentru
un AVR 8 biti poate fi descris ca fiind o întrerupere specială,
cea mai prioritară şi, datorită faptului că ea nu poate fi
dezactivată, numită şi nemascabilă.
– Toate celelalte întreruperi sunt descrise ca mascabile putând fi
dezactivate/activate individual si global
62
Sistemul de întreruperi AVR 8 biți: Întreruperi
externe si Reset pentru ATTiny2313
63
Sistemul de întreruperi AVR 8 biți :
vectorii de întrerupere
• ATENŢIE:
• Funcție de varianta de AVR, același tip periferic poate avea
vectori (adrese) diferite de tratare
• Mai mult, pentru variantele MEGA si XMEGA care au si o
zona de Bootloader in memoria program, tabela de vectori
poate fi relocata corespunzător prin programarea unui fuzibil
sau a unui bit dintr-un registru (de exemplu IVSEL din
MCUCR) astfel încât Bootloaderul să poată si el utiliza
întreruperile
• Trebuie consultată neapărat tabela de vectori si eventual
facilitățile de relocare a lor din foaia de catalog a variantei
respective!
– De exemplu pentru ATTiny2313 comparatorul analogic are
vectorul 11 (la adresa 0x000A), iar pentru un anumit ATMega
același periferic are vectorul 19 (0x0024), s.a.m.d
64
Cea mai prioritară
Prioritate
descrescătoare
Reset
Prioritate
descrescătoare
68
Cea mai puţin prioritară
Tabela de vectori pentru ATMega32
69
Întreruperi externe si Reset la ATMega 328
(capsula PDIP28)
Pe langa INT0 si INT1 mai exista (tot ca functii alternative ale pinilor) PCINT0
la PCINT23: aproape toti pinii pot fi utilizati pentru intreruperi externe!
70
Tabela de vectori pentru ATMega 328
71
Sistemul de întreruperi AVR 8 biți
• Schema utilizată este una vectorială, cu adrese (vectori) de tratare fixe, la fel
ca la multe alte familii de microcontrolere.
• Pentru fiecare întrerupere există rezervat un vector separat, având
dimensiunea fixă de 2 octeți (1 cuvânt), la fel ca și pentru reset, în zona
de început a memoriei de program.
• Toate întreruperile (mai puțin reset-ul) au asignat un bit de activare
individuală care trebuie să fie “1” logic, împreună cu bitul I de activare
globală al întreruperilor în registrul de stare, pentru a se putea utiliza/trata
întreruperea respectivă.
– Prin intermediul acestui bit se spune ca întreruperile pot fi mascate (bit in “0”) sau nu (bit in “1”)
• Bitul I din registrul de stare SREG acționează ca o mască globală (pentru
toate întreruperile) si este controlat de instrucțiunile (limbaj de asamblare)
dedicate SEI (I=“1”) si CLI (I=“0”)
• Întoarcerea dintr-o subrutina de tratare a întreruperii se face cu
instrucțiunea dedicata RETI
– Funcție de valoarea curentă a numărătorului program PC, întreruperile mai pot fi în mod
automat dezactivate atunci când biții (fuzibilele) “Boot Lock” BLB02 sau BLB12 sunt programați
(la un ATMEGA).
• Aceasta caracteristică poate eventual îmbunătăți “protecția” software-ului la copieri neautorizate.
72
Sistemul de întreruperi AVR 8 biți
• Cele mai joase adrese în spațiul de memorie de program, în zona de aplicaţie, sunt
implicit definite ca vectorii de reset şi întrerupere.
• Această listă definește şi nivelele de prioritate ale diferitelor întreruperi.
• Adresa cea mai de jos are nivelul de prioritate cel mai înalt.
– Astfel reset-ul are cea mai mare prioritate, urmat de INT0 – cererea de întrerupere externă 0,
ş.a.m.d.
• Deși vectorii de întrerupere sunt la adrese fixe, ei pot să fie “mutaţi” de la începutul
zonei de aplicație la începutul zonei de Bootloader setând bitul IVSEL în registrul de
control general al întreruperilor GICR (General Interrupt Control Register) – doar la
variantele cu Zona Boot (ATmega).
– Vectorul de reset poate fi, de asemenea, mutat la începutul zonei de Bootloader programând fuzibilul BOOTRST
– doar la ATMega sau Xmega.
• Când o întrerupere este recunoscută şi tratată, bitul I din SREG este
șters şi toate întreruperile sunt dezactivate.
• Utilizatorul poate eventual, in rutina de tratare a întreruperii, să scrie bitul I în “1” logic
pentru a (re)activa întreruperile.
– Toate întreruperile active pot atunci să întrerupă rutina de tratare a întreruperii curente: aşa se
pot imbrica întreruperile (întreruperea întreruperii..)
– Bitul I este în mod automat setat când are loc execuția unei instrucțiuni de revenire
(întoarcere) din rutina de tratare a întreruperii (RETI), făcând posibilă tratarea unei
noi întreruperi: aceasta este diferența esențială intre instrucțiunile RETI si RET
(întoarcerea dintr-o subrutină obișnuită)
73
Exemple: bitul I, biţi de activare întrerupere
- Interrupt enable
74
Tipuri de întreruperi AVR 8 biți: întreruperi
bazate pe un eveniment memorat
• Există în două tipuri de întreruperi din punct de vedere al
comportării/utilizării cererii de întrerupere.
• Acest prim tip de întrerupere este declanșat de un eveniment care
setează un bit (un flag) asociat unei anume întreruperi: cererea de
întrerupere este deci memorata
• La tratarea întreruperii în numărătorul program PC se aduce automat
vectorul corespunzător pentru a se putea executa rutina de tratare a
întreruperii, iar bitul corespondent întreruperii este setat.
• Acești biți asociați întreruperilor pot să fie însă șterși de utilizator
scriind un “1” logic în poziția bitului respectiv.
• Dacă apare o cerere de întrerupere în timp ce bitul corespondent
activării întreruperii este șters, bitul va fi setat şi memorat până când
întreruperea este activată sau bitul este şters prin soft.
• Similar, dacă una sau mai multe cereri de întrerupere apar în timp ce
bitul I este șters, bitul corespondent întreruperii va fi setat şi memorat
până când bitul I este setat din nou, şi atunci cererile vor fi executate în
ordinea priorității.
• Exemple (AVR 8 biti): depășirile in cazul sistemului de temporizare
/numărare
75
Tipuri de întreruperi AVR 8 biți: întreruperi bazate
pe o condiție (nememorată)
• Acest al doilea tip de întrerupere va declanșa o întrerupere doar
atât timp cât condiția de întrerupere este activă (adevărată) si
întreruperea poate fi tratată.
– Aceste întreruperi nu au biți asociați cererii de întrerupere (nu există
fizic o memorare a ei) dar tratarea ei (dacă are loc) este similară
primului tip
– Dacă este posibilă tratarea întreruperii, atunci în numărătorul
program PC se aduce automat vectorul corespunzător pentru a se
putea executa rutina de tratare a întreruperii
– Dacă însă condiția de întrerupere dispare înainte ca
întreruperea (cererea) să fie recunoscută de unitatea centrala,
întreruperea nu va fi luata in considerare şi nu va fi tratată
(informația asociată ei va fi pierdută!).
• La întoarcerea (cu instrucțiunea RETI) dintr-o rutină de tratare a unei
întreruperi în programul principal se vor executa una sau mai multe
instrucțiuni înainte ca orice nouă cerere de întrerupere să poată fi
recunoscută şi tratată.
• Exemple (AVR 8 biți): recepția unui caracter pe portul serial (USART)
76
Întreruperi AVR 8 biți: bitul I din SREG
• Registrul de stare SREG NU este în mod automat
memorat (salvat) când se intră în rutina de tratare a
unei întreruperi şi nici nu este restaurat când se
revine din rutină.
– Această operație trebuie să fie realizată de utilizator
(aplicație), dacă este vorba de limbaj de asamblare
– Pentru limbajul C ea este realizată de compilator
• Când se folosește instrucțiunea CLI pentru a dezactiva
global întreruperile (ștergerea bitului I), ele vor fi imediat
dezactivate.
– Nici o întrerupere nu va fi executată după execuția instrucțiunii
CLI, chiar dacă se ea apare simultan cu instrucțiunea CLI.
• Când se folosește instrucțiunea SEI(setarea bitului I)
pentru a activa global întreruperile, instrucțiunea ce
urmează instrucțiunii SEI va fi executată înaintea de
tratarea oricărei cereri de întrerupere
77
Sistemul de întreruperi AVR 8 biți: timpul de răspuns
al unității centrale la o cerere de întrerupere
Timpul de răspuns la o cerere de întrerupere (numit si
latența întreruperii - interrupt latency ) pentru toate
întreruperile active este de minim patru cicluri (perioade)
de ceas sistem.
• După patru cicluri de ceas rutina de tratare a întreruperii
curente va începe să fie executată.
– În timpul celor patru cicluri de ceas, valoarea PC-ului
corespunzătoare instrucțiunii următoare (doi octeți) este
memorată în stivă, indicatorul de stivă SP este decrementat cu
două unități, şi bitul I din SREG este șters (dezactivare globală a
întreruperilor).
• Tratarea întreruperii presupune un salt la rutina de
tratare a întreruperii şi efectuarea acestui salt durează
încă trei cicluri de ceas.
• Dacă mai apare o cerere de întrerupere în timpul execuției
unor instrucțiuni care durează mai mult de un ciclu (de
exemplu 2 sau 4 cicluri), această instrucțiune multi-ciclu va
fi finalizată înainte ca întreruperea să poată fi tratată.
78
Sistemul de întreruperi AVR 8 biți: timpul de
răspuns in modurile cu putere redusă
• Dacă apare o cerere de întrerupere în timp ce unitatea
centrală este în modul de putere redusa “Sleep”, timpul
de răspuns la cererea de întrerupere este mărit cu încă
patru cicluri de ceas.
– La aceasta se va adăuga și timpul de repornire (de trezire) dintr-
un mod de putere redusa „sleep”.
• Timpul de revenire (întoarcere) din rutina de tratare a
unei întreruperi este de patru cicluri de ceas.
– În timpul acestor patru cicluri ceas, PC-ul (cei doi octeţi) este
extras din stivă, indicatorul de stivă SP este incrementat cu două
unități şi bitul I din SREG este setat (reactivare globală a
întreruperilor)..
• Vom mai reveni asupra descrierii si utilizării
sistemului de întreruperi pentru AVR 8 biți
79