La presenza degl iinterrupt in un microcontrollore è una benedizione divina! Guai se non ci fossero!
Detto in parole povere, ecco cosa accare. Il tuo programma (MainProg) esegue una numero di operazioni/istruzioni in modo indefinito, di continuo: il programma "cicla". Per eventi particolari, come ad esempio lo scadere di un timer o un evento di trigger scatenato da una interazione del mondo esterno con il microcontrollore, il programma principale si interrompe e viene invocata una routine di interrupt (ISR = Interrupt Service Routine) che esegue operazioni "straordinarie" che normalmente non verrebbero eseguite.
Ora, a seconda del tipo di evento scatenante, le routine di interrupt sono diverse. Il programmatore decide quali saranno i comportamenti da mantenere qualora ci sia da servire una richiesta di interrupt per timer scaduto o perché il convertitore A/D ha pronto il dato acquisito dal canale analogico, eccetera.
Sui PIC 16F (a 8 bit) la faccenda è abbastanza semplice: quando viene scatenato un interrupt, qualunque esso sia, il registro di programma (Program Counter) viene portato ad un indirizzo di program memory (oggi è di tipo FLASH) e qui viene eseguita la ISR.
Come detto la ISR è unica, quindi come fa il PIC a "scegliere" quale azione intraprendere? In questo caso, ogni interrupt che scatta, alza un proprio flag:
Quando si entra in ISR il programmatore deve pertanto porre delle condizioni sul motivo scatenante l'interrupt e questo lo si fa normalmente con dei costrutti "if".
- Codice: Seleziona tutto
if (T0IF == 1)
{
// Eseguo codice dovuto a overflow timer 0)
TOIF = 0;
} else if (T1IF == 1)
{
// Eseguo codice dovuto a overflow timer 1)
T1IF = 0;
} else if (T2IF == 1)
// Eseguo codice dovuto a overflow timer 2)
T2IF = 0;
} else if (ADIF == 1)
// Eseguo codice dovuto fine conversione A/D)
ADIF = 0
}
Come vedi, all'interno del codice è stato messo un reset dei flag (T0IF, T1IF, ...) che a turno scatenano l'interrupt. Se questo non fosse fatto, all'uscita della ISR i flag non resettati portano ad una immediata riesecuzione della ISR. E questo non va bene.
Sui PIC18F la cosa è molto simile, ma le locazioni di memoria ove viene portato il program counter a seguito di un interrupt sono due. Il programmatore sceglie di associare a taluni eventi una priorità maggiore rispetto ad altri.
Venendo al tuo caso, posso dire che, leggendo il manuale di CCS, si legge quanto segue:
The compiler will generate code to jump to the function when the interrupt is detected. It will generate code to save and restore the machine state, and will clear the interrupt flag.
Il che significa che il compilatore esegue lui il reset del flag di interrupt. Questo aspetto non è bello! Se cambi compilatore, vai in palla.
Non è un argomento banale né tantomeno credo di essere stato esaustivo. Spero che quanto esposto sia chiaro.
Ciao.
Paolo.