Biologie | Chimie | Didactica | Fizica | Geografie | Informatica | |
Istorie | Literatura | Matematica | Psihologie |
1. Modul de tratare a intreruperilor .
AT90S8535 pune la dispozitie 16 surse de intrerupere diferite. Fiecare dintre acestea are cate un bit de activare/dezactivare precum si cate un flag care semnalizeaza aparitia cererii intreruperii respective. Flagul este setat de sursa de intrerupere in momentul in care se indeplineste conditia respectiva, iar daca bitul de activare este setat se sare la rutina de tratare a acelei intreruperi. Exista de asemenea un bit general de activare/dezactivare a intreruperilor, bitul I din registrul de stare - SREG. Bitii de activare/dezactivare individuali si bitul I din registrul de stare trebuie sa fie setati (in 1 logic) pentru a activa intreruperea. Acesti biti si flagurile de semnalizare se vor prezenta odata cu prezentarea diverselor blocuri care pot genera intreruperi.
In momentul in care se genereaza o intrerupere, in numaratorul de program se incarca automat o adresa din memoria de program, numita vector de intrerupere, astfel ca microcontrolerul executa un salt la acea adresa. Evident, vechiul continut al numaratorului de program se salveaza in stiva, iar indicatorul de stiva este decrementat corespunzator.
Adresele cele mai de jos din spatiul memoriei de program sunt in mod automat definite ca vectori destinati resetarii si intreruperii, formand asa-numita tabela de intreruperi. Deoarece fiecare vector de intrerupere are alocata doar o locatie in aceasta tabela, acolo se plaseaza o instructiune de salt la subrutina de tratare a intreruperii respective, subrutina care se scrie de regula in partea finala a programului, dupa bucla principala. Exceptie face prima locatie, care este rezervata pentru Reset, si unde se plaseaza o instructiune de salt catre inceputul programului. Acest inceput al programului trebuie sa se afle dupa tabela de intreruperi, de exemplu la adresa $0011 pentru microcontrolerul AT90S8535, si se plaseaza acolo folosind o directiva ORG.
Lista completa a acestor vectori este aratata in tabelul 3.1. Din tabel rezulta si nivelele de prioritate ale diferitelor intreruperi. Cu cat adresa este mai joasa, cu atat nivelul de prioritate este mai ridicat. RESET are cea mai inalta prioritate. Urmeaza apoi INT0 - Cererea de Intrerupere Externa 0 etc.
Tabelul 3.1. Vectorii de resetare si intrerupere.
Vector numarul |
Adresa din program |
Sursa |
Conditia generatoare a intreruperii |
RESET |
Semnal pe pinul de Reset si resetare watchdog |
||
INT0 |
Cerere de intrerupere externa 0 |
||
INT1 |
Cerere de intrerupere externa 1 |
||
TIMER2 COMP |
Egalitate de comparatie la Timer/Counter2 |
||
TIMER2 OVF |
Depasire la Timer/Counter 2 |
||
TIMER1 CAPT |
Eveniment de captura la Timer/Counter1 |
||
TIMER1 COMPA |
Egalitate de comparatie cu registrul A la Timer/Counter1 |
||
TIMER1 COMPB |
Egalitate de comparatie cu registrul B la Timer/Counter1 |
||
TIMER1 OVF |
Depasire la Timer/Counter 1 |
||
TIMER0 OVF |
Depasire la Timer/Counter0 |
||
$00A |
SPI, STC |
Terminarea unui transfer serial |
|
$00B |
UART, RX |
Terminarea receptiei unui caracter la UART |
|
$00C |
UART, UDRE |
Golirea registrului de date UART |
|
$00D |
UART, TX |
Terminarea transmisiei unui caracter de la UART |
|
$00E |
ADC |
Terminarea unei conversii la ADC |
|
$00F |
EE_RDY |
EEPROM gata pentru o noua scriere |
|
ANA_COMP |
Comparatorul analogic |
Programul general tipic de setare a adreselor vectorilor de resetare si intrerupere incepe cu instructiuni de salt catre diversele subrutine de tratare a intreruperilor, sau catre partea de initializare (inceput al programului la Reset), ca in exemplul urmator:
Adresa Etichete Cod Comentarii
rjmp RESET ;Vector de reset
rjmp EXT_INT0 ;Vector IRQ0
rjmp EXT_INT1 ;Vector IRQ1
rjmp TIM2_COMP ;Vector egalitate T/C2
rjmp TIM2_OVF ;Vector depasire T/C2
rjmp TIM1_CAPT ;Vector captura T/C1
rjmp TIM1_COMPA;Vector egalitate cu A la T/C1
rjmp TIM1_COMPB;Vector egalitate cu B la T/C2
rjmp TIM1_OVF ;Vector depasire T/C1
rjmp TIM0_OVF ;Vector depasire T/C0
$00A rjmp SPI_STC ;Vector terminare transfer SPI
$00B rjmp UART_RXC ;Vector terminare RX UART
$00C rjmp UART_DRE ;Vector golire UDR la UART
$00D rjmp UART_TXC ;Vector terminare TX UART
$00E rjmp ADC ;Vector terminare conversie ADC
$00F rjmp EE_RDY ;Vector terminare scriere EEPROM
rjmp ANA_COMP ;Vector comparator analog
$0011 Reset: <instr> xxx ; Start program principal
In cazul in care nu sunt folosite toate sursele de intreruperi, vectorii folositi vor trebui plasati la adresele corespunzatoare, conform tabelului, folosind directive de asamblare .ORG (care pun instructiunea imediat urmatoare la adresa specificata). De exemplu, daca se folosesc doar intreruperile de la Timer/Counter1 si de la UART, inceputul programului sursa, fara declararea explicita a adreselor de asamblare a fiecarei instructiuni, va arata astfel:
Adresa Etichete Cod Comentarii
rjmp RESET ; Vector de reset
ORG $0005
rjmp TIM1_CAPT ; Vector captura T/C1
rjmp TIM1_COMPA ; Vector egalitate cu A la T/C1
rjmp TIM1_COMPB ; Vector egalitate cu A la T/C1
rjmp TIM1_OVF ;Vector depasire T/C1
ORG $000B
rjmp UART_RXC ; Vector terminare RX UART
rjmp UART_DRE ; Vector golire UDR la UART rjmp UART_TXC ;Vector terminare TX UART
ORG $00011
RESET: <instr> xxx ; Start program principal
Se observa ca folosind directive ORG s-a sarit peste unele zone alocate vectorilor de intreruperi nefolositi. In caz contrar, la instructiunile de salt catre subrutinele de tratare a intreruperilor se vor aloca vectori gresiti.
2. Registrul de stare - SREG.
Activarea globala a intreruperilor se realizeaza prin setarea in 1 logic a bitului I din registrul SREG. Acest registru, plasat la locatia $3F ($5F) din spatiul I/O, este definit astfel:
SREG
BIT |
| |||||||
$3F ($5F) |
I |
T |
H |
S |
V |
N |
Z |
C |
Citeste/Scrie |
C/S |
C/S |
C/S |
C/S |
C/S |
C/S |
C/S |
C/S |
Valoare initiala |
Bitul 7 - I: Activarea globala a intreruperilor.
Pentru a activa intreruperile, bitul de activare globala a intreruperilor trebuie sa fie setat (unu). Setarea acestui bit permite controlul individual al intreruperilor din cadrul registrelor de masti de intreruperi GIMSK si TIMSK. Daca bitul de activare globala a intreuperilor este sters (zero), nici una dintre intreruperi nu este activa, independent de valorile GIMSK si TIMSK. Bitul I este sters de catre hardware in urma aparitiei unei intreruperi si este setat prin instructiunea RETI de reintoarcere dintr-o subrutina de intrerupere, pentru a permite intreruperi ulterioare.
Bitul 6 - T: Bitul de stocare la instructiuni pe bit.
Instructiunile de copiere a bitului BLD (Incarcare a bitului) si BST (Stocare a bitului), folosesc bitul T ca sursa si destinatie pentru bitul operat. Orice bit din orice registru aflat in Aria de Registre poate fi copiat in T cu instructiunea BST, operatiunea inversa (din T in orice registru din Aria de Registre) fiind realizata cu instructiunea BLD.
Bitul 5 - H: Indicatorul transport la jumatate (Half Carry)
Acest flag indica aparitia unui transport la jumatatea unui octet in unele operatii aritmetice (cu numere in format BCD).
Bitul 4 - S: Bitul de semn, S = N xor V.
Bitul S este totdeauna obtinut prin operatia Sau-Exclusiv intre flagul negativ, N si flagul de depasire in complement fata de doi, V.
Bitul 3 - V: Flagul de depasire in complement fata de doi.
Acest flag este folosit in aritmetica complementului fata de doi.
Bitul 2 - N: Flagul negativ.
Indica un rezultat negativ obtinut in urma diferitelor operatii aritmetice si logice.
Bitul 1 - Z: Flagul zero.
Indica un rezultat zero obtinut in urma efectuarii diferitelor operatii aritmetice si logice.
Bitul 0 - C: Flagul transport.
Indica un transport intr-o operatie aritmetica sau logica.
Activarea intreruperilor se poate face in mai multe moduri. De exemplu, pentru setarea individuala a bitului I se poate folosi secventa:
IN R16, $3F ;Se citeste SREG
ORI R16,$80 ;Se pune in 1 bitul corespunzator lui I, ceilalti ;neschimbati
OUT $3F, R16 ;Se trimite inapoi in SREG, cu bitul I in 1, ceilalti ;neschimbati
De asemenea, exista si instructiuni speciale de control a intreruperilor globale:
SEI ; activeaza intreruperile globale
CLI ; dezactiveaza intreruperile globale
Atunci cand apare o intrerupere, bitul I de activare generala a intreruperilor este sters (zero), astfel ca toate intreruperile sunt dezactivate. Pentru activarea intreruperilor, utilizatorul de software are sarcina de a seta bitul I (unu). De asemenea, acest bit este setat automat daca revenirea din rutina de tratare a intreruperii se face cu instructiunea RETI (in loc de cea de revenire din subrutinele normale, RET).
Cand se sare la subrutina de tratare a unei intreruperi, si flagul corespunzaaor sursei care a generat intreruperea este sters automat. Flagurile individuale de intreruperi pot fi sterse si prin sofware, prin scrierea unui 1 logic in bitul din pozitia corespunzatoare in registrul care contine flagul respectiv.
3. Indicatorul de stiva (Stack Pointer - SP)
Deoarece intreruperile presupun chemarea (automata) a unor subrutine, este necesar ca inainte de validarea intreruperilor sa se initializeze stiva, prin incarcarea in Stack Pointer a adresei de baza a stivei. De exemplu, daca se foloseste pentru stiva memoria RAM interna, se poate incaarca in SP valoarea $025F.
Indicatorul de stiva de 16 biti este alcatuit din doua registre de 8-biti cu locatiile $3E ($5E) si $3D ($5D), in spatiul I/O. La microcontrolerul AT90S8515, care suporta pana la 64 kB SRAM extern, sunt folositi toti cei 16 biti.
Bit |
|
||||||||
$3E ($5E) |
SP15 |
SP14 |
SP13 |
SP12 |
SP11 |
SP10 |
SP9 |
SP8 |
SPH |
$3D ($5D) |
SP7 |
SP6 |
SP5 |
SP4 |
SP3 |
SP2 |
SP1 |
SP0 |
SPL |
Bit |
|
||||||||
Citire/ Scriere |
C/S C/S |
C/S C/S |
C/S C/S |
C/S C/S |
C/S C/S |
C/S C/S |
C/S C/S |
C/S C/S |
|
Val. initiala |
|
|
La microcontrolerul AT90S8535, care nu suporta SRAM extern, sunt folositi numai cei 10 biti mai putin semnificativi.
Stack Pointer-ul este decrementat cu unu atunci cand sunt trimise in stiva date prin intermediul instructiunii de salvare in stiva (Push), iar atunci cand se salveaza in stiva adrese prin intermediul instructiunii de apel de subrutina (Call) sau de catre o intrerupere, acelasi pointer este decrementat cu doi. In mod similar, pointerul este incremntat cu unu atunci cand sunt extrase date din stiva prin intermediul instructiunii Pop, iar atunci cand se extrag adrese din stiva prin instructiunea RET (intoarcere din subrutina) sau IRET (intoarcere din intrerupere) , SP este incrementat cu doi.
Acest registru este de 16 biti (per ansamblu) iar accesarea lui se va face dupa regulile generale de lucru cu registre de 16 biti. Atunci cand CPU-ul acceseaza aceste registre, pentru a fi asigurata citirea si scrierea simultana atat a octetului superior cat si a octetului inferior , este folosit un registru temporar de 8-biti - TEMP. Atunci cand pentru accesarea registrelor de 16 biti, atat din programul principal cat si din rutinele de intrerupere, este folosit registrul TEMP, pe durata accesarii este obligatoriu ca intreruperile sa fie dezactivate.
Scrierea in SP.
Atunci cand CPU-ul scrie octetul superior - SPH, datele scrise sunt plasate in registrul TEMP. Cand in pasul urmator CPU-ul scrie octetul inferior - SPL, acest octet este combinat cu octetul deja existent in registrul TEMP, astfel incat toti cei 16-bitii sunt scrisi simultan in registrul SP. In consecinta, pentru a fi realizata corect o operatie de scriere completa a registrului de 16-biti, este obligatoriu ca octetul superior SPH sa fie scris primul, si imediat dupa aceea si registrul inferior.
Citirea din SP.
Atunci cand CPU-ul citeste octetul inferior SPL, datele citite din acesta sunt transmise in CPU iar datele octetului superior SPH sunt plasate automat in registrul TEMP. Cand CPU-ul relizeaza citirea octetului superior SPH, el primeste datele din registrul TEMP. In consecinta, pentru a fi realizata corect o operatie de citire completa a registrului de 16-biti, se va citi intii octetul inferior - SPL, si imediat dupa aceea si octetul superior.
4. Intreruperile externe
Microcontrolerul AT90S8535 are doua surse de intrerupere externa, INT0 si INT1 care apar la schimbari de stare logica a pinilor corespunzatori: PD2 respectiv PD3. Pentru activarea lor, in afara de setarea flagului global de intrerupere (bitul I din SREG) trebuie setati si bitii de control individuali din registrul GIMSK - Registrul general al mastilor intreruperilor. Aparitia unei intreruperi externe este semnalizata prin setarea bitilor corespunzatori din registrul GIFR - Registrul general al flagurilor de intrerupere .
Registrul general al mastilor de intreruperi - GIMSK.
Acest registru contine bitii pentru activarea sau dezactivarea individuala a intreruperilor externe.
GIMSK
Bit | ||||||||
$3B ($5B) |
INT1 |
INT0 | ||||||
Citeste/Scrie |
C/S |
C/S |
C |
C |
C |
C |
C |
C |
Valoare initiala |
Bitul 7 - INT1: Activarea cererii de intrerupere externa 1.
Pinul intreruperii externe 1 este activat atunci cand atat bitul INT1, cat si bitul I din registrul de stare (SREG) sunt amandoi setati (unu). Bitii 3 si 2, de control ai sensului intreruperii externe 1 (ISC11 si ISC10), plasati in registrul de control general al MCU (vor fi prezentati la registrul MCUCR), stabilesc daca intreruperea externa 1 este activata pe front crescator sau pe cel descrescator al semnalului de pe pinul INT1 sau sesizata pe nivel. Activitatea pe acest pin va provoca o cerere de intrerupere chiar daca INT1 este configurat ca iesire, dar pentru a se evita conflictele, este bine ca el sa fie configurat ca intrare. Intreruperea corespunzatoare cererii 1 de intrerupere externa este executata de la adresa $002 din memoria de program.
Bitul 6 - INT0: Activarea cererii 0 de intrerupere externa.
Pinul intreruperii externe 0 este activat atunci cand atat bitul INT0, cat si bitul I din registrul de stare (SREG) sunt amandoi setati (unu). Bitii 1 si 0, de control ai sensului intreruperii externe 0 (ISC01 si ISC00), plasati in registrul de control general al MCU (vor fi prezentati la registrul MCUCR), stabilesc daca intreruperea externa 0 este activata pe front crescator sau pe cel descrescator al semnalului de pe pinul INT0 sau sesizata pe nivel. Activitatea pe acest pin va provoca o cerere de intrerupere chiar daca INT0 este configurat ca iesire, dar pentru a se evita conflictele, este bine ca el sa fie configurat ca intrare. Intreruperea corespunzatoare cererii 1 de intrerupere externa este executata de la adresa $002 din memoria de program.
Bitii 5 . . . 0 - Res: Biti rezervati.
Acesti biti sunt rezervati in AT90S8515 si sunt cititi intotdeauna ca zero.
Registrul general de flaguri de intrerupere - GIFR.
Corespunzator mastilor generale exista si flaguri generale, plasate in registrul GIFR, acestea fiind activate la aparitia conditiilor de generare a intreruperilor respective.
GIFR
Bit | ||||||||
$3A ($5A) |
INTF1 |
INTF0 | ||||||
Citeste/Scrie |
C/S |
C/S |
C |
C |
C |
C |
C |
C |
Valoare initiala |
Bitul 7 - INTF1: Flagul de intrerupere externa 1.
Atunci cand un eveniment ce are loc asupra pinului INT1 plaseaza o cerere de intrerupere, INTF1 devine setat (unu). Daca atat bitul I din SREG cat si bitul INT1 din GIMSK sunt setati (unu), MCU va sari la vectorul intrerupere de la adresa $002. Flagul este sters atunci cand rutina de intrerupere este executata, dar numai daca intreruperea a fost declansata pe front. Ca alternativa, cand se doreste stergerea acestuia se poate scrie un l in el.
Bitul 6 - INTF 0: Flagul 0 de intrerupere externa.
Atunci cand un eveniment ce are loc asupra pinului INT 0 plaseaza o cerere de intrerupere, INTF0 devine setat (unu). Daca atat bitul I din SREG cat si bitul INT0 din GIMSK sunt setati (unu), MCU va sari la vectorul intrerupere de la adresa $001. Flagul este sters atunci cand rutina de intrerupere este executata, dar numai daca intreruperea a fost declansata pe front. Ca alternativa, cand se doreste stergerea acestuia se poate scrie un l in el.
Bitii 5 . . . 0 - Res: Biti rezervati.
Acesti biti sunt rezervati la AT90S8535 si sunt cititi intotdeauna ca zero.
Registrul de control al MCU-ului - MCUCR.
Acest registru contine biti pentru controlul memoriei SRAM externe, al modurilor de sleep si al fronturilor care genereaza intreruperile externe.
MCUCR
Bit | ||||||||
SE |
SM1 |
SM0 |
ISC11 |
ISC10 |
ISC01 |
ISC00 |
||
Citeste/ Scrie |
C/S |
C/S |
C/S |
C/S |
C/S |
C/S |
C/S |
C/S |
Val. initiala |
Bitul 7 - Res: Bit rezervat.
Acest bit este rezervat la AT90S8535 si este citit intotdeauna ca zero.
Bitul 6 - SE: Activarea modului SLEEP.
Atunci cand este executata instructiunea SLEEP, pentru ca MCU-ul sa intre in aceasta stare, bitul SE trebuie sa fie setat (unu). Pentru a evita intrarea in sleep a MCU-ului (exceptie facind situatia in care se doreste acest lucru), se recomanda setarea bitului de activare a a sleep-ului (SE) doar cu putin timp inainte de executatrea instructiunii SLEEP.
Bitii 5,4 - SM: Selectarea modului de sleep.
Acesti biti face alegerea intre cele trei moduri de sleep, conform tabelului 3.2.
Tabelul 3.2. Controlul sensului intreruperii INTx
SM1 |
SM0 |
Modul de Sleep |
Idle |
||
Rezervat |
||
Power-down |
||
Power Save |
Bitii 3, 2, 1, 0 - ISCx1, ISCx0: Controlul sensului semnalului de intrerupere externa x, bitul 1 si bitul 0.
Intreruperea externa x (unde x este 0 sau 1) este activata de catre pinul extern INTX, in situatia in care flagul I din SREG impreuna cu flagul de masca a intreruperii corespunzatoare din GIMSK este setat. Nivelul sau fronturile semnalului care se aplica pinului INTX pentru a activa intreruperea, sunt definite in tabelul 3.2.
Tabelul 3.2. Controlul sensului intreruperii INTx
ISCx1 |
ISCx0 |
Descriere |
Nivelul jos al INTx genereaza o cerere de intrerupere |
||
Rezervat |
||
Frontul descrescator pe INTx genereaza o cerere de intrerupere |
||
Frontul crescator pe INTx genereaza o cerere de intrerupere |
Intreruperile pe front apar dupa esantionarea pinului INTx, astfel ca un puls trebuie sa dureze cel putin o perioada de ceas pentru a declansa intreruperea.
La intreruperile pe nivel jos, acest nivel trebuie sa dureze pana la terminarea instructiunii in curs pentru a declansa intreruperea. Deoarece in acest caz flagul respectiv nu se sterge la executarea intreruperii, ea va fi generata in mod repetat atat timp cat nivelul pe pin este jos.
Programul urmator va utiliza intreruperea externa 0 pentru a incrementa un registru, al carui continut este apoi afisat. Se va observa ca la aplicarea de impulsuri pe pinul PD2, corespunzator intrarii de intrerupere externa 0, numarul afisat pe leduri va fi incrementat. De mentionat ca aplicarea unui impuls de la un contact mecanic introduce de fapt mai multe impulsuri parazite datorate fenomenului de multicontact.
Se pot observa cele 5 parti principale intalnite in general in toate programele:
;Declaratii
.equ PINA=$19 ;pinii A (push-button)
.equ ADIR=$1A ;directia la reg. A
.equ Leds=$15 ;Registrul C (Leduri)
.equ CDIR=$14 ;directia la reg. C
;Tabela de intreruperi
rjmp Reset ;Vectorul de reset
rjmp Intr0 ;Vectorul intreruperii 0
rjmp Intr1 ;Vectorul intreruperii 1
.org $11
Reset: ; Programul va incepe de la adresa 11 ;hexa deci dincolo de zona unde se ;afla vectorii de intrerupere
;Stabilirea directiei porturilor
ser r16 ;Pune $ff in r16 (C va fi iesire)
out cdir,r16
clr r16 ;Pune 0 in r16 (A va fi intrare)
out adir,r16
;Initializare stiva SP=$025f
ldi r16,02 ;Mai intai se scrie octetul superior
out $3e,r16 ; in SPH
ldi r16,$5f ;Apoi se scrie octetul inferior
out $3d,r16 ; in SPL
;Initializare intreruperi
ldi r16,$c0 ;INT1 si INT0
out $3b,r16 ;in GIMSK
in r16,$35 ;Bitii 0-3 din MCUCR sunt in 1,
ori r16,$0f ;selectand frontul crescator pentru
out $35,r16 ;generarea intreruperii externe sei ;Activeaza intreruperile global
;Bucla principala
Main: out leds,r18
rjmp main
;Subrutine (de intreruperi)
Intr0:
inc r18
reti
Intr1:
reti
Se va modifica programul de mai sus pentru a realiza urmatoarele:
Intreruperea 0 sa decrementeze informatia afisata pe leduri iar intreruperea 1 sa o incrementeze.
Intreruperea 0 sa deplaseze stanga
informatia afisata pe leduri iar intreruperea 1 sa o deplaseze dreapta.
Valoarea initiala de afisat se va introduce inainte de
Intreruperea 0 sa deplaseze stanga informatia afisata pe leduri in felul urmator:
00011000->00100100->01000010->10000001->00000000,
iar intreruperea 1 sa o deplaseze invers. Valoarea initiala de afisat se va
introduce inainte de
Copyright © 2024 - Toate drepturile rezervate