[AUDIO VIDE] Bonjour. Dans cette leçon, nous allons parler d'un mécanisme très important dans les systèmes à microcontrôleurs : les interruptions. Au cours de notre exposé, nous parlerons des principes fondamentaux des interruptions, nous verrons les événements pouvant provoquer les interruptions, puis la mise en œuvre de ce mécanisme, et nous finirons par deux exemples. Un système à microcontrôleur possède généralement, des entrées et des sorties. Le but premier du programme est de réagir correctement aux différents changements sur les entrées en agissant sur les sorties. Il faut noter que les afficheurs et enseignes à LED sont une exception dans ce domaine, car possèdent très peu d'entrées. Des enseignes et afficheurs à LED peuvent avoir des entrées, par exemple, une télécommande pour éteindre ou allumer l'afficheur, un bouton poussoir pour augmenter ou diminuer la luminosité, ou même changer le texte à afficher. Il existe des cas où le système à microcontrôleur doit réagir à des événements. C'est le cas d'un afficheur multiplexé, où nous avons une gestion rigoureuse du temps. Dans ce cas-là , le système doit, à des moments bien précis, envoyer de nouvelles valeurs sur les LED. Une interruption en informatique est l'arrêt temporaire et inattendu, d'un programme en cours d'exécution au profit d'un autre programme jugé à ce moment plus important. Nous voyons bien que la notion d'interruption en informatique correspond au sens que nous lui donnons dans la vie courante. Exemple, je suis assis au bureau en train de travailler, le téléphone sonne, j'arrête le travail pour répondre au téléphone. Après la conversation, je reprends le travail là où je l'avais interrompu. Comme nous le voyons, c'est toujours un événement qui provoque une interruption. Cet événement a un caractère imprévisible. Le programme ne sait pas quand il va se produire, cet événement. Pour utiliser les interruptions, nous n'avons pas besoin de comprendre en détail le mécanisme qui les rend possibles. C'est un peu comme les fonctions, et les procédures, en langage évolué, que nous utilisons sans toutefois comprendre le détail de leur fonctionnement. Voici le programme principal dont les instructions sont représentées ici en bleu. Lorsque certaines instructions doivent être reprises plusieurs fois, nous formulons une routine ou sous routine. Le programme principal s'exécute. À un instant donné, nous avons besoin des services de la routine. Avec l'instruction CALL nous appelons la routine que nous exécutons. L'instruction RET nous permet de revenir dans le programme principal que nous continuons. À un instant bien précis, nous avons également besoin des services de la même routine, nous appelons la routine ici, et nous l'exécutons. Nous avons ici la routine d'interruption. Pendant l'exécution du programme, à cet instant bien précis, nous avons un événement qui provoque l'exécution de la routine d'interruption. La fin de la routine d'interruption est matérialisée par RETI qui nous permet de revenir au programme principal et de continuer son exécution. La suite, nous remarquons que, à ce niveau se produit le même événement, alors nous lançons la routine d'interruption qui s'exécute. À la fin de la routine, nous revenons au programme principal. Deux sortes d'événements produisent des interruptions. Nous avons les événements extérieurs au microcontrôleur, par exemple changement d'état sur une ligne en entrée ; des événements intérieurs au microcontrôleur, exemple, fin de conversion en point convertissant analogique numérique. Nous avons également des événements liés au timer. Le sujet du timer sera repris en détail dans une prochaine leçon. Il y a plusieurs sources d'interruption sur un microcontrôleur. Le système doit être capable de reconnaître la source d'interruption. Pour reconnaître la source d'interruption, deux techniques sont utilisées. Nous avons la consultation des fanions, et les vecteurs d'interruption. Dans certains microcontrôleurs, on peut combiner ces deux techniques. C'est le cas du MSP430 que nous étudions. Cette table nous donne la liste des vecteurs d'interruption sur MSP430G. Nous voyons ici quelques vecteurs d'interruption sur un microcontrôleur MSP430. Nous remarquons le vecteur d'interruption pour le port 1, et le vecteur d'interruption pour le port 2. Là , le vecteur d'interruption pour le convertisseur analogique-numérique 10 bits, le vecteur d'interruption pour le timer zéro, et le vecteur d'interruption pour le reset. La mise en œuvre d'une interruption passe par trois étapes. Dans la première étape, nous autorisons l'interruption qui nous intéresse. Dans la deuxième étape, nous précisons comment cette interruption doit fonctionner. Par exemple pour une entrée, il faut préciser le flanc actif. La dernière étape consiste à autoriser globalement les interruptions. Montrons sur ce schéma comment la mise en œuvre des interruptions se fait. Nous avons ici la logique de décodage des événements, qui lorsqu'un événement apparaît ici, le fanion va se mettre à 1. Lorsque le fanion d'autorisation de l'interruption est mis à 1 ici, ce qui rend la porte ET passante, et nous arrivons au niveau de cette porte OU. Plusieurs autres sources d'interruption peuvent arriver là , ce qui permet d'activer cette entrée de la porte ET que voici. Lorsque nous avons l'autorisation générale des interruptions, nous avons finalement à la sortie ici le signal d'interruption. Nous présentons ici la syntaxe de routine d'interruption en C. Il faut noter que cette syntaxe n'est pas normalisée car elle dépend des différents compilateurs. Nous avons ici choisi une syntaxe qui est acceptée par le compilateur GCC. La première ligne présente le numéro du vecteur d'interruption, ensuite la ligne suivante nous indique le nom d'une procédure avec void pour dire que cette procédure n'a pas de paramètre. Pour les lignes d'entrée sortie, nous avons à notre disposition les quatre registres suivants. P1DIR pour signifier si la ligne est en entrée ou en sortie, P1OUT pour nous donner la valeur de sortie, P1IN pour nous donner la valeur des entrées, P1REN qui nous permet d'activer la résistance de tirage ou de pull-up. Dans le cas où nous devons utiliser une interruption sur une ligne d'entrée, nous devons utiliser les registres complémentaires que voici. P1IE Interrupt Enable : c'est dans ce registre que nous autorisons l'interruption qui nous intéresse. P1IES Interrupt Edge Select nous permet de choisir le flanc actif. Donc c'est dans ce registre que nous précisons s'il s'agit d'un flanc montant ou d'un flanc descendant. P1IFG Interrupt Flag est le drapeau des fanions d'interruption. En consultant ce registre, nous pouvons savoir quelle est la broche qui a produit l'interruption. Ces trois registres que nous venons de voir agissent à ce niveau pour P1IE, l'autorisation de l'interruption qui nous intéresse, P1IES qui nous permet de choisir le flanc agit à ce niveau. Donc nous voyons que P1 IES est relié à la logique de décodage de l'évènement. P1IFG, le registre d'un fanion d'interruption, se trouve à ce niveau. Voici un programme qui nous permet de faire la mise en œuvre des interruptions. Nous avons une LED verte sur la ligne P1.6, sur la ligne P1.3, nous avons une entrée. La LED verte doit changer d'état à chaque flanc montant de l'entrée P1.3. Cette ligne nous permet de stopper le watchdog timer. Ces deux instructions permettent de faire un pull-up sur l'entrée P1.3. Nous choisissons un flanc descendant en mettant à 1 le bit 3 de P1IES. Nous autorisons l'interruption pour la ligne P1.3 par cette instruction. Nous maintenons à zéro le fanion d'interruption, qui est dans P1IFG. Cette ligne autorise globalement les interruptions. Le programme principal ne fait rien, comme nous le voyons ici. Lorsque nous aurons un événement sur la ligne P1.3, c'est-à -dire un flanc descendant sur la ligne P1.3, la routine d'interruption va s'exécuter. Regardons en détail cette routine d'interruption. Cette ligne précise qu'il s'agit du vecteur d'interruption du PORT1. Voici, ici, le plan de la routine et cette instruction permet de mettre à 0 le fanion. La dernière ligne inverse l'état de la LED verte. Voici une variante du programme précédent. Ici, nous avons deux entrées actives. L'entrée P1.3 et l'entrée P1.4. Dans la routine d'interruption, nous voyons bien que nous faisons une consultation de ces deux entrées. L'interruption montre qu'ici, nous faisons une consultation de l'entrée P1.3. Nous remettons à 0 son fanion et nous faisons les actions associées à cette entrée. Dans la deuxième ligne, nous refaisons la même chose, mais pour l'entrée P1.4. Ce programme fait intervenir un convertisseur analogique numérique 10 bits. Comme la conversion dure un certain temps, l'interruption va se faire à la fin de la conversion. Ces trois lignes permettent de configurer correctement le convertisseur analogique. Remarquons ici ADC10IE, qui nous permet d'autoriser l'interruption. La ligne que nous reconnaissons là autorise globalement les interruptions. Nous lançons le convertisseur pour la première conversion grâce à cette instruction et remarquons que le programme principal ne fait absolument rien. Mais, à la fin de la conversion, un signal d'interruption sera envoyé, la routine d'interruption va s'exécuter. Dans cette routine d'interruption que nous avons ici, nous remarquons que nous gardons, dans la variable val, la valeur obtenue après conversion. Nous lançons une autre conversion. Ensuite, nous comparons la valeur val à la moitié de la valeur maximale. Si la tension lue est supérieure à cette moitié, la LED verte s'allume. Dans cette leçon, nous avons vu les principes fondamentaux des interruptions. Les événements provoquant les interruptions internes ou externes. Nous avons fait la mise en œuvre du mécanisme des interruptions et montré deux exemples.