II2 : microcontrôleur
7) Appels de fonctions, pile
Lors de l'écriture d'un programme informatique, même très simple, il est courant d'utiliser
des fonctions. Cela a plusieurs intérêts, le principal étant de structurer l'application.
main(){
....
....
foo(); void foo(void){
a=2; b=3;
....; ....
} return;
}
Dans l'exemple, la fonction foo()est appelée depuis le programme main(). Le
diagramme suivant indique, au cours du temps, quelle fonction (du main ou de foo) est en
cours d'exécution par le microcontrôleur.
Or, si il est clair dans le main() que le microcontrôleur doit aller exécuter la fonction
foo(). Il n'est indiqué nulle part dans la fonction foo() doit se poursuivre l'exécution
une fois que la dernière instruction de cette fonction a été exécutée ! Qui plus est comme
une fonction peut être appelée de nombreuses fois depuis différents endroits, il ne pourrait
pas en être autrement.
IL EST NECESSAIRE DE MEMORISER L'ADRESSE DE RETOUR DE FONCTION
Lorsque le main appelle la fonction foo() , le microcontrôleur sauvegarde dans la PILE
(Stack en anglais, voir chapitre « organisation mémoire ») l'adresse de la première
instruction à exécuter APRES la fin d'exécution de la fonction appelée foo().
Ce mécanisme est gérée par le couple d'instruction CALL/RET (appel et retour de sous
II2/Systèmes embarqués à microprocesseurs 1
main()
foo()
main()
t
programme et utilise la pile (registre poiteur de pile SP) pour sauvegarder l'adresse de retour.
Sur les microcontroleurs AVR il y a 3 variantes de l'instruction CALL (RCALL, CALL,
ICALL) mais cela ne change en rien ce mécanisme.
L'exemple initial a été compilé, les lignes de ...... représentent des instructions inutiles pour la
compréhension du mécanisme d'appel.
La fonction foo débute à l'adresse 0x00000071 en mémoire programme (Flash)
10: void main (void){
.........
12: foo();
+0069: 940E0071 CALL 0x0071 Call subroutine
13: a=2;
+006B: E082 LDI R24,0x02 Load immediate
+006C: 93800101 STS 0x0101,R24 Store direct to data space
..........................................
@0071: foo
16: void foo(){
.......................................
18: b=3;
+0075: E083 LDI R24,0x03 Load immediate
+0076: 93800100 STS 0x0100,R24 Store direct to data space
.........................
+007A: 9508 RET
Principe d'un appel/retour de fonction (voir schéma) : mémorisation de l'adresse de retour dans la
pile (STACK)
PC = 0x00000069 : le microcontrôleur arrive a l'exécution de CALL 0x00000071 (appel de la
fonction foo().
Avant d'avoir entièrement décodé cette instruction, PC = 0x0000006B (en l'absence d'appel
de fonction l'instruction suivante exécutée aurait du être LDI R24,0x02, située à l'adresse
0x00000071)
Le microcontrôleur exécute l'instruction CALL:
Il mémorise dans la pile (le pointeur de pile est décrémenté ) l'adresse de LDI R24,0x02
(0x0000 006B) pour pouvoir exécuter cette instruction une fois foo() finie
Il charge PC avec l'adresse de début de foo 0x0000 0071
PC = 0x0000 0071, le microcontrôleur exécute les instructions de foo() jusqu'à RET
(instruction assembleur de retour de fonction).
Le sommet de la pile contient l'adresse de retour (0x0000 006B, adresse de l'instruction qui
doit être exécutée à la fin de l'appel de fonctionnement
Le microcontrôleur charge PC avec l'adresse contenue en haut de la pile (0x0000 006B)
PC =0x0000 006B, l'exécution reprend normalement (LDI R24,0x03)
II2/Systèmes embarqués à microprocesseurs 2
Illustration 1: Instructions xCALL, RET
II2/Systèmes embarqués à microprocesseurs 3
8) Interruptions
Une des intérêts des composants de type microcontrôleurs (en particulier la famille AVR)
réside dans le nombre et la variété des périphériques intégrés. Ainsi un programme peut
interagir avec des processus physiques en fonctions des événements qui surviennent :
- attendre qu'un niveau logique passe à 1, passe à 0, change d'état
- attendre qu'un caractère soit transmis
- attendre qu'une tension dépasse un certain seuil
- attendre qu'un timer déborde
- etc.....
par exemple la boucle suivante attend le passage à l'état haut de la pin PD2 de l'ATMéga16.
do{
}while ((PIND&0x04) ==0x00); // attente que PIND2 soit au //
// niveau logique 1
{Faire ce qu'il y a à faire maintenant que PD2 est passé à
l'état haut}
On appelle ce principe le « Polling » (ou scrutation) : le processeur scrute en permanence
l'état de la pin PD2.
Outre que le processeur consomme de l'énergie à scruter ce port (qcq mA ), il est difficile
d'envisager la scrutation de 2, 3 ou 4 périphériques simultanément. Un mécanisme plus efficace est
de permettre aux périphériques de signaler au microcontrôleur qu'un événement à eu lieu, charge a
celui ci de traiter cet événement (ou de l'ignorer) . Ce mécanisme s'appelle le mode
d'INTERRUPTIONS.
Principe de fonctionnement :
Le microcontrôleur exécute son programme principal (éventuellement le microcontrôleur est en
mode sommeil)
Un événement (matériel) survient et provoque une demande d'interruption du programme
principal (éventuellement réveille le uC).
L'instruction du programme principal en cours d'exécution se termine
Le programme d'interruption s'exécute.
le programme principale reprend son exécution normale
On reconnaîtra un fonctionnement similaire à un appel de fonction SAUF que c'est un
événement matériel qui déclenche l'exécution du programme d'interruption.
Pour fonctionner en mode d'interruptions plusieurs conditions doivent être réunies :
Le périphérique doit être configuré pour pouvoir générer une demande d'interruption
La prise en compte par le microcontrôleur de cette demande à du être autorisée auparavant.
Il doit y avoir une fonction d'interruption associée à cette interruption.
II2/Systèmes embarqués à microprocesseurs 4
L'association interruption/fonction d'interruption se fait par l'intermédiaire de la Table de
vecteurs d'interruptions qui est placée en tout début de mémoire programme (0x0000)
Exemples:
si un événement sur la broche INT0 (par exemple un front montant) survient, l'interruption
INT0 (préalablement autorisée) va interrompre le programme principal. Et l'instruction placée à
l'adresse 0x0002 (vecteur de la table d'interruption) va s'exécuter. Cette instruction est général
un SAUT vers le code de la fonction d'interruption.
Si le timer 0 déborde (TCNT0>255), c'est l'interruption TIMER0 OVF qui se déclenche avec
II2/Systèmes embarqués à microprocesseurs 5
1 / 12 100%
La catégorie de ce document est-elle correcte?
Merci pour votre participation!

Faire une suggestion

Avez-vous trouvé des erreurs dans linterface ou les textes ? Ou savez-vous comment améliorer linterface utilisateur de StudyLib ? Nhésitez pas à envoyer vos suggestions. Cest très important pour nous !