Sistema di interrupt



Il sistema di interrupt e' stato gia' introdotto a grandi linee alla sezione "Memoria RAM/FLASH/EEPROM". Grazie alla gestione degli interrupt, il microcontrollore puo' essere istruito in maniera tale da "porsi in ascolto" di eventi esterni durante l'esecuzione normale del programma; quando uno di questi eventi si manifesta il program counter viene temporaneamente salvato nello stack e si salta alla locazione di memoria 0x0004 (vettore di interrupt). Compito del programmatore e' quello di inserire, a partire da questa locazione, una subroutine in grado di gestire l'attuale istanza di interruzione. La subroutine di gestione delle interruzioni dovra' terminare con l'istruzione RETFIE: questa istruzione ricarica automaticamente l'ultimo program counter salvato nello stack e cosi' permette la normale continuazione del programma precedentemente interrotto. E' molto simile a RETURN e RETLW ma in piu' riporta a 1 il bit GIE del registro INTCON.
La figura sottostante ripropone il flusso di controllo che il microcontrollore segue al manifestarsi di una interruzione esterna:





Gli eventi di interruzione che possono essere gestiti dal pic 16F84 sono di quattro tipi:
  • Interrupt dal pin RB0/INT
  • Interrupt per cambio di stato dei pin RB4..RB7
  • Interrupt per completamento della fase di scrittura della EEPROM interna
  • Interrupt dal timer
Esiste un registro opportuno, tale INTCON, grazie al quale e' possibile abilitare o disabiltare tutti o in parte i quattro eventi di interrupt elencati sopra. Inoltre alcuni suoi bit vengono settati dal controllore stesso e permettono (se si vuole) di sapere, all'interno della subroutine, quale interrupt tra i quattro possibili si e' appena verificato.
Gli interrupt possono essere disabilitati del tutto settando a 0 il bit GIE (Global Interrupt Enable) del registro INTCON (il valore di default al reset e' proprio questo). Un programma che voglia far uso del sistema di interrupt dovra' preoccuparsi di porre ad 1 questo bit. Quando si verifica una interruzione, il microcontrollore setta automaticamente a 0 il bit GIE: in questo modo si evita che possano verificarsi altri interrupt durante la gestione di quello attuale. L'istruzione RETFIE, oltre a ripassare il controllo al programma interrotto, riabilita automaticamente gli interrupt, settando ad 1 il bit GIE.



    Interrupt dal pin RB0/INT



L'interruzione sul piedino RB0/INT e' scatenata dal comportamento del segnale TTL su questo piedino. L'interruzione su RB0/INT viene abilitata settando ad 1 il bit INTE del registro INTCON. Ovviamente deve essere settato ad 1 anche il bit GIE.
Quando il bit INTE e' settato a 0 oppure il GIE a 0 il piedino RB0/INT e' a tutti gli effetti la prima linea della porta B (RB0) e come tale puo' essere usata. Questo e' il comportamento di default del piedino. Quando pero' si attiva l'interrupt il pin non puo' piu' essere usato come linea della porta B ma esclusivamente come linea per ricevere le interruzioni dall'esterno.
Esistono due modalita' di interrupt:
  • Rising edge
  • Falling edge
Con la prima (rising edge) l'interrupt viene attivato nel momento in cui la tensione sulla linea INT passa da 0 a +5 volt, quindi si presume che normalmente il livello di tensione sia il primo (0 volt). La seconda invece attiva l'interrupt quando la tensione sul piedino INT passa da +5 volt a 0, presupponendo quindi che +5 volt sia la tensione standard.
La modalita' (rising/falling edge) viene impostata settando opportunamente il bit INTDEG del registro OPTION_REG.
Una volta che il microcontrollore ha lanciato l'interruzione viene automaticamente settato ad 1 il bit INTF del registro INTCON. Questo bit puo' essere controllato dalla routine di gestione dell'interrupt per sapere se si e' verificato proprio l'interrupt associato alla linea INT oppure era qualche altra interruzione. Nel primo caso la routine dovra' provvedere a riportare a 0 tale bit altrimenti saranno inibiti i prossimi interrupt dal piedino INT.



    Interrupt dal timer



Quando il contatore TIMER0 va in overflow (cioe' passa dal valore 0xFF a 0x00) viene lanciata una interruzione. L'interruzione deve pero' essere prima abilitata settando ad 1 il bit T0IE del registro INTCON. Inoltre, al verificarsi della interruzione, viene automaticamente settato ad 1 il bit T0IF del registro INTCON, e deve essere riportato a 0 dalla routine di gestione definita dal programmatore per poter mantenere abilitato il sistema di interruzione dal timer.



    Interrupt per cambio di stato dei pin RB4..RB7



In questo caso viene sollevata una interruzione quando avviene un cambio di stato qualsiasi (cioe' un cambio di tensione) tra uno o piu' dei piedini RB4,RB5,RB6 e RB7. Questo tipo di interrupt puo' essere abilitato o disabilitato settando opportunamente il bit RBIE del registro INTCON.
Al lancio della interruzione viene automanticamente settato ad 1 il bit RBIF del registro INTCON.




    Interrupt per completamento della fase di scrittura della EEPROM interna



Senza addentrarci troppo nel sistema di lettura/scrittura della EEPROM interna si puo' dire che, siccome la fase di scrittura e' estremamente lenta (20 ms) comparata con la velocita' tipica di esecuzione delle istruzioni del microcontrollore, e' stato pensato di permettere alla EEPROM di lanciare una interruzione al completamento della fase di scrittura. In questo modo il programma utente puo' dare il comando di scrittura e continuare subito con le istruzioni successive, per poi gestire con comodo il completamento della scrittura rilevando l'interruzione.
Questo tipo di interruzione si abilita tramite il bit EEIE del registro INTCON. Per rilevare questa interruzione occorre controllare assieme i bit RBIF,INTF e T0IF: se sono tutti a 0 allora l'interruzione e' stata lanciata dalla EEPROM.