Tutorials - PIC18 by Data Sheet

 

pag 91 - INTERRUPT


L' Interrupt

Un programma è essenzialmente una sequenza ordinata di istruzioni che svolge i compiti previsti dal programmatore.

E' possibile che, in una applicazione reale, siano disponibili eventi che richiedono una attenzione immediata. Ad esempio, se stiamo leggendo un libro, siamo impegnati nello scorrere le parole e le frasi e a comprenderne il significato (qeusto è il flusso principale del "programma").
Ma ecco che squilla il telefono (interrupt): occorre sospendere la lettura e rispondere alla chiamata. Dopo di che si potrà nuovamente riprendere la lettura dal punto in cui è stata interrotta.

Analogamente, il flusso del programma può avere la necessità di essere interrotto per passare il controllo ad altre sezioni del programma che hanno lo scopo di gestire la causa dell' interruzione.

Nei PIC, come in altri processori embedded, la procedura di interrupt consiste essenzialmente nella sostituzione del valore contenuto nel Program Counter con un indirizzo fisso, predeterminato dalla struttura del processore. Questo fa si che l' istruzione successiva all' evento di interrupt sia  la prima che si trova a questo indirizzo.

Ovvero, dalla posizione attuale, sospendendo il flusso di istruzioni principale, si passa immediatamente ad un indirizzo determinato, dove il programmatore ha posizionato le routines di gestione dell' interrupt. 

Al termine dell' esecuzione di queste routines, una speciale istruzione di ritorno-da-interrupt (RETFIE) ripristina il Program Counter nella posizione da cui si era distaccato, riprendendo il flusso di istruzioni principale.

 

Il salto all' indirizzo di inizio delle routines di interrupt può essere causato da numerose fonti di evento interne (timer, UART, MSSP, ecc) oppure esterne (cambio di livello sui pin, tensione, ecc.).

I PIC18F dispongono di una numerosa serie di possibili fonti di interrupt, dato che integrano un altrettanto elevato numero di periferiche, tipicamente superiore ai mid-range, ma sopratutto, di una struttura di gestione dell' interrupt a priorità.

Ne deriva che un buon numero di registri sono disponibili per la gestione degli eventi.

Ogni sorgente di interrupt dispone di TRE di bit di controllo :

bit funzione
IE - Interrupt Enable bit di abilitazione. la cui sigla termina tipicamente con IE; settando questo bit si abilita la sorgente a generare interruzioni
IF - Interrupt Flag bit di flag, la cui sigla termina con IF. 
Quando questo bit va a livello 1 livello indica l' avvenuto evento.
IP - Interrupt Priority bit di priorità, la cui sigla termina con Ip. 
Questo bit stabilisce il livello di priorità ed è attivo in dipendenza dal valore assegnato a IPEN <RCON:7> (questo bit 1 abilita la priorità a due livelli).

Per consentire una gestione dell' evento, il flag IF resta a livello 1 fino a che non viene azzerato dall' utente. Questo comporta la necessità assoluta di resettare il flag una volta servito onde evitare che, non appena usciti dalla routine di interrupt, il flag a 1 la riattivi immediatamente, con i risultati immaginabili.

 


ATTENZIONE:

La gestione di un interrupt deve SEMPRE prevedere la cancellazione del flag della periferica che ha generato la chiamata. In caso contrario non sarà possibile uscire da un loop sul vettore dell' interrupt.


L' abilitazione dei bit IE non è sufficiente ad attivare l' interrupt : un ulteriore bit GIE (Global Interrupt Enable) funge da "interruttore generale" e sarà necessario settare anche questo perchè l' evento di interrupt abbia effetto.


INTERRUPT Periferici e non periferici

I PIC distinguono poi due categorie di sorgenti di interrupt :

  • interrupt "non periferici" 

  • interrupt "periferici"

La differenza consiste in questo : le sorgenti di interrupt "non periferici" hanno i bit IE e IF nei registri INTCON, mentre le sorgenti "periferiche" hanno i bit di controllo nei registri PIR/PIE.
A seguito di questa divisione, i bit di abilitazione globale diventano due : il già citato GIE e un PEIE (PEripheral Interrupt Enable) .

Per attivare gli interrupt periferici, oltre a GIE, sarà necessario attivare anche PEIE; ovvero PEIE funge da interruttore generale per gli interrupt periferici e GIE funge da interruttore generale per tutte le sorgenti di interrupt, periferiche e non. Quindi, per abilitare un interrupt periferico, sarà necessari settare sia il relativo bit IE sia il bit GIE, mentre per attivare un interrupt non periferico si dovrà settare sia IE che GIE e PEIE.
Questo, a fronte di una maggiore complessità di gestione, consente una maggiore flessibilità nell' attivazione/disattivazione degli interrupt.

Lo schema complesso qui sopra utilizza delle funzioni logiche AND e OR per spiegare il funzionamento della catena di bit preposti al controllo di un interrupt.
Prendiamo ad esempio l' interrupt generato dal fine conteggio di TIMER0.

Se il timer termina il conteggio, passando da FFh a 00h, il bit TMR0IF va a livello 1. Questo bit è in AND con i bit di abilitazione TMR0IE e il bit di priorità TMR0IP: se entrambi sono a livello 1, anche l' uscita dell' AND va a livello 1.

Questa uscita è in OR con altre catene similari: dunque basta che uno solo degli ingressi dell' OR vada a livello 1 perchè l' uscita del gate sia pure a livello 1.

Questa uscita viene riportata ad un ulteriore AND che la somma al bit di abilitazione GIE/GIEH: se questo è a livello 1, l' uscita dell' AND, a livello 1, attiva la chiamata di interrupt.
Nello stesso tempo, se la funzione è abilitata a questo, un gate OR comanda il wake up dalla condizione di sleep.

Il vettore che viene sostituito al Program Counter, a seguito della richiesta di interrupt, è posto a 0008h.

Nella modalità ad un solo livello di priorità, il bit TMR0IP non ha effetto. Quindi, se esemplifichiamo quanto detto con una catena di interruttori, otteniamo:

Se è selezionata la modalità con due livelli di priorità, in serie alla catena si inserisce anche il bit TMR0IP.

Un caso particolare è costituito dall' INT0, che non ha bit di selezione del livello di priorità e quindi è attivo sempre alla priorità più alta.

Così dovrebbe essere facile seguire le altre fonti di interrupt attraverso la catena degli "interruttori" logici che le abilitano, osservando che lo switch di priorità IP (quando abilitato), invia la chiamata di interrupt ad un vettore diverso, posto a 0018h.

Da notare che questo vettore è abiltato dal bit GIEH(GIE), ma anche dal bit GIEL(PEIE). 

GIE abilta il complesso degli interrupt e PEIE solo quelli periferici, in modalità senza priorità.

Nel modo con priorità GIE, che viene chiamato GIEH, di nuovo abilita in generale gli interrupt, mentre PEIE, che viene chiamato GIEL, abilita solo quelli a priorità bassa

Schematizzato come interruttori:

Ma vediamo ora altri dettagli per chiarire l' argomento.


 

Copyright © afg. Tutti i diritti riservati.
Aggiornato il 11/12/10.