Il livello di priorità dell'
interrupt
E' inteso che il livello di priorità non è un obbligo ed
è possibile, dove non sia necessario, utilizzare un solo livello di
interrupt (quello relativo al vettore alto), in modo del tutto analogo ai
PIC delle famiglie mid range. Così non ha senso abilitare le priorità e
poi utilizzare solo la priorità alta.
Con una singola priorità si ha a disposizione un solo livello in cui un
interrupt in corso non è interrompibile da altri.
Nel modo a doppia priorità, un interrupt di livello basso potrà essere
interrotto da uno di livello altro (mentre non è possibile il contrario).
Ovviamente questo richiede una maggiore cura nella scrittura delle routine
di gestione dell' interrupt, sia per la logica delle operazioni, sia per il
salvataggio del contesto.
Le due priorità dispongono di due diversi vettori di
ingresso :
vettore a 0008h |
interrupt senza priorità |
vettore unico |
interrupt con priorità |
vettore alta priorità |
vettore a 0018h |
interrupt senza priorità |
ignorato |
vettore con priorità |
vettore priorità bassa |
Rispetto ai mid range che hanno un unico vettore a 004h, la
partenza a 0008h permette di introdurre un maggior numero di istruzioni tra
il questo e il vettore di reset a 0000h, tenendo però presente che le
istruzioni PIC18 sono a 2 bytes.
Nel caso di impiego di interrupt senza priorità il vettore
comune di accesso alle routines sarà 0008H (mentre 0018H non ha funzione
specifica), il che, nel caso di una conversione da mid-range, richiede la
correzione della direttiva ORG del listato.
Non avendo 00018H una funzione specifica, le istruzioni relative alla
gestione dell' interrupt potranno occupare con continuità tutte le
locazioni necessarie a partire da 0008H.
Nella doppia priorità, sia a 0008H che a 0018H l' utente
dovrà collocare le opportune routines. In questo caso, avendo abilitato la
priorità, la gestione dell' interrupt ad alta priorità (vettore 0008h)
richiede un jump ad una locazione più avanti, essendoci spazio solo
per poche istruzioni, mentre a partire dal vettore a bassa priorità
(0018h), non essendoci altro spazio impegnato dopo di esso, le routine
possono essere scritte in successione diretta.
Questa scelta dei progettisti è sfavorevole al vettore ad alta priorità
che , logicamente, dovrebbe anche essere quello servito in modo più
immediato , in contrasto con la necessità obbligata di un jump iniziale.
La scelta se impiegare o no il doppio livello di priorità
dipende dal settaggio del bit IPEN (RCON<7>). Quando questo bit è a
zero (e si tratta del default dopo il reset) solamente un livello di
interrupt è attivo. Con IPEN = 0 (compatibility mode) la definizione della
priorità degli interrupt non ha effetto ed eventuali impostazioni dei
bit xxxIP non sono considerate.
Per contro, se viene settato IPEN=1 si abilita la doppia
priorità e diventano attivi sia il vettore a 0018h sia le impostazioni dei
bit xxxIP.
Una volta abilitata la priorità, tutte le sorgenti sono
intese come appartenente al livello alto e dove necessario va loro
attribuito il livello basso attraverso i relativi bit xxxIP.
INTCON
Oltre ai bit specifici di ogni sorgente di interrupt
esistono altri due bit che è necessario considerare nella gestione dell'
interrupt :
INTCON
|
bit
|
GIE
GIEH
|
PEIE
GIEL
|
-
|
-
|
-
|
-
|
-
|
-
|
funzione
|
R/W
|
R/W
|
-
|
-
|
-
|
-
|
-
|
-
|
default
|
0
|
0
|
-
|
-
|
-
|
-
|
-
|
-
|
-
bit 7 GIE/GIEH
: Global Interrupt Enable/ GIE High priority
con
IPEN = 0
1 = Abilita tutti gli interrupt
0 = Disabilita tutti gli interrupt
con
IPEN = 1
1 = Abilita tutti gli interrupt ad alta priorità
0 = Disabilita tutti gli interrupt ad alta priorità
-
bit 6 PEIE/GIEL
: Peripheral Interrupt Enable/ GIE Low priority
con
IPEN = 0
1 = Abilita tutti gli interrupt periferici
0 = Disabilita tutti gli interrupt periferici
con
IPEN = 1
1 = Abilita tutti gli interrupt a bassa priorità
0 = Disabilita tutti gli interrupt a bassa priorità
Al POR i due bit di controllo generale dell' interrupt sono
a 0, per cui le funzioni di interrupt sono disabilitate.
Per riassumere,
la sequenza di inizializzazione di un interrupt non periferico con o senza
priorità sarà questa :
-
il bit IPEN
in RCON va programmato a 0 se non è desiderata la priorità e a 1 per
la doppia priorità
-
se è stata
scelta la doppia priorità, il bit xxxIP relativo alla sorgente
dovrà essere programmato per assegnare il livello voluto. Altrimenti
questo non occorre
-
il bit xxxIE
nel registro ICONn relativo alla sorgente di interrupt interessata va
settato
-
il bit xxxIF
va azzerato per evitare una chiamata di interrupt inaspettata
-
se esiste un
solo livello di interrupt il bit GIE di INTCON abiliterà (o
disabiliterà) globalmente tutti gli interrupt attivati, che non avranno
effetto fino a che questo bit resta a 0.
Se si impiega il
doppio livello di priorità, i bit di abilitazione globale sono due : GIEH e
GIEL
Il primo riguarda la globalità degli interrupt, sia ad alta che a bassa
priorità, mentre il secondo riguarda la globalità dei soli interrupt a
bassa priorità.
Questo va inteso così :
abilitando GIEL si abilitano globalmente gli interrupt a bassa priorità, ma
questa attivazione non ha effetto se contemporaneamente non viene attivato
anche GIEH, formalmente relativo agli interrupt ad alta priorità, ma in
pratica avente funzione globale su tutti i livelli.
Quindi portando a zero
GIEH si disabilitano tutti gli interrupt di qualsiasi livello.
Questo sdoppiamento di GIE è fatto a scapito di PEIE, che diventa GIEL
(mentre GIE diventa GIEH).