Tutorials - PIC18 by Data Sheet

 

INTERRUPT


Schematicamente :

IPEN

INTCON<7>

INTCON<6>

Logica operativa

IPEN = 0

GIE

PEIE

Nessuna priorità
Differenziazione interrupt periferici e non

IPEN = 1

GIEH

GIEL

Doppia priorità
Differenziazione tra interrupt a priorità alta e bassa

 

Nel caso di una sorgente periferica, ovvero i cui bit di controllo si trovano nei registri PIE/PIR :

  • il bit IPEN in RCON va programmato a 0 se non è desiderata la priorità e a 1 per la doppia priorità

  • se è stata scelta la doppia priorità,  il bit xxxIP relativo alla sorgente dovrà essere programmato per assegnare il livello voluto. Altrimenti questo non occorre

  • il bit xxxIE nel registro ICONn relativo alla sorgente di interrupt interessata va settato

  • il bit xxxIF va azzerato per evitare una chiamata di interrupt inaspettata

  • Trattandosi di sorgenti periferiche, alla loro abilitazione si aggiunge un ulteriore bit PEIE che andrà settato. Questo bit è disponibile solo nella modalità senza priorità. Se non viene settato, la chiamata di interrupt dalla periferica resta inattiva anche se è stato abilitato il bit globale GIE.

  • se esiste un solo livello di interrupt il bit GIE di INTCON abiliterà (o disabiliterà) globalmente tutti gli interrupt attivati, che non avranno effetto fino a che questo bit resta a 0. Se esistono due livelli, il bit GIE diventa GIEH e , attenzione, il bit PEIE diventa GIEL. In sostanza nel modo a due priorità non  esiste più una abilitazione specifica per le sorgenti periferiche, ma solo una suddivisione in alta e bassa priorità.

Esiste quindi una importante differenza tra la logica di "compatibilità" con i mid-range e quella propria dei PIC18 con priorità a livelli :

  • la prima vede le sorgenti di interrupt divise tra periferiche (sotto l' azione di PEIE) e non periferiche (sotto l' azione di GIE) ed entrambe dipendenti da GIE.

  • la seconda, pura mantenendo una struttura di registri simile, non distingue più le sorgenti tra periferiche e non, ma solo tra assegnate alla alta o alla bassa priorità. Anche qui, però, la funzionalità di GIEL dipende da GIEH


Nota:
 

Una nota riguarda gli Errata del costruttore (che è sempre necessario leggere prima di utilizzare il componente, in quanto possono riservare sorprese non indifferenti).
Nel caso di GIE, per alcuni PIC è necessario attivare prima GIEH e poi GIEL e disattivarli nell' ordine inverso, pena il mancato funzionamento dell' operazione.

Una soluzione semplice ed efficiente al problema sopra indicato è quella di creare un paio di macro che svolgano queste due istruzioni in modo adeguato al PIC. Ad esempio:  

STARTINT macro            ; abilita interrupt globale
     bsf    INTCON,GIEH    
     bsf    INTCON,GIEL
          endm 
STOPINT   macro            ; disabilita interrupt globale
     bcf     INTCON,GIEL
     bcf     INTCON,GIEH
          endm

   

A riguardo delle priorità va detto che, attivare la modalità per poi assegnare tutte le richieste alla priorità superiore non è sensato. Lo scopo delle priorità è quello di fare operare periferiche in interrupt invece che in polling in un insieme dove il tempo di esecuzione di alcune funzioni è drasticamente più importante che per altre. Quindi l' uso della priorità sarà riservato alle applicazione che ne necessitano realmente. 


Un esempio

Esempio 1 Vogliamo attivare gli interrupt esterni sui pin di PORTB, con INT1 ad alta priorità e INT2 a bassa priorità.

  • IPEN = 1 in RCON per abilitare le priorità

  • INT1IP = 1 in INTCON3 per avere l' alta priorità

  • selezionare il fronte di trigger per INT1 con INTEDG1 del registro INTCON2

  • INT2IP = 0 in INTCON3 per avere la bassa priorità

  • selezionare il fronte di trigger per INT2 con INTEDG2 del registro INTCON3

  • abilitare l' interrupt di INT1 con il bit INT1IE = 1 in INTCON3

  • abilitare l' interrupt di INT2 con il bit INT2IE = 1 in INTCON3

  • portare GIEH =1 (abilitazione alta priorità)

  • portare GIEL =1 (abilitazione bassa priorità)

  Il che origina le seguenti istruzioni:  

  bsf  RCON,    IPEN      ; enable priority
 bsf  INTCON3, INT1IP    ; hp to INT1
 bsf  INTCON2, INTEDG1   ; select rising edge
 bcf  INTCON3, INT2IP    ; lp to INT2
 bcf  INTCON2, INTEDG2   ; select falling edge
 bsf  INTCON3, INT1IE    ; enable INT1
 bsf  INTCON3, INT2IE    ; enable INT2
 bcf  INTCON3, INT1IF    ; clear flag INT1
 bcf  INTCON3, INT2IF    ; clear flag INT2
 bsf  INTCON,  GIEH      ; enable global hp
 bsf  INTCON,  GIEL      ; ebnable lp

A questo punti i livelli di trigger scelti, quando presenti sui pin, attiveranno i relativi interrupt.

Ovviamente sarà necessario che il programma disponga dell' entry ad alta priorità all' indirizzo 0008h e di quello a bassa priorità a 0018h, dei necessari salvataggi delle variabili ambientali e , da non dimenticare, la cancellazione dei flag prima di rientrare al flusso normale del programma. 

Il clear dei flag realtivi alle sorgenti di interrupt è prassi necessaria prima dell' abilitazione dell' interrupt in quanto questi flag potrebbero essere settati da eventi precedenti e quindi generare un immediata chiamata di interrupt non richiesta.

Esempio 2 - Volendo attivare gli interrupt esterni sui pin di PORTB, con INT1 e INT2 , ma senza gestione della priorità :

  • IPEN = 0 in RCON per disabilitare le priorità (lo è già al reset)

  • Selezionare il fronte di trigger per INT1 con INTEDG1 del registro INTCON2

  • Selezionare il fronte di trigger per INT2 con INTEDG2 del registro INTCON3

  • Abilitare l' interrupt di INT1 con il bit INT1IE = 1 in INTCON3

  • Abilitare l' interrupt di INT2 con il bit INT2IE = 1 in INTCON3

  • Portare GIEH =1 (abilitazione globale)

  Il che origina le seguenti istruzioni:  

    bcf  RCON,    IPEN      ; disable priority
  bsf  INTCON2, INTEDG1   ; select rising edge
  bcf  INTCON2, INTEDG2   ; select falling edge
  bsf  INTCON3, INT1IE    ; enable INT1
  bsf  INTCON3, INT2IE    ; enable INT2
  bcf  INTCON3, INT1IF    ; clear flag INT1
  bcf  INTCON3, INT2IF    ; clear flag INT2
  bsf  INTCON,  GIE       ; enable global  
  

Non occorre toccare il bit PEIE in quanto non si tratta di interrupt periferici. 

Come sopra, il flag identificatore relativo all' interrupt chiamante va resettato via software onde evitare chiamate inaspettate.
Inoltre, una volta servito l' interrupt , è tassativo ricordarsi di resttare il flag.


  •  


Nota:
 

Si deve ricordare che i flag IF vanno a 1 anche se il relativo interrupt non è abilitato : basta si sia verificato l' evento ad essi collegato. 

Pertanto possono essere utilizzati per una gestione in polling , ricordando sempre di azzerarli una volta usati.

 


 

Copyright © afg. Tutti i diritti riservati.
Aggiornato il 09/12/10.