INTERRUPT (PIC 16F877A)



Il PIC16F877A ha 3 possibili sorgenti di interrupt, comuni a tutti i microcontrollori della famiglia PIC16, più tutti quelli che possono essere generati dalle periferiche specifiche.

 

Quelle comuni a tutta la famiglia sono:

Interrupt esterno sul pin RB0/INT (posso scegliere fronte di salita o discesa);

Interrupt su cambiamento di livello su almeno uno degli ingressi RB7:RB4;

Interrupt su overflow del counter/timer TMR0;

Possono poi generare interrupt il convertitore A/D, la porta seriale, i timer 1 e 2, i moduli Compare/Capture ecc., per un totale complessivo di 14 sorgenti.

 

Non esistono interrupt non mascherabili: tutti gli interrupt sono “filtrati” da un flag di abilitazione generale degli interrupt GIE (bit 7 del registro INTCON), che di default è basso (interrupt disabilitati).

 

La logica degli eventi legati a un’interrupt è la seguente: ogni periferica che può chiedere interruzione ha un “flag d’interruzione” che si alza quando si verificano le condizioni previste per l’interrupt; la CPU testa i flag d’interruzione dei periferici ogni ciclo Q1 del clock, cioè all’inizio del ciclo macchina






Se ne trova uno alto (e se quel tipo di interrupt è abilitato a generare interrupt), l’indirizzo di rientro viene salvato sullo stack hardware, e il PC (Program Pounter) caricato con 0004h, locazione dove di conseguenza la CPU salta, con un ritardo (tempo di latenza) di 2 – 3 cicli macchina. In 0004h deve iniziare la routine di gestione, o un salto alla routine di gestione.

 Il vettore d’interruzione è pertanto unico: è il software che può (di solito deve) individuare quale periferica tra quelle abilitate ha chiesto interrupt interrogando (polling) i loro flag d’interruzione.

 Quando il PIC risponde a un’interruzione, ulteriori interrupt vengono disabilitati dall’abbassamento automatico di GIE.

 E’ possibile, anche se non molto raccomandabile, permettere la nidificazione degli interrupt, rialzando GIE (che è scrivibile come tutti i flag di INTCON) all’interno della routine di gestione.

 Al rientro dall’interruzione il flag GIE si rialza automaticamente, riabilitando le interruzioni. (consiglio di controllare)

 E’ assolutamente importante ricordare che il flag d’interruzione della periferica non si riabbassa automaticamente, quindi ci si deve ricordare di abbassarlo all’interno della routine di gestione . Di solito viene fatti alla fine della routine, per impedire che al rientro al programma principale, l’interrupt riparta immediatamente, innescando un loop infinito.

Il meccanismo degli interrupt non è semplicissimo da spiegare, per capirlo meglio si può vedere la figura sotto che lo traduce in uno schema logico:








La richiesta di interrupt alla CPU è un livello alto all’uscita dell’ultimo AND a destra, da cui si vede che è inibita da GIE = 0

Ogni periferica ha un flag d’interruzione, che si alza comunque sempre quando si verificano le condizioni che potrebbero chiedere interrupt, e un flag di abilitazione specifico. A titolo d’esempio, consideriamo gli interrupt dalla linea RB0/INT: il flag d’interruzione è INTF e quello d’abilitazione è INTE. Dallo schema si vede che perché la CPU “senta” l’innalzamento di INTF, non basta che sia alto GIE, ma deve essere alto anche INTE: i flag di abilitazione specifici dei periferici permettono quindi di selezionare quali di essi possono chiedere interrupt.

 

La richiesta d’interrupt da parte dei periferici specifici dell’877A è generata dalla combinazione AND – OR a sinistra, e si vede che perché tale richiesta “passi” è necessaria un’ulteriore abilitazione rappresentata dal flag PEIE (PEripheral Interrupt Enable). Nel registro principale collegato agli interrupt – INTCON – ci sono i flag di interrupt e abilitazione interrupt delle tre sorgenti di base, oltre a GIE e PEIE

Di INTF e INTE abbiamo già detto. TMR0IF/TMR0IE è la coppia flag d’interrupt/flag d’abilitazione interrupt relativa al Timer 0, RBIF/RBIE quella relativa all’interrupt da cambiamento su RB7:RB4. Le coppie relative agli altri periferici sono sparse in altri registri specializzati. Vedere la documentazione relativa ai singoli periferici. Notare che anche INTCON è mappato in tutti i banchi di memoria.

  I registri dedicati alla gestione degli interrupt sono : INTCON, PIE1, PIE2, PIR1 e PIR2.