L'interrupt è una particolare caratteristica dei PIC
(e dei microprocessori in generale) che consente di intercettare un evento esterno,
interrompere momentaneamente il programma in corso, eseguire una porzione di programma
specializzata per la gestione dell'evento verificatosi e riprendere l'esecuzione del
programma principale.
Volendo fare un paragone con il mondo reale possiamo dire che
l'interrupt rappresenta per il PIC quello che per noi rappresenta ad esempio la suoneria
del telefono.
Per poter ricevere telefonate non dobbiamo preoccuparci di alzare
continuamente la cornetta per vedere se c'é qualcuno che vuol parlare con noi, ma, grazie
alla suoneria, possiamo continuare tranquillamente a fare le nostre faccende in quanto
saremo avvisati dà questa ogni volta che qualcuno ci sta chiamando.
Appena sentiamo lo squillo, possiamo decidere di interrompere
momentaneamente le nostre faccende, rispondere al telefono e, una volta terminata la
conversazione, riprendere dal punto in cui avevamo interrotto.
Riportando i termini di questo paragone al PIC abbiamo che:
- le nostre faccende corrispondono al programma in esecuzione;
- la chiamata da parte di qualcuno corrisponde all'evento da gestire;
- lo squillo del telefono corrisponde alla richiesta di interrupt;
- la nostra risposta al telefono corrisponde alla subroutine di gestione
dell'interrupt.
E' evidente quanto sia più efficiente gestire un evento con un
interrupt anzichè controllare ciclicamente il verificarsi dell'evento con il programma
principale. Gran parte degli aspetti legati alla gestione dell'interrupt vengono inoltre
trattati direttamente dall'hardware interno del PIC per cui il tempo di risposta
all'evento è praticamente immediato.
Tipi di evento e bit di abilitazione
Il PIC16F84 è in grado di gestire in interrupt quattro eventi diversi,
vediamo quali sono:
- Il cambiamento di stato sulla linea RB0 (External interrupt RB0/INT pin).
- La fine del conteggio del registro TMR0 (TMR0 overflow interrupt).
- Il cambiamento di stato su una delle linee da RB4 ad RB7 (PORTB change
interrupts).
- La fine della scrittura su una locazione EEPROM (EEPROM write complete
interrupt).
L'interrupt su ognuno di questi eventi può essere abilitato o
disabilitato indipendentemente dagli altri agendo sui seguenti bit del registro INTCON:
- INTE (bit 4) se questo bit viene messo a 1 viene
abilitato l'interrupt sul cambiamento di stato sulla linea RB0
- T0IE (bit 5) se questo bit viene messo a 1 viene
abilitato l'interrupt sulla fine del conteggio del registro TMR0
- RBIE (bit 3) se questo bit viene messo a 1 viene
abilitato l'interrupt sul cambiamento di stato su una delle linee da RB4
ad RB7
- EEIE (bit 6) se questo bit viene messo a 1 viene
abilitato l'interrupt sulla fine della scrittura su una locazione EEPROM
Esiste inoltre un bit di abilitazione generale degli interrupt che deve
essere settato anch'esso ad uno ovvero il bit GIE (Global Interrupt
Enable bit) posto sul bit 7 del registro INTCON.
Interrupt vector ed Interrupt handler
Qualunque sia l'evento abilitato, al suo manifestarsi il PIC interrompe
l'esecuzione del programma in corso, memorizza automaticamente nello STACK
il valore corrente del PROGRAM COUNTER e salta all'istruzione presente
nella locazione di memoria 0004H denominata Interrupt vector
(vettore di interrupt).
E' da questo punto che dobbiamo inserire la nostra subroutine di
gestione dell'interrupt denominata Interrupt Handler (gestore di
interrupt).
Potendo abilitare più interrupt, tra i primi compiti dell'interrupt
handler è la verifica di quale, tra gli eventi abilitati, ha generato l'interrupt e
l'esecuzione della parte di programma relativo.
Questo controllo può essere effettuato utilizzando gli
Interrupt flag.
Interrupt flag
Dato che qualunque interrupt genera una chiamata alla locazione
04H, nel registro INTCON sono presenti dei flag che
indicano quale è l'evento che ha generato l'interrupt, vediamoli:
- INTF (bit 1) Se vale 1 l'interrupt è stato generato dal
cambiamento di stato sulla linea RB0.
- T0IF (bit 2) Se vale 1 l'interrupt è stato generato al
termine del conteggio del timer TMR0.
- RBIF (bit 0) Se vale 1 l'interrupt è stato generato dal
cambiamento di stato di una delle linee da RB4 a RB7.
Come si vede per l'interrupt sul fine scrittura in EEPROM non è
previsto alcun flag di segnalazione per cui l'interrupt handler dovrà considerare che
l'interrupt è stato generato da questo evento quando tutti e tre i flag sopra citati
valgono 0.
Importante: Una volta rilevato quale flag è attivo,
l'interrupt handler deve azzerarlo altrimenti non verrà più generato l'interrupt
corrispondente.
Ritorno da un interrupt handler
Quando viene generato un interrupt il PIC disabilita automaticamente il
bit GIE (Global Interrupt Enable) del registro INTCON in modo da disabilitare tutti gli
interrupt mentre è già in esecuzione un interrupt handler. Per poter ritornare al
programma principale e reinizializzare a 1 questo bit occorre utilizzare l'istruzione:
RETFIE
Nel passo successivo vedremo un esempio pratico
di uso degli interrupt. |