Programmation de microcontrôleurs STM32: Interruptions
Cette page vise à présenter une première utilisation des interruptions sur un microcontrôleur STM32. À la suite de cette page, un développeur logiciel doit être capable:
- De trouver les informations nécessaires dans une datasheet pour l’utilisation des interruptions,
- De programmer les différents registres pour l’utilisation d’une interruption,
- De comprendre le fonctionnement pour différentes sources d’interruption.
Détection d’un évènement
Précédemment, nous avons utilisé un bouton poussoir pour déclencher l’allumage d’une LED. La détection de l’état du bouton était alors faite de manière scrutative: le programme vérifiait régulièrement l’état du registre correspondant. Bien que fonctionnel, ce type de fonctionnement est peu efficace: le microcontrôleur exécute en boucle des opérations pour détecter le changement d’état. Ainsi, il ne peut exécuter aucune autre tâche utile pendant ce temps d’attente, en plus de continuer à consommer en réalisant les calculs.
Les interruptions sont un moyen de répondre à ces limitations. L’idée derrière ce mécanisme matériel est de permettre au processeur d’être prévenu lorsqu’un évènement a lieu. Différents évènement peuvent être configurés: changement d’état d’une broche, le débordement d’un compteur etc. Lorsque le processeur en est informé, il interrompt l’exécution en cours pour traiter l’évènement.
Dans cette première partie, nous allons voir comment ce mécanisme peut être utilisé pour détecter le changement d’état d’un bouton poussoir.
Comme précédemment, configurez la broche du bouton poussoir (broche 13 du GPIOC) dans l’état suivant:
- MODE: Input,
- RÉSISTANCE DE RAPPEL: pull-up.
ISER du NVIC, activez l’interruption correspondant à la ligne EXTI susceptible de recevoir un changement d’état du bouton-poussoir.Aide supplémentaire (si nécessaire)
Chaque ligne EXTIx est susceptible de détecter un évènement sur la broche x d’un des ports.
Ainsi, pour la ligne à activer pour le bouton poussoir est celle correspondants aux broches 13: EXTI15_10.
De base, le signal d’horloge pour certains modules du système est désactivé. Pour les interruptions depuis un GPIO, il est nécessaire de réactiver le signal d’horloge pour SYSCFG. Pour cela, il est nécessaire d’ajouter la ligne de code suivante:
RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN;
EXTICR dans SYSCFG permet de choisir le port de déclenchement sur chaque ligne.
Modifiez le registre EXTICR pour que la ligne EXTI13 utilise le port C du bouton poussoir.IMR de EXTI en mettant le bit pour EXTI13 dans l’état correspondant.RTSR et FTSR sont mis à disposition, respectivement pour activer/désactiver un déclenchement sur front montant ou descendant.
Configurez ces deux registres pour ne lancer une interruption que lorsque le bouton est pressé.Toutes les étapes précédentes permettent d’activer et paramétrer l’activation d’une interruption sur la ligne EXTI13 depuis la broche 13 du GPIOC.
L’étape suivante est de créer la fonction qui sera appelée lorsque l’évènement configuré sera détecté: c’est qu’on appelle le handler.
Pour cela, des noms sont prédéfinis par l’environnement de programmation STM32 permettant de remplir automatiquement le vecteur d’interruptions du NVIC avec l’adresse de la fonction correspondante.
Dans le cas de l’évènement EXTI15_10, la fonction est alors:
void EXTI15_10_IRQHandler(void) {
// Contenu
}
EXTI15_10_IRQHandler et lancez l’exécution du programme.
Que se passe-t-il si vous appuyez sur le bouton-poussoir ?0.
Pour cela, utilisez le bit correspondant dans le registre PR de EXTI.Communication main / handler
On aimerait à présent concevoir un système où la fonction main fait clignoter la LED à un rythme variable.
Ce rythme pourra ensuite être modifié selon le nombre de pressions effectuées sur le bouton poussoir: plus le bouton est pressé un grand nombre de fois, plus le clignotement accélère ou inversement.
Pour cela, nous allons devoir faire des échanges d’informations entre les deux fonctions.
main pour qu’elle fasse clignoter la LED selon la valeur d’une variable tempo.tempo d’une valeur N à chaque exécution.Aide supplémentaire (si nécessaire)
Les variables locales sont internes à chaque fonction. Les variables globales sont accessibles depuis n’importe quelle fonction.
tempo d’une valeur N jusqu’à 0.
Si la valeur tempo est déjà à 0, alors la variable tempo doit être augmentée d’une valeur N jusqu’à une valeur maximale libre.Aide supplémentaire (si nécessaire)
Pour savoir le sens utilisé (augmentation ou diminution de tempo), vous pouvez utiliser une nouvelle variable pour stocker l’information.
Source d’interruption logicielle
Généralement, les évènement déclenchant une interruption sont proviennent d’un composant matériel, souvent extérieur (e.g. par le biais d’une broche de GPIO).
Cependant, il est aussi possible de déclencher une interruption du logiciel.
Cela peut-être utile pour du débogage, synchroniser plusieurs applications, réutiliser des routines existantes etc.
Dans le cas des cartes Nucleo-F446RE, les lignes d’interruptions EXTI peuvent être activées par un évènement extérieur (GPIO) ou alors depuis le logiciel en écrivant dans le registre SWIER d’EXTI.
EXTI13, paramétrez une routine qui s’active lorsqu’une interruption arrive sur la ligne EXTI4.
Générez ensuite cette exception depuis le main avec le registre SWIER d’EXTI.IPR du NVIC, modifiez la priorité des interruptions venant de EXTI4 et EXTI13 pour que la seconde puisse pré-emptée la première.
En effectuant une exécution en mode debogage, validez ensuite le fonctionnement du système.