5 - Utiliser un "bouton poussoir" avec un "GPIO in" : Différence entre versions

De Wiki L.A.B
Aller à : navigation, rechercher
Ligne 14 : Ligne 14 :
 
* avec des interruptions: Les microcontrôleurs implémentent une technique dit "interrupt": Le code peut exécuter d'autres taches, mais le code va être interrompu dès que le bouton est poussé. Une fonction spéciale (appelé "interrupt handler" ou "interrupt service routine") est exécuté. Après la fin de cette fonction, le code interrompu reprend la main et continue son exécution.
 
* avec des interruptions: Les microcontrôleurs implémentent une technique dit "interrupt": Le code peut exécuter d'autres taches, mais le code va être interrompu dès que le bouton est poussé. Une fonction spéciale (appelé "interrupt handler" ou "interrupt service routine") est exécuté. Après la fin de cette fonction, le code interrompu reprend la main et continue son exécution.
  
=== Utiliser le button poussoir en mode "polling" ===
+
=== Utiliser le bouton poussoir en mode "polling" ===
  
 
<b> Création du Projet </b>
 
<b> Création du Projet </b>
Ligne 22 : Ligne 22 :
 
<b>Configuration du Pinout </b>
 
<b>Configuration du Pinout </b>
 
<br>- Cliquer sur le PC13
 
<br>- Cliquer sur le PC13
<br>- Séléctionner GPIO_Input
+
<br>- Sélectionner GPIO_Input
 +
<br>- Cliquer sur PA5
 +
<br>- Sélectionner GPIO_Output
 
<br>
 
<br>
 
[[Fichier:STM32CubeMX_BouttonPoussoir_GPIOInputPC13.png]]
 
[[Fichier:STM32CubeMX_BouttonPoussoir_GPIOInputPC13.png]]
Ligne 35 : Ligne 37 :
  
 
   /* USER CODE BEGIN 0 */
 
   /* USER CODE BEGIN 0 */
   uint8_t ButtonPressed;
+
   uint8_t ButtonPressed=0;
  
 
<br>- Créer les boucles permettant de régir l'état de la LED selon l'action sur le bouton poussoir. Ajouter les lignes suivantes sous la boucle infinie while(1)
 
<br>- Créer les boucles permettant de régir l'état de la LED selon l'action sur le bouton poussoir. Ajouter les lignes suivantes sous la boucle infinie while(1)
Ligne 74 : Ligne 76 :
 
<b>Configuration du Pinout </b>
 
<b>Configuration du Pinout </b>
 
<br>- Cliquer sur le PC13  
 
<br>- Cliquer sur le PC13  
<br>- Séléctionner GPIO_EXTI13  
+
<br>- Séléctionner GPIO_EXTI13
 +
<br>- Cliquer sur PA5
 +
<br>- Sélectionner GPIO_Output
 
<br>
 
<br>
  
Ligne 96 : Ligne 100 :
 
<br> User Label : PUSH_BUTTON
 
<br> User Label : PUSH_BUTTON
 
<br> - Cliquer "Apply" et "OK"
 
<br> - Cliquer "Apply" et "OK"
 +
  
 
<br>
 
<br>
 
[[Fichier:STM32CubeMX_BouttonPoussoir_GPIOConf.png]]
 
[[Fichier:STM32CubeMX_BouttonPoussoir_GPIOConf.png]]
 +
<br>
 +
<b>Générer le code </b>
 +
<br>- Cliquer sur "Project" > "Settings"
 +
<br>- Choisissez l'emplacement approprié (sous votre espace de travail ou workspace sous Eclipse) et assurez vous que le "Toolchain/IDE" soit bien configuré en tant que "SW4STM32" avant de valider.
 +
<br>
  
  
 +
<b> Ouvrir votre workspace sous Eclipse </b>
 +
<br>- Ouvrir le fichier "main.c"
 +
<br>- Créer la variable ButtonPressed et l'initialiser à l'état 0
  
   void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
+
  /* USER CODE BEGIN 0 */
 +
  uint8_t ButtonPressed=0;
 +
<br>- Ecrire la fonction qui value la valeur de la variable booléenne ButtonPressed en fonction de l'état du bouton poussoir.
 +
 
 +
   void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
 
   {
 
   {
   if ( GPIO_Pin == GPIO_PIN_13 )
+
   if ( GPIO_Pin == PUSH_BUTTON_Pin )
  {
+
    GPIO_PinState PinState;
    GPIO_PinState PinState;
+
    //PinState = HAL_GPIO_ReadPin( GPIOC, GPIO_PIN_13);
    PinState = HAL_GPIO_ReadPin( GPIOC, GPIO_PIN_13);
+
    PinState = HAL_GPIO_ReadPin( PUSH_BUTTON_GPIO_Port, PUSH_BUTTON_Pin); // on retrouve la correspondante entre GPIO_PIN_13 et PUSH_BUTTON_Pin dans le fichier main.h
    if ( PinState == GPIO_PIN_RESET )
+
    if ( PinState == GPIO_PIN_RESET )
    ButtonPressed = 1;
+
      ButtonPressed = 1;
    else
+
    else
    ButtonPressed = 0;
+
      ButtonPressed = 0;
  }
+
 
   }
 
   }
 +
<br>- Créer les boucles permettant de régir l'état de la LED selon l'action sur le bouton poussoir. Ajouter les lignes suivantes sous la boucle infinie while(1)
 +
 +
 +
  while ( ButtonPressed == 0 )                        // block until button pressed
 +
  {
 +
  GPIO_PinState PinState;
 +
  PinState = HAL_GPIO_ReadPin( GPIOC, GPIO_PIN_13);  // get current state of pin
 +
  if ( PinState == GPIO_PIN_RESET )
 +
    ButtonPressed = 1;
 +
  else
 +
    ButtonPressed = 0;
 +
  }
 +
  HAL_GPIO_WritePin( GPIOA, GPIO_PIN_5, GPIO_PIN_SET);
 +
 +
  while ( ButtonPressed == 1 )                       
 +
  {
 +
  GPIO_PinState PinState;
 +
  PinState = HAL_GPIO_ReadPin( GPIOC, GPIO_PIN_13);
 +
  if ( PinState == GPIO_PIN_RESET )
 +
    ButtonPressed = 1;
 +
  else
 +
    ButtonPressed = 0;
 +
  }
 +
  HAL_GPIO_WritePin( GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);

Version du 2 janvier 2018 à 18:30

Utiliser un "bouton poussoir" avec un "GPIO in"

Dans cet atelier, on va regarder comment utiliser des GPIO in pour connecter un bouton poussoir.
Dans notre exemple nous allons utiliser la carte “Nucleo64” de référence “NUCLEO-L476RE”.
NUCLEO476.jpg
Cette carte embarque un bouton bleu appelé "USER BUTTON" connecté au pin2 (I/O PC13) dans la doc. Ainsi on peut l'utiliser sans hardware supplémentaire.
Pour info: Il y a aussi un bouton noir sur la carte. Ceci reset la carte et fait redémarrer le code ("reboot").
UserButton Pin2 PC13.jpg

Il y a deux possibilités d'utiliser les boutons poussoir:

  • en polling: On appelle un fonctionnement de code "en polling", si le code lit à l’intérieur d'une boucle l'état d'un périphérique (par exemple notre bouton, qui peut avoir les états "poussé" et "non poussé"). Le programme attend d’exécuter les instructions tant qu'un état de périphérique n'est pas détécté. Ainsi le code devient bloquant et ne peut pas exécuter d'autres taches. Cette signification ne convient seulement aux situations simples (ou si le programme fonctionne en "multi thread").
  • avec des interruptions: Les microcontrôleurs implémentent une technique dit "interrupt": Le code peut exécuter d'autres taches, mais le code va être interrompu dès que le bouton est poussé. Une fonction spéciale (appelé "interrupt handler" ou "interrupt service routine") est exécuté. Après la fin de cette fonction, le code interrompu reprend la main et continue son exécution.

Utiliser le bouton poussoir en mode "polling"

Création du Projet
- Créer un nouveau projet dans STM32CubeMX
- Sélectionner la carte Nucleo64-L476RG
Configuration du Pinout
- Cliquer sur le PC13
- Sélectionner GPIO_Input
- Cliquer sur PA5
- Sélectionner GPIO_Output
STM32CubeMX BouttonPoussoir GPIOInputPC13.png
Générer le code
- Cliquer sur "Project" > "Settings"
- Choisissez l'emplacement approprié (sous votre espace de travail ou workspace sous Eclipse) et assurez vous que le "Toolchain/IDE" soit bien configuré en tant que "SW4STM32" avant de valider.

Ouvrir votre workspace sous Eclipse
- Ouvrir le fichier "main.c"
- Créer la variable ButtonPressed et l'initialiser à l'état 0

 /* USER CODE BEGIN 0 */
 uint8_t ButtonPressed=0;


- Créer les boucles permettant de régir l'état de la LED selon l'action sur le bouton poussoir. Ajouter les lignes suivantes sous la boucle infinie while(1)


 while ( ButtonPressed == 0 )                        // block until button pressed
 {
  GPIO_PinState PinState;
  PinState = HAL_GPIO_ReadPin( GPIOC, GPIO_PIN_13);  // get current state of pin
  if ( PinState == GPIO_PIN_RESET )
   ButtonPressed = 1;
  else
   ButtonPressed = 0;
 }
 HAL_GPIO_WritePin( GPIOA, GPIO_PIN_5, GPIO_PIN_SET);
 while ( ButtonPressed == 1 )                        
 {
  GPIO_PinState PinState;
  PinState = HAL_GPIO_ReadPin( GPIOC, GPIO_PIN_13); 
  if ( PinState == GPIO_PIN_RESET )
   ButtonPressed = 1;
  else
   ButtonPressed = 0;
 }
 HAL_GPIO_WritePin( GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);

- On observe que la LED s’éteint dès qu'on appuie sur le bouton poussoir et s'allume dès qu'on le relâche conformément à ce que nous avons écrit dans nos 2 boucles while

Utiliser le bouton poussoir en mode "interrupt"

Création du Projet
- Créer un nouveau projet dans STM32CubeMX
- Sélectionner la carte Nucleo64-L476RG

Configuration du Pinout
- Cliquer sur le PC13
- Séléctionner GPIO_EXTI13
- Cliquer sur PA5
- Sélectionner GPIO_Output

STM32CubeMX BouttonPoussoir GPIOEXTI13.png


Configuration du NVIC
- Cliquer sur l'onglet "Configuration"
- Cliquer sur "NVIC"
- Cocher la case correspondant à la ligne "EXTI line interrupts" pour l'activer
STM32CubeMX BouttonPoussoir GPIOEXTI13 NVIC.png

Configuration du GPIO
- Sous l'onglet "Configuration", cliquer sur "GPIO"
- Configurer le PC13 comme suit (le label PUSH_BUTTON permettra de faciliter l'identification du bouton poussoir dans notre programme plutôt que d'avoir à se rappeler du pin associé):
GPIO mode : External Interrupt Mode with Rising/Falling edge trigger detection
GPIO Pull-up/Pull-down : No pull-up and no pull-down
User Label : PUSH_BUTTON
- Cliquer "Apply" et "OK"



STM32CubeMX BouttonPoussoir GPIOConf.png
Générer le code
- Cliquer sur "Project" > "Settings"
- Choisissez l'emplacement approprié (sous votre espace de travail ou workspace sous Eclipse) et assurez vous que le "Toolchain/IDE" soit bien configuré en tant que "SW4STM32" avant de valider.


Ouvrir votre workspace sous Eclipse
- Ouvrir le fichier "main.c"
- Créer la variable ButtonPressed et l'initialiser à l'état 0

 /* USER CODE BEGIN 0 */
 uint8_t ButtonPressed=0;


- Ecrire la fonction qui value la valeur de la variable booléenne ButtonPressed en fonction de l'état du bouton poussoir.

 void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
 {
  if ( GPIO_Pin == PUSH_BUTTON_Pin )
    GPIO_PinState PinState;
    //PinState = HAL_GPIO_ReadPin( GPIOC, GPIO_PIN_13);
    PinState = HAL_GPIO_ReadPin( PUSH_BUTTON_GPIO_Port, PUSH_BUTTON_Pin); // on retrouve la correspondante entre GPIO_PIN_13 et PUSH_BUTTON_Pin dans le fichier main.h
    if ( PinState == GPIO_PIN_RESET )
      ButtonPressed = 1;
    else
      ButtonPressed = 0;
 }


- Créer les boucles permettant de régir l'état de la LED selon l'action sur le bouton poussoir. Ajouter les lignes suivantes sous la boucle infinie while(1)


 while ( ButtonPressed == 0 )                        // block until button pressed
 {
  GPIO_PinState PinState;
  PinState = HAL_GPIO_ReadPin( GPIOC, GPIO_PIN_13);  // get current state of pin
  if ( PinState == GPIO_PIN_RESET )
   ButtonPressed = 1;
  else
   ButtonPressed = 0;
 }
 HAL_GPIO_WritePin( GPIOA, GPIO_PIN_5, GPIO_PIN_SET);
 while ( ButtonPressed == 1 )                        
 {
  GPIO_PinState PinState;
  PinState = HAL_GPIO_ReadPin( GPIOC, GPIO_PIN_13); 
  if ( PinState == GPIO_PIN_RESET )
   ButtonPressed = 1;
  else
   ButtonPressed = 0;
 }
 HAL_GPIO_WritePin( GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);