Les interruptions
Le PIC 16F84A dispose de 4 sources d'interruptions :
1- Le mécanisme des interruptions
Quand une interruption survient, le programme principal est interrompu :
Le microcontrôleur finit l'exécution de l'instruction en cours puis il se branche vers le sous-programme d'interruption (la routine d'interruption).
Quand la routine d'interruption est achevée (instruction retfie), le microcontrôleur retourne au programme principal, à l'endroit exact où il l'avait quitté.
2- Cas d'une seule source d'interruption
Imaginons une application où l'on désire utiliser l'interruption sur la broche RB0/INT.
Il peut s'agir d'un bouton poussoir connecté sur la broche RB0/INT :
On veut donc provoquer une interruption quand on appuie sur le bouton poussoir.
Pour cela, il faut commencer par autoriser les interruptions de manière globale :
Puis, on autorise uniquement l'interruption qui nous intéresse :
Enfin, on initialise le drapeau (flag) INTF à 0 (bit 1 du registre INTCON).
Tout cela se fait pendant la phase d'initialisation du programme principal par :
movlw B'10010000'
movwf INTCON
Maintenant, quand on appuie sur le bouton poussoir, le drapeau INTF est automatiquement mis à 1.
Le microcontrôleur prend en compte cette interruption quand il a connaissance du niveau haut de drapeau INTF (3 ou 4 cycles de délai).
Le mécanisme des interruptions est lancé (voir plus haut).
Important :
Sinon, le microcontrôleur se rebranche indéfiniment sur la routine d'interruption (puisque INTF = 1) : le programme est planté !
Il est important que le contexte de travail du programme principal soit le même avant et après l'exécution de la routine d'interruption.
Cela concerne le registre STATUS et l'accumulateur W qui doivent retrouver le même contenu (en effet, ces deux registres sont souvent utilisés et donc modifiés pendant la routine d'interruption).
Voici la procédure préconisée par Microchip :
La routine d'interruption commence par la sauvegarde du registre W puis du registre STATUS :
org H'0004' ; vecteur d'interruption (directive du compilateur MPLAB)
movwf W_TEMP
swapf STATUS, W
movwf STATUS_TEMP
La routine d'interruption finit par la restauration du registre STATUS puis du registre W :
swapf STATUS_TEMP, W
movwf STATUS
swapf W_TEMP, f
swapf W_TEMP, W
retfie ; retour d'interruption
3- Cas de plusieurs sources d'interruption
On suppose que les 4 sources d'interruptions sont actives :
Dans la routine d'interruption (après avoir sauvegardé le registre W et le registre STATUS), se pose la question suivante : quelle est la source de l'interruption ?
La réponse se fait en testant, les uns après les autres, le niveau logique des drapeaux :
Par exemple, supposons que l'interruption est due au débordement du registre TMR0 :
Après le test, le microcontrôleur se branche vers le bloc de traitement spécifique de l'interruption TMR0.
Il ne faut pas oublier d'effacer le drapeau T0IF.
On finit par la restauration du registre STATUS puis du registre W.
Il peut arriver qu'il y ait plusieurs sources d'interruptions en même temps :
Dans ce cas, on peut se contenter de traiter une seule source d'interruption à la fois.
Ce sera l'interruption RB0/INT s'il se trouve que le drapeau INTF est testé en premier.
Après retour dans le programme principal, on aura :
L'interruption "RB" est alors traitée, etc ...
On voit ici que l'on peut choisir des niveaux de priorités entre les différentes sources d'interruptions.
Rien ne vous empêche de traiter toutes les sources d'interruption en une seule fois.
Voici l'organigramme correspondant :
4- Remarques
Si une autre interruption survient pendant l'exécution de la routine d'interruption, elle est pour l'instant ignorée.
Elle sera prise en compte à la fin de la routine d'interruption, c'est à dire au moment où le microcontrôleur retourne au programme principal.
En fait, cela se comprend facilement quand on sait que le bit GIE est automatiquement :
- mis à 0 au début de la routine d'interruption (désactivation de toutes les interruptions)
- mis à 1 à la fin de la routine d'interruption (activation de toutes les interruptions)
© Fabrice Sincère ; Révision 1.9.2