PIC e Linux: 3) L’uso degli interrupt in SDCC

Cosa siano e come si usano gli interrupt lo abbiamo già visto nella lezione di settorezero sul timer, e maggiori approfondimenti che riguardano gli interrupt a due livelli tipici dei PIC18 li possiamo trovare in quest’altra lezione.

Tuttavia la sintassi con cui si usano gli interrupt nell’SDCC non è documentata molto chiaramente, e per evitarvi di perdere tempo ve la spiego con un esempio:

int flagportaB = 0; //variabile che useremo per verificare se è successo qualcosa sulla porta B nei pin 4 - 7
int flagtimer = 0; //variabile che useremo per verificare se il timer è arrivato a 0

void pippo() interrupt 1 {
   if (INTCONbits.RBIF == 1) {
       flagportaB = 1;
       INTCONbits.RBIF = 0;
   }
   if( INTCONbits.TMR0IF == 1 ){
       flagtimer = 1;
       INTCONbits.TMR0IF=0;
   }

}

Come potete vedere occorre creare una funzione, non importa quale nome abbia, purchè dopo il nome ci sia scritta la parola “interrupt” seguita dal numero 1 o 2, nel caso dei PIC18, che indicano il livello di priorità degli interrupt. Il valore 1 indica la massima precedenza.

La funzione di gestione degli interrupt deve avere alcune caratteristiche importanti:

  1. non accetta parametri in ingresso e non restituisce nulla in uscita. L’unico modo per farla comunicare con il programma principale è usare delle variabili globali che possono essere modificate dalla funzione e poi lette nel programma principale
  2. deve essere brevissima
  3. deve resettare gli indicatori di interrupt per poterli intercettare altre volte

Detto questo, vediamo come si scrive il main():

void main() {
long int i;
 TRISB = 0b11110000;
 TRISD = 0b00000000;
 PORTB = 0;
 LATD = 0;
 PORTD=7;
 INTCONbits.RBIE=1; //abilita gli interrupt sulla portB 4 - 7
 //RCONbits.IPEN = 0; //funziona anche con lo 0, serve per usare 1 o 2 livelli di interrupt
 INTCONbits.GIE=1; Abilita gli interrupt

while (1) {
if (flagtimer==1) {
 faiqualcosa-relativo-al-timer()
 flagtimer=0;
 }
if (flagportaB==1) {
 fai-qualcosa-relativo-alla-portaB()
 flagportaB=0;
 }
 }
}

Come avete potuto vedere, il main() non richiama mai in modo esplicito la funzione di gestione degli interrupt, ma si limita ad inizializzare i registri degli interrupt, per abilitarli, e poi controlla se una delle variabili “flag” ha cambiato valore, ed in tal caso agisce di conseguenza

Annunci

Rispondi

Inserisci i tuoi dati qui sotto o clicca su un'icona per effettuare l'accesso:

Logo WordPress.com

Stai commentando usando il tuo account WordPress.com. Chiudi sessione / Modifica )

Foto Twitter

Stai commentando usando il tuo account Twitter. Chiudi sessione / Modifica )

Foto di Facebook

Stai commentando usando il tuo account Facebook. Chiudi sessione / Modifica )

Google+ photo

Stai commentando usando il tuo account Google+. Chiudi sessione / Modifica )

Connessione a %s...