ELEMANIA
PIC16F690 - Funzione di interrupt
Funzione di interrupt

L'argomento interrupt nel PIC è già stato trattato nel dettaglio parlando di programmazione in linguaggio assembly. Qui ci occupiamo semplicemente della scrittura di una funzione di interrupt, cioè di una interrupt service routine (ISR) in C.

La scrittura di una funzione di interrupt è grandemente semplificata in C rispetto all'assembly, come mostra il seguente esempio:

int tick_count;

void interrupt tc_int(void)
    {
     // test su T0IE (TMR0 Overflow Interrupt Enable) e T0IF (TMR0 Overflow Interrupt Flag)
    if (T0IE && T0IF)
        {
        T0IF=0;             // azzera T0IF (TMR0 Overflow Interrupt Flag)
        ++tick_count;     // incrementa il contatore
        return;
        }

    // qui bisogna aggiungere la gestione di eventuali altre sorgenti di interrupt
    }

Questa funzione di interrupt (il nome tc_int è stato scelto a piacere!) risponde agli interrupt generati dal TIMER0 incrementando un contatore (tick_count). Si noti anzitutto la parola chiave interrupt che non fa parte del C standard e che serve per indicare al compilatore che si tratta di una interrupt service routine.

La funzione di interrupt viene automaticamente caricata nella locazione 0004h nella memoria di programma del PIC. Inoltre il compilatore C si occupa automaticamente del salvataggio e ripristino dei registri del PIC e della disabilitazione e riabilitazione degli interrupt (i flag di interrupt devono invece essere azzerati dal programmatore all'interno della funzione, come nell'esempio precedente). Infine la funzione di interrupt viene terminata con un'istruzione return come ogni altra funzione (il compilatore si occupa di tradurre questa istruzione nell'istruzione RETFIE di return da interrupt).

Ci sono alcune importanti limitazioni sull'uso delle funzioni di interrupt che è bene tenere a mente:

Per quanto riguarda l'esempio precedente, si noti che la variabile tick_count è dichiarata come variabile globale, in modo da poter conservare il proprio valore fra un interrupt e il successivo. Si noti inoltre come, per individuare la sorgente di interrupt, venga fatto un test sia sul bit di abilitazione T0IE che sul bit di flag T0IF all'interno del registro INTCON.

ATTENZIONE: all'interno della funzione di interrupt viene azzerato il flag T0IF (altrimenti al termine della funzione di interrupt, la richiesta di interrupt rimarrebbe attiva).

Per quale motivo nella funzione vengono testati sia il flag T0IF che il bit di abilitazione T0IE (e non solo il bit di flag)? La ragione è che, in presenza di più sorgenti di interrupt, potrebbe accadere che una sorgente sia disabilitata, mentre arriva un interrupt da un'altra sorgente. Per esempio supponiamo di poter ricevere l'interrupt da TIMER0 o da RA2 e che TIMER0 sia temporaneamente disabilitato. Ora se arriva un interrupt da RA2 e non controlliamo il bit di abilitazione T0IE ma solo il flag T0IF, rischiamo di eseguire erroneamente il codice per il servizio dell'interrupt da TIMER0 invece di quello da RA2. Infatti se TIMER0 richiede un interrupt, il suo flag T0IF viene settato anche se l'interrupt da TIMER0 è stato disabilitato.

 

precedente - successiva

Sito realizzato in base al template offerto da

http://www.graphixmania.it