Utilisation des interruptions
Les mots ecrits en vert sont explicités à la fin de la page.
Exemple n°3: clignotement d'une LED à l'aide des interruptions du TIMER 0
Voici
le schema de cablage, vous pouvez réaliser ce petit montage
sur plaquette d'essais:
Explications
et conseils: C3, C4, et le Quartz 4MHz servent pour l'horloge du
PIC
C2 sert à découpler l'alimentation (alim plus
stable).
N'oubliez pas de relier la patte RESET au
+5V.
Attention l'alimentation doit etre de bonne qualité
et valoir de 4.5V à 5.5V
La norme voudrait qu'on relie
toutes les entrées inutilisées à un potentiel
(masse ou +5V). C'est à faire si vous voulez que le PIC
consomme moins ...
Le
cablage sur plaque d'essais:
(remarque:
le composant que vous voyez en haut à gauche est un
regulateur de tension. Il n'est pas necessaire, dés
l'instant ou votre alim sort du +5V d'une qualité correcte)
C'est va vous permettre de mieux comprendre le fonctionnement des interruptions.
Vous pouvez cliquer ici pour telecharger le programme (au format .asm. Il faudra le compiler avec MPASM. Regardez les pages precedentes pour plus d'informations)
list p=16f84,f=inhx8m __config B'11111111110001' #include "p16f84a.inc" temps equ H'0C' org H'00' goto Debut org H'04' movlw D'012' movwf TMR0 bcf INTCON,T0IF decfsz temps,1 retfie comf PORTB,1 movlw D'008' movwf temps retfie Debut bsf STATUS,RP0 movlw B'10000111' movwf OPTION_REG bcf TRISB,0 bcf STATUS,RP0 movlw D'008' movwf temps movlw B'10100000' movwf INTCON Boucle goto Boucle end |
Principe de fonctionnement du programme:
Le cycle d'horloge,
c'est a dire le temps entre la lecture de 2 instructions est d'1µs
(0.000001s)
Le Timer0 (TMR0)
est une variable incrementée d'1 tous les 256 cycles
d'horloge, et prealablement initialisée a la valeur 12.
Lorsque TMR0
passe de la valeur H'FF' à la valeur H'00',
le programme est
interrompu, et le PIC
lit ce qu'il y a à la ligne 4.
Ce cycle est repeté
8 fois avant que la LED change d'etat.
Le temps d'attente
entre chaque changement d'etat de la LED est donc:
1µs *
256 * 244 * 8 = 0.4997s
Le "1µs" est le
temps du cycle d'horloge
Le "256" est le nombre de
cycles d'horloges avant que TMR0 soit incrementé
Le
"244" = 256 - 12 est le nombre de fois que doit etre
incrementé le TMR0 avant qu'il y ait interruption
le "8"
est le nombre de fois qu'on execute le programme d'interruption
avant de changer l'etat de la LED
Détaillons la fonction de chaque ligne de ce programme:
list p=16f84,f=inhx8m: permet de dire au compilateur le type de PIC utilisé (16F84), et indique le format de fichier.
__config B'11111111110001': configure le PIC pour que le code ne soit pas protégé, on utilise la temporisation de démarage, on n'utilise pas le chien de garde, et oscillateur à quartz.
#include "p16f84a.inc": Ce fichier qui est fournit avec le compilateur de Microchip contient la définition des instructions que vous écrivez. Grace à ce fichier, le compilateur va pouvoir traduire les insctruction que vous écrivez en chiffres comprehensibles par le PIC.
temps
equ H'0C':
Définition d'une variable: temps est le nom de la variable;
H'0C' est l'adresse de la RAM à laquelle est stockée
cette variable. A chaque fois que le PIC aura a faire avec cette
variable, il modifiera le contenu a l'adresse 0C de la RAM.
Par
exemple lors de l'execution de l'instruction "movwf temps"
le PIC va mettre le contenu de la variable W à l'adresse
H'0C' de la RAM.
org H'00': Dit au compilateur à partir de quelle adresse il faut placer le programme dans le PIC
goto Debut: Va au label "Debut". Ceci permet de sauter la partie de programme concernant les interruptions.
org H'04': Dit au compilateur de placer le code qui suit a partir de l'adresse H'04'. Cette adresse est l'adresse à laquelle le programme est executé lorsqu'il y a une interruption.
movlw
D'012'
movwf
TMR0: Met la valeur 12 dans la
variable TMR0. Ceci permet de regler
precisement le temps entre chaque changement d'etat de la LED
(voir au dessus)
bcf INTCON,T0IF: Met à zero le bit T0IF du registre INTCON. Ce bit est mis a "1" par le PIC chaque fois qu'il y a une interruption par le Timer0 (TMR0).
decfsz
temps,1
retfie:
décremente la valeur la variable temps (qui a ete
initialisée a 8). Si temps n'est pas nulle, le programme
continue à s'executer à l'endroit où il a ete
interrompu. Sinon, le "retfie" est sauté, et
c'est la commande qui suit qui est executée:
comf
PORTB,1: permet d'inverser l'etat des
sortie du port B. Toutes les sortie
qui etaient à 0 passent à 1, et toutes les sorties
qui etaient à 1 passent à 0.
Dans notre cas,
seule la patte 6 du PIC changera d'etat.
movlw
D'008'
movwf
temps: On met la valeur 8 dans la
variable temps. La variable temps permet d'executer 8 fois
l'interruption avant de faire changer d'etat la LED. Une fois que
la LED a changé d'etat, il faut donc reinitialiser la
variable temps à la valeur 8.
retfie: On retourne à l'endroit ou le programme s'est interrompu.
Debut:
C'est un label. On pourrait le comparer à une borne
kilometrique qui sert à savoir à quel endroit on est
sur une route.
Dans le cas du PIC, le label sert à
reperer un endroit du programme.
On s'en sert pour executer
directement la partie de programme qui suit, sans executer la
partie concernant les interruptions. S'utilise avec l'instruction
goto Debut
Le nom "Debut" est donné par le
programmeur, on aurait pu mettre "fleur", ou ce que vous
voulez!
bsf STATUS,RP0: Sert à choisir la zone memoire n°1 (page 1). Cette zone memoire contient un certain nombre de registres de configuration (= variables pour configurer le PIC). En clair, pour pouvoir configurer le PIC, il faut generalement passer dans la zone memoire n°1 (bank 1), car c'est la que se trouvent la majorité des registres de configuration.
movlw
B'10000111': On transfert la valeur
binaire 10000111 dans le registre de travail W.
Je rapelle que
W est une variable "à tout faire". C'est par
exemple elle qui sert à transferer une valeur dans une
variable.
movwf
OPTION_REG: On transfert le contenu
de W (c'est à dire B'10000111') dans le registre (=
variable) "OPTION_REG".
Ceci a pour effet de
configurer le PIC.
En partant de la gauche, le premier "1"
signifie qu'on désactive les resistances de rappel en
entrée. les trois premier "0" signifient qu'on
n'utilise pas les interruptions, ....
Le "0" qui suit
signifie que le prédiviseur
est utilisé par le Timer0
Quant
au "111", il sert à définir la valeur du
prédiviseur. 111 =>
prédivision par 256.
bcf
TRISB,0: On met a zero le bit 0 de la
variable TRISB.
Cette variable permet de définir quelles
pattes sont en entrée, et quelles pattes sont en sortie. Le
port B comporte 8 pattes (n°6 à
n°13), Chaque bit de TRISB à 1 configure une patte en
entrée, et chaque bit à 0 configure une patte en
sortie. Ici, seul la patte 6 (bit 0 de port B) est en sortie.
C'est sur cette patte qu'on branche la LED.
Notez que par
defaut toutes les pattes du port A et B sont configurées en
entrée (TRISB vaut B'11111111' par defaut).
bcf STATUS,RP0: Maintenant que toutes les configurations sont finies, on repasse dans le zone memoire n°0, et on va commencer le programme en lui meme.
movlw
D'008'
movwf
temps: met la valeur 8 dans la
variable temps. La variable temps permet d'executer 8 fois
l'interruption avant de faire changer d'etat la LED. Une fois que
la LED a changé d'etat, il faut donc reinitialiser la
variable temps à la valeur 8.
movlw
B'10100000'
movwf INTCON:
met la valeur B'10100000' dans le registre INTCON.
Le premier "1" en partant de la gauche autorise les
interruptions, et l'autre "1" indique quel type
d'interruption est autorisé: ici ce sont les interruptions
dues au passage de H'FF' à H'00' de la variable TMR0.
Boucle: C'est un label. Il sert à reperer un endroit du programme.
goto Boucle: retourne au label "Boucle" (voir plus haut). le programme tourne donc en rond. et tous les 256 cycles d'horloge, il incremente la variable TMR0. Lorsque cette variable passe de la valeur 256 à la valeur 0, il y a interruption, et le PIC execute momentanement le programme contenu a partir de l'adresse H'04'. Lorsqu'il rencontre l'instruction RETFIE, il reprend l'execution normale du programme là ou il l'avait arreté. C'est a dire qu'il refait des cycles avec goto Boucle.
end: Il est indispensable pour le compilateur.
Pour
bien assimiler le fonctionnement du programme, voici un petit
résumé du fonctionnement:
~
Supposons que la LED est eteinte.
~ Pendant 0.5 secondes, le PIC
va executer l'instruction goto Boucle.
~ Au bout de ces 0.5
secondes, il va y avoir interruption de l'execution du programme,
et la LED va s'allumer.
~ Le PIC va de nouveau executer
l'instruction goto Boucle pendant 0.5 secondes.
~ Il va y avoir
de nouveau une interruption, et la LED va s'eteindre.
~ Et ainsi
de suite.
Interret
des interruptions:
Vous
allez me dire qu'il est bien plus simple de faire une temporisation
avec le chien de garde. Oui mais les interruptions presentent un
grand avantage, c'est qu'elles fonctionnent en parallele avec le
programme principal (qui serait contenu entre le label Boucle et le
goto Boucle).
Ainsi, on peut par exemple faire une temporisation
precise qui incremente une variable toutes les secondes, tout en
faisant fonctionner un programme en parallele, chose qu'on en
pouvait pas faire avec le chien de garde.
Quelques définitions:
Interruption:
C'est un événement qui interrompt le programme.
Lorsqu'il y a interruption, le PIC lit la partie de programme qui
commence à l'adresse H'04', et revient à l'endroit où
le programme s'est interrompu lorsqu'il rencontre l'instruction
RETFIE.
L'évenement qui provoque une interruption peut
etre de different type:
~ soit externe, un changement d'etat
d'une entrée préalablement configurée peut
provoquer une interruption.
~ Soit interne, c'est qu'on voit
dans l'exemple ci dessus; au bout d'un certain nombre de cycles
d'horloge, le programme est interrompu.
Chien de garde (WDT): C'est une fonction du PIC qui permet de savoir si une instruction dure "trop" longtemps (peut etre désactivé).
temporisation de démarage: le PIC attend 72 mS avant d'executer le programme lorsqu'on l'allume. Ceci permet d'attendre la stabilisation de l'oscillateur.
Oscillateur à quartz: voir le schema. Pour fonctionner, le PIC a besoin d'une horloge, et là l'horloge est réalisée avec un quartz 4 Mega Hertz et deux condensateurs.
registre
INTCON: Ce registre contient toutes les sources
d'interruption. Il permet de savoir ce qui a provoqué une
interruption, et il permet de configurer ce qui a le droit et ce
qui n'a pas le droit d'interrompre le programme.
Par exemple le
bit T0IE de INTCON lorsqu'il est a "1" permet d'autoriser
les interruptions dues au Timer0.
Le bit T0IF quant-à lui
passe à "1" quand il y a eu une interruption due
au Timer0.
Enfin le bit GIE permet de désactiver toutes
les sources d'interruptions lorsqu'il est à zero.
Configurer le PIC: Lorsqu'on configure le PIC, on dit quelles pattes sont en entrée, quelles autres sont en sortie, ....
Prédiviseur: ca sert à fixer le nombre de cycles d'horloge avant que la variable TMR0 soit incrementée. Si le prediviseur est à zero, le timer sera incrementé tous les deux cycles d'horloge. Si le prédiviseur est à 256 (c'est à dire que les 3 derniers bits de OPTION_REG sont à 1), la variable TMR0 sera incrementée tous les 256 cycles d'horloge.
TMR0 ou Timer0: c'est la variable qui compte le nombre de cycles d'horloge. Lorsque cette variable passe de la valeur 255 à la valeur 0, ca provoque une interruption, et le PIC execute le programme à partir de l'adresse H'04'
PORTB: c'est un registre (variable) de 8 bits qui contient les etats des sorties du pic. Par exemple si PORTB = B'00010011', les sorties 1, 2, et 5 (pattes 6, 7 et 10) sont au niveau logique "1", les autres sont à zero.
Ecrivez nous: xizard@enib.fr et rbourdon@enib.fr