• 30 hours
  • Medium

Free online content available in this course.

course.header.alt.is_video

course.header.alt.is_certifying

Got it!

Last updated on 7/18/24

Entraînez-vous en détectant l'appui sur un bouton

À vous de jouer !

Cette activité a pour but de finaliser le jeu que vous avez commencé à réaliser dans la partie précédente.

Rappelons l'objectif global : un joueur doit appuyer sur un bouton quand une LED s’allume et avant qu'elle ne s'éteigne. Le moment auquel s’allume la LED est aléatoire. Le joueur aura seulement 300 ms pour réagir, la LED s’éteignant ensuite. Si le joueur gagne, alors la LED se met à clignoter 4 fois par seconde.

Le chronogramme ci-dessous reprend ce fonctionnement. Pendant la phase notée 1, le système s’initialise, puis après une durée aléatoire la LED s’allume pendant 300 ms (2 sur le schéma). Si le joueur appuie sur le bouton (événement noté 3) quand la LED est allumée alors elle se met à clignoter régulièrement (phase 4), sinon la LED s’éteint avant d’être de nouveau allumée après une durée aléatoire.

Chronogramme illustrant le fonctionnement du jeu
Chronogramme illustrant le fonctionnement du jeu

Composants du système

Le système est toujours composé de :

  • la LED verte (nommée LD2) de la carte Nucleo : elle est branchée sur la broche 5 du port A (le mode de configuration de la broche de sortie doit être output push-pull),

  • le bouton USER (bouton bleu) : le bouton est connecté sur la broche 13 du port C (la broche devra être configurée en input floating).

Il va falloir maintenant ajouter un moyen pour détecter l'appui du bouton et vérifier que cela s'est bien produit pendant que la LED est allumée.

La difficulté de cette activité ne réside pas dans les fonctionnalités à réaliser, mais dans la configuration de l'interruption externe. Pour cela vous allez devoir rechercher, lire et comprendre la documentation.

Vous partirez du fichier main_v2.c qui correspond à la correction de l'activité précédente et ajouterez simplement la fonction void configure_afio_exti_pc13() qui permet de configurer une interruption externe pour capter l'appui du bouton, ainsi que la ou les fonctions d'interruption pour finaliser le jeu.

Contraintes 

Pour capter l'appui du bouton, vous ne devez pas faire d’attente active (scrutation), mais travailler uniquement sous interruption. Votre main ne doit donc contenir que les fonctions d’initialisation, une fonction pour lancer le premier timer et une boucle while(1).

Vous devez gérer le bouton à l’aide d’une interruption sur événement externe (voir documentation page 206). L’interruption doit se faire sur un front descendant (la logique du bouton est inversée). Pour simuler une interruption externe, regardez la vidéo ci-dessous.

Vous devez aussi tester votre application en simulation pour vérifier que le système fonctionne correctement. Pour cela, vérifiez bien que :

  • le joueur ne peut gagner que si la LED est allumée,

  • la période de clignotement de la LED après avoir gagné est bien de 250 ms.

Vérifiez bien que vous avez les éléments suivants.

Vous devez rendre uniquement le fichier main_v2.c que vous avez modifié. Ne créez pas de fichier d’en-tête ou d’autres fichiers pour structurer votre code. 

Vérifiez votre travail

Attention, il peut y avoir plusieurs solutions pour réaliser l’application de jeu. Ce qui compte ici n’est pas la qualité de ces fonctionnalités, mais la maîtrise des éléments de configuration et d’utilisation des périphériques d’un microcontrôleur. Il faut donc avant tout regarder si les configurations sont justes.

Vérifiez que le fichier main_v2.c compile bien, si ce n’est pas le cas trouvez-en les raisons. Si vraiment rien n'y fait, vérifiez par une simple lecture les éléments à corriger, mais si ça ne compile pas, c'est qu'a priori il y a un problème.

Les éléments à vérifier sont :

  • La qualité globale du code : est-ce qu’il est bien structuré, est-ce qu’il est un minimum commenté ?

  • La configuration de l'interruption externe et des fonctions d’interruption : est-ce que l'interruption est bien activée au niveau du périphérique ainsi qu’au niveau du NVIC ? est-ce que les fonctions d’interruption ont bien été réalisées et est-ce que la source d’interruption est validée ?

Vous devez ensuite évaluer le fonctionnement du code en vérifiant en simulation, ou en réel, si :

  • la configuration de l'interruption externe est bien validée au niveau du périphérique et du NVIC ?

  • la configuration de l'interruption périodique permet de faire clignoter la LED  ?

Vous pouvez de nouveau mettre en place une approche par test pour vérifier tout cela.

Pour répondre aux besoins, j’ai décidé de configurer une interruption externe sur la broche du port C, ainsi que le timer TIM4 pour gérer le clignotement de la LED. Il aurait aussi été possible d'utiliser le timer TIM2 ou TIM3 pour faire cela.

Dans l'exemple de correction, pour savoir si le joueur a bien appuyé au bon moment, on utilise une simple variable globale, led_on,  qui a pour valeur 0 si la LED est allumée et 0 si elle est éteinte. Cette variable est mise à jour dans les interruptions des timers quand on éteint et allume la LED. Cela peut se représenter par :

Chronogramme de la solution proposée
Chronogramme de la solution proposée

Il aurait été possible de regarder directement l'état de la broche en lisant le bon bit dans le registre ODR.

Example of certificate of achievement
Example of certificate of achievement