Topic "[STM32] Premiers pas avec CubeMix"

Flux RSS des posts récents dans ce topic ( Flux Atom)


Pas de photo de profil

weetoz

Membre

#157 | Signaler ce message



Introduction.

Aujourd'hui, nous allons voir comment configurer des entrées et des sorties afin d' allumer quelques leds grâce à des boutons poussoirs. Pour ça nous allons utiliser CubeMix, qui nous servira à générer un code de base avec la librairie Cube HAL.

Nous utiliserons deux boutons et trois diodes que nous ajouterons à nos cartes.

Liste du matériel.

    • Une breadboard.

    • Trois LEDs. ( rouge, vert bleu).

    • Trois résistances de 180 Ohms, ou si vous n' en avez pas, 220 Ohms ferons l' affaire.

    • Deux boutons poussoirs pour CI traversant ( ceux qu' on trouve dans les kits).

    • Deux condensateurs pour les anti rebond, la valeur dépend des boutons, généralement entre 10 et 100nF.

    • Des câbles Dupont.

Présentation de CubeMix.

Si ce n'est fait, lancez STM32CubeMix, une habitude à prendre c'est de fair un « Check for Update » via le menu Help, ou plus simplemùent Alt+C, cliquez sur « Check ».

Cliquez sur « New Project ».

Sélection de la carte.

Periphéral selection.

Nous sommes à présent dans l' onglet MCU Selector. Vous pouvez observer en encadré vert la liste des périphérique qu' il est possible de choisir. Ils sont assez nombreux, et pour certains en plusieurs fois. Prenons le cas de ADC 12-bits :

Dans la colonne Max apparaît en grisé le nombre maximum de périphérique ADC 12-Bits qu' il est possible d' obtenir, soit quarante. Dans la colonne Nb, saisissez ce chiffre et appuyez sur la touche Entrée. Vous voyez que la liste des µCs se réduit pour ne laisser paraître qu' une dizaine de µCs. C'est très pratique pour choisir le type de µCs pour une application défini.

Board Selector.

Cliquez maintenant sur l' onglet Board Selector.

La première chose que l' on constate, c' est que ADC 12-Bits a disparut de la liste Peripheral Selection. Si on retrouve le CAN ainsi que quelques autes périph., on trouve à présent des choses comme Button, Accelerometer, Gyroscope… La liste s'est juste adapté à l' électronique embarqué possible sur les cartes. Si vous voulez trouver quelle carte correspond à vos besoins, il faut déjà déterminer quel type de µC il faut pour votre projet dans l'onglet MCU Selector.

Il y a trois filtres de présélections, et un bouton à gauche de l' écran :

  1. Vendor -Aucune utilitée dans l' état actuel des choses.

  2. Type of Board-Choisissez ici votre type de carte.

  3. MCU Series-Choisissez ici votre type de µC.

  4. Bouton Affiche une image de la carte sélectionné.

Voici un exemple avec ma Nucleo F303K8 :

On voit tout de suite que la liste Peripheral Selection s' est réduite pour ne laisser apparaître que le contenu d' électroniques embarquées.

Il est intéressant de regarder la liste Peripheral Selection du µC embarqué sur la carte Nucleo F303K8 :

On voit bien que l' on dispose de dix entrées analogiques en 12 bits ( ADC 12-Bits ) ainsi que de trois sorties analogiques en 12 bits également ( DAC 12-Bits ). Sans renrter dans les détails, ce qui est important, c'est de ne pas avoir peur de fouiner dans ces deux onglets pour trouver son compte.

Bien maintenant sélectionnez le modèle de votre carte, ou si vous ne vous sentez pas à l'aise, la Nucleo32_F303K8. Vous pourrez toujours refaire le tutoriel avec votre carte par la suite.

Une fois la carte sélectionné, cliquez sur OK.

L' onglet Pinout.

L'interface.

Vous arrivez maintenant sur l'interface de configuration graphique :

Dans l' encadré bleu, les onglets :

  • Pinout C'est ici que l' on configure les broches.

  • Liste des périphériques Paramétrages des périphériques.

  • Représentation graphique du µC Tout ce passe avec la sourie.

Les possibilités de configuration de broche.

Faite un clique gauche sur la broche PA_3 dans la Représentation graphique du µC. Une liste de périphériques pouvant être affectés à cette broche apparaît. Chaque broches propose des périphériques différents, par exemple pour la broche PA_3 de la Nucleo_32_F303 :

Selon votre µC, cette liste peut être différente. N' hésitez surtout pas à regarder les autres broches afin de voir quels périphériques peuvent leurs être affectés.

S' organiser avec ses périphériques.

Rien de tel qu' un tableau pour y voir plus clair lors des affectations des broches :

Broche physique

PORT / PIN

Nom Arduino

Périph 1

Périph 2

Périph 3

PWM(o/n)

1

PA_9

D1

TX_1

Tim1-ch2 Tim2 _ch3

DAC 1 et 2

o

2

PA_10

D0

RX_1

Tim17-BKIN Tim1-ch3 Tim2-ch4

TSC_G4_IO2

o

3

NRST

4

GND

5

PA_12

D2

CAN_TX

Tim16_ch1 Tim1_ch2N Tim1_ETR

USART1_DE USART1_RTS COMP2_out

o

6

PB_0

D3

Analog in ADC1_in11

TIM1_CH2n TIM3_CH3

COMP4 OPAMP2…

o

Je n' ai pas mis la totalité du tableau, c'est pour ce faire une idée. Le tableau pourrait contenir d'autres colonnes, et être agencé autrement. C'est juste un exemple. De cette manière, pour des projets plus gourmand en broche et en périphériques, il devient plus aisé de choisir quelle broche pour tel périphérique.

Le montage

Personnellement, j' ai choisi de prendre une LED RGB en guise de mes trois LEDs.

  • LED rouge câblé surla broche A4 soit le PORT_PIN PA_5.

  • LED verte câblé sur la broche A1 soit sur le PORT_PIN PA_1.

  • LED bleu câblé sur la broche A6 soit sur le PORT_PIN PA_7.

  • Le bouton 1 est câblé sur A3 soit PA_4, il servira à sélectionner une des trois LEDs.

  • Le bouton 2 est câblé sur A2 soit PA_3, il servira à allumer ou éteindre la LED sélectionné.

Je ne mets pas de schéma, vous en trouverez plein sur la toile.

Configuration des broches en mode graphique..

Passons aux choses sérieuses, nous allons configurer nos broches pour notre projet.

Les broches en sorties pour les LEDs.

Commençons par PA_5, dans la Représentation graphique du µC faite un clique gauche avec la sourie sur la broche concerné. Sélectionnez GPIO_Output, puis faite la même chose pour PA_1 et PA_7.

Les broches en entrées pour les boutons.

Mêmes opérations pour PA_4 et PA_3, mais en sélectionnant GPIO_Input

Voici ce que ça donne pour la Nucleo_32_F303 ::

Configaration « Serial Debug ».

Afin de pouvoir faire du débogage, il faut le paramétrer. Rien de plus simple, Cliquez sur SYS dans la zone Liste des périphériques, et en face de « Debug » sélectionnez « Serial wire ».

Cela permettra aussi d'utiliser le port série pour communiquer entre la carte et le PC. Je n'en ferais pas état dans cet article.

Option de configuration supplémentaire

Dans l' état actuel, nous ne savons pas exactement comment les entrées/sorties sont configurer.

Les résistances de tirages.

Les entrées/sorties sont configurés par défaut sans résistances de tirages. Cependant nous voudrions avoir des « Pulldown » sur nos entrées. Allez dans l' onglet Configuration, puis cliquez sur le bouton « GPIO ».

Cliquez sur une des lignes « Input mode », dans l' encadré violet sélectionné « PullDown ». Répétez cette opération pour chaque entrées.

Définir des noms pour les broches.

Il est possible de donner un nom à chaque GPIOs dans l' encadré rouge. Il prendra la forme suivante dans le code : #define B1_Pin GPIO_PIN_4 pour la broche et #define B1_GPIO_Port GPIOA. Nous retrouverons ces définitions dans le fichier « mxconstants.h ». Pour ce faire, nommez comme bon vous semble vos broches dans l' encadré rouge.

Comme toujours, n' hésitez pas à découvrir par vous même les possibilités de configurations.

Configuration graphique de l' horloge.

La première chose à savoir, c' est si il y a un dispositif externe d' horloge sur votre carte. (Quartz et/ou résonateur céramique). Rendez-vous sur la page produit de votre carte STM. Pour l' exemple, je vais sur la page produit de ma Nucleo_32. Il faut télécharger ou ouvrir le « PDF » User Manual.

Nous cherchons dans ce document le schéma de la carte.

Et plus précisément la partie « Clock ».

Sur cette carte, il a été prévu des emplacements pour recevoir un quartz et ses deux condensateurs de découplages. Cependant, aucun composant n' est présent sur ces emplacements, ce qui veut dire qu' il faut utiliser l'horloge interne du µC. Sur le « F303K8 » elle est de 8MHz.

Exemple de carte disco F100RB avec horloge externe présente :

Les « ponts » (encadré rouge) montrent les connections optionnels, ici la présence de résonateurs ne fait aucun doute. X2 pour le système, et X3 pour le « RTC » (Real Time Clock, pour la gestion de la date et l'heure).

Selon le µC embarqué sur la carte et dans le cas où il n' y a pas de résonateur, les fréquences de fonctionnement maximum ne pas être atteinte. C' est le cas de la Nucleo_32_F303 , donné pour 72MHz, mais ne peut atteindre « que » 64MHz avec son résonateur interne de 8MHz.

Si je voulais atteindre les 72MHz de ma carte, il faudrait alors que je soude un quartz de 12 MHz à l'emplacement prévu et ajouter un multiplicateur de 6 dans le « PLLMul ».

Dans CubeMix, cliquez sur l' onglet Clock Configuration.

Dans System Clock Mux (encadré en rouge de gauche) cliquez sur le bouton PLLCLK, ensuite sélectionnez dans *PLLMul « X16 », ou autre selon votre carte. Le but étant d' atteindre Votre HCLK est maintenant à 64MHz, cependant votre APBH Prescaler s'est mit en rouge. Rien de grave, sélectionnez « /2 », normalement c'est réglé. N' hésitez pas par la suite à expérimenter le configurateur d' horloge. Vous devriez à présent avoir quelque chose qui ressemble à ceci :

Bien évidement, selon le µC que vous utilisez ça pourrait ressembler à ça :

Selon votre carte essayez d' atteindre l' horloge maximum, des infos_bulles apparaissent lorsque vous passez votre sourie vous donnant de précieuses informations.

Génération du code.

Sauvegardez votre configuration dans un emplacement facile à retrouver. Soit dans le menu File et Save Project As… soit avec le raccourci clavier Ctrl + A

Réglage du projet

Il nous faut faire quelque réglage de CubeMix avant de générer notre code.Dans le menu Project, cliquez sur Setting ou utilisez le raccourci clavier Alt + P . Vous voici avec cette fenêtre :

  • Dans Project Name Saisissez le nom de votre projet, par exemple »3Led_2BP » .

  • Dans Project Location, remplacez « sw4stK » par « Cube_Output ». Laissez « Generate under Root » décoché.

  • Dans Toolchain / IDE, sélectionnez « SW4STM32 ». Décochez « Generate under root ».

Le chemin de Toolchain Folder Location s'est changé tout seul pour s' adapter.

Cliquez sur l' onglet Code Generator. Sélectionnez «Copy all used libraries into the project folder» . Sélectionnez aussi «Backup previously generated files when re-generating». Pour le reste, laissez par défaut . Rien ne vous empêche de sélectionner « Set all free pins as analog (to optimize the power consumption)» et «Enable Full Assert»..

Cliquez sur OK.

Générer le code.

Rien de plus simple : Ctrl+Shift+G.

Une fois le code généré, cliquez sur Open Folder.

Importation du code généré dans SW4STM32.

Notre code de base est enfin généré, mais il faut encore l' importer dans SW4STM32.

Créer un nouveau projet.

Lancez AC6 SW4STM32, puis sélectionnez le Workspace où a été généré votre code. /home/weetoz/STM32Cube/Repository/Cube_Output/3led2BP. Cliquez sur OK.

Fermez l' onglet Welcome, cliquez sur Import… dans le menu File. Dans General, cliquez sur Existing Projects into Workspace pui Next.

En face de Select root_directory:, cliquez sur Browse…. Sélectionnez le répertoire « SW4STM32 » puis Valider et ensuite Finish.

Vous aurez peut-être une erreur de type:Symbol 'Systick_IRQn' could not be resolved. Dans ce cas remplacez la ligne :

1
HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);

par

1
HAL_NVIC_SetPriority(-1, 0, 0);

Vous aurez peut-être une liste d' erreurs assez nombreuses, vous pouvez essayer de les effacer et de faire un « Rebuild ».

Le « main.c »

On peut constater que le fichier main.c généré est long, mais bien pensé! Ce ne sont pas les commentaires qui manques, comme on peu le voir, c'est bien structuré.

La fonction MX_GPIO_Init();

On retrouve l' instruction qui renomme la structure GPIO_InitTypeDef en GPIO_InitStruct, juste en dessous le bloc d'instructions /* GPIO Ports Clock Enable*/

1
2
 __HAL_RCC_GPIOF_CLK_ENABLE();
 __HAL_RCC_GPIOA_CLK_ENABLE();

Ensuite le bloc d'instructions /*Configure GPIO pin Output Level */

1
 HAL_GPIO_WritePin(GPIOA, G_LED_Pin|R_LED_Pin|B_LED_Pin, GPIO_PIN_RESET);

Nous retrouvons la fonction que nous avions vu dans le tutoriel précédent, elle met à zéro les sorties.

En dessous, nous avons un bloc /*Configure GPIO pins : G_LED_Pin R_LED_Pin B_LED_Pin */, il concerne encore les sorties, mais cette c' est la configuration. Vous devriez reconnaître cette suite d' instructions, bien que un peu différentes.

1
GPIO_InitStruct.Pin = G_LED_Pin|R_LED_Pin|B_LED_Pin;

Cette ligne prend en compte les trois sorties, avec une opération binaire | « ou » . La manipulation bit à bit sort du cadre de ce tutoriel, mais si toutefois vous vouliez en savoir plus, je vous recommande l'article de Skywodd sur son blog Skyduino .

1
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;

Les sorties sont configurées en « Pushpull ». Voici les possibilités de configuration possibles :

GPIO_MODE_INPUT Input Floating Mode

GPIO_MODE_OUTPUT_PP Output Push Pull Mode

GPIO_MODE_OUTPUT_OD Output Open Drain Mode

GPIO_MODE_AF_PP Alternate Function Push Pull Mode

GPIO_MODE_AF_OD Alternate Function Open Drain Mode

GPIO_MODE_ANALOG Analog Mode

GPIO_MODE_IT_RISING External Interrupt Mode with Rising edge trigger detection

GPIO_MODE_IT_FALLING External Interrupt Mode with Falling edge trigger detection

GPIO_MODE_IT_RISING_FALLING External Interrupt Mode with Rising/Falling edge trigger detection

GPIO_MODE_EVT_RISING External Event Mode with Rising edge trigger detection

GPIO_MODE_EVT_FALLING External Event Mode with Falling edge trigger detection

GPIO_MODE_EVT_RISING_FALLING External Event Mode with Rising/Falling edge trigger detection

1
GPIO_InitStruct.Pull = GPIO_NOPULL;

Ici ce sont les résistances de tirages qui sont configurées, trois possibilités :

GPIO_NOPULL Pas de résistance de tirage.

GPIO_PULLUP Résistance de tirage vers le positif.

GPIO_PULLDOWN Résistance de tirages vers le 0V.

Pour des Leds très sensibles, il peut-être intéressant de configurer des « Pulldowns » en sorties. Je ne sais si c'est possible avec un Arduino 328p, mais ça l'est avec les µC ARM. Si vous avez remarqué que lorsque l'on touche une led éteinte sur un montage sous tension, elle s' allume légèrement lorsque l'on met le doigt sur une des boroches ?…

1
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;

L'élément « speed » est l' un paramètre équivalent au « slew rate » d' un AOP, c'est le temps de monté à la tension voulu. Selon les µCs, cela va de trois à quatre vitesses possibles.

Le bloc /*Configure GPIO pins : VCP_TX_Pin VCP_RX_Pin */ configure l'USART qui sert à charger le code dans le µC. Dans le tutoriel précédent, il ne figurait pas dans le main.c. Nous pouvons y voir la ligne GPIO_InitStruct.Alternate = GPIO_AF7_USART2; qui nous donne un exemple de configuration d'un périphérique.

Enfin le bloc /*Configure GPIO pins : PA3 PA4 */ qui configure les entrées. Encore une ligne en moins…

La fonction assert_failed()

Bien qu'inutilisée dans ce tutoriel, une petite description ne nous fera pas de mal. Cette fonction sert à récupérer les retours d' autres fonctions, permettant de gérer les erreurs. Nous nous y attarderons lors d'un prochain tutoriel, car son intérêt est certain.

Notre code!

Que les hostilités commence !! J' aurais pu me contenter d'un simple « Blink » pour ce tutoriel, mais faut rigoler un peu. Plus sérieusement, il est plus intéressant d' avoir une base avec laquelle on peut trouver d' autres formes de fonctionnements afin de pratiquer un peu.

Déclarations.

Nous avons vu que nous pouvions faire des « labels » dans le paragraphe « Définir des noms pour les broches. », et que ces définitions étaient « rangé » dans le fichier « mxconstants.h ». Ouvrez le, nous allons en avoir besoin.

Voici son contenu chez moi :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/* Private define ------------------------------------------------------------*/

#define MCO_Pin GPIO_PIN_0
#define MCO_GPIO_Port GPIOF
#define G_LED_Pin GPIO_PIN_1
#define G_LED_GPIO_Port GPIOA
#define VCP_TX_Pin GPIO_PIN_2
#define VCP_TX_GPIO_Port GPIOA
#define B2_Pin GPIO_PIN_3
#define B2_GPIO_Port GPIOA
#define B1_Pin GPIO_PIN_4
#define B1_GPIO_Port GPIOA
#define R_LED_Pin GPIO_PIN_5
#define R_LED_GPIO_Port GPIOA
#define B_LED_Pin GPIO_PIN_7
#define B_LED_GPIO_Port GPIOA
#define SWDIO_Pin GPIO_PIN_13
#define SWDIO_GPIO_Port GPIOA
#define SWCLK_Pin GPIO_PIN_14
#define SWCLK_GPIO_Port GPIOA
#define VCP_RX_Pin GPIO_PIN_15
#define VCP_RX_GPIO_Port GPIOA
/* USER CODE BEGIN Private defines */

Nous retrouvons nos définitions mais rallongés. Dans le main.c, nous allons avoir besoin d' une variable pour sélectionner quelle led nous voulons allumer ou éteindre. Je l' appel ColorSelect.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
int main(void)
{


  /* MCU Configuration----------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* Configure the system clock */
  SystemClock_Config();

  /* Initialize all configured peripherals */
  MX_GPIO_Init();

  
/* Variable de sélection de la led   
 * que l'on veut contrôler */
/*R=0;G=1;B=2;*/
int ColorSelect=0;      

La boucle while.

Voici le code sans l' utilisation des définitions de nos broches. A ce niveau, c'est lisible. Je sais que la pin 3 c'est le bouton 2, la pin 4le bouton 1, la pin 7, la led bleu….

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
  while (1)
  {
      if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_3) == GPIO_PIN_RESET){ColorSelect++;}

      if ((HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_4) == GPIO_PIN_RESET) && (ColorSelect == 0)) {
           HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_5);
    }
      HAL_Delay(1);
      if ((HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_4) == GPIO_PIN_RESET) && (ColorSelect == 1)) {
           HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_1);
        }
      if ((HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_4) == GPIO_PIN_RESET) && (ColorSelect == 2)) {
           HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_7);
        }

      if(ColorSelect>2){ColorSelect=0;} //contrôle de remise à zéro pour la sélection des leds
      HAL_Delay(180);                   //delais antirebonds
  }

Mais si on commence à triturer le code, ça va être rapidement illisible. Nous allons donc utiliser les définitions. Voici ce que ça donne :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
 while (1)
  {
      if(HAL_GPIO_ReadPin(GPIOA,B2_Pin) == GPIO_PIN_RESET){ColorSelect++;}

      if ((HAL_GPIO_ReadPin(GPIOA,B1_Pin) == GPIO_PIN_RESET) && (ColorSelect == 0)) {
           HAL_GPIO_TogglePin(GPIOA,R_LED_Pin);
    }
      HAL_Delay(1);
      if ((HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_4) == GPIO_PIN_RESET) && (ColorSelect == 1)) {
           HAL_GPIO_TogglePin(GPIOA,G_LED_Pin);
        }
      if ((HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_4) == GPIO_PIN_RESET) && (ColorSelect == 2)) {
           HAL_GPIO_TogglePin(GPIOA,B_LED_Pin);
        }

      if(ColorSelect>2){ColorSelect=0;} //contrôle de remise à zéro pour la sélection des leds
      HAL_Delay(180);                   //delais antirebonds
  }

C'est déjà mieux, cependant, pour l'usage des boutons, il aurait été préférable de savoir quel bouton fait quoi. Nous allons donc renommer dans les définitions les boutons de cette manière :

  • B1_Pin en Select

  • B2_Pin en State

Voici ce que vous devez obtenir :

1
2
3
4
#define State GPIO_PIN_3
#define State_Port GPIOA
#define Select GPIO_PIN_4
#define Select_Port GPIOA

Soyez attentif, pour chaque bouton il y a deux définitions : une pour la broche et une pour le port. Le nom du port doit être différent de celui de la broche. Par exemple pour le bouton State, le nouveau nom pour le PORT est State_Port et celui de la broche est State. Le but n'est pas de raccourcir le code avec deux trois lettres enlevées, mais de gagner en lisibilité ! Si vous avez l' intention de faire un projet plus gourmand en ressource externe, ce qui va compter n'est pas le temps que vous allez passer à taper le code, mais le temps que vous allez passer à le corriger. Si vous n'êtes pas très expérimenté, ce qui est mon cas, vous devez prendre de bonnes habitudes. Un code bien commenté et bien écrit est plus facile à corriger qu' un code dont les noms ne veulent rien dire.

Voici mes nouvelles définitions :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
/*Définition des pins pour les Leds*/
#define RED_LED GPIO_PIN_5
#define GREEN_LED GPIO_PIN_1
#define BLUE_LED GPIO_PIN_7
/*Comme toutes les leds sont sur le même Port,
 * je n'utilise qu'une seule définition pour toutes les leds*/
#define LED_Port GPIOA
/*Définitions des pins pour les boutons*/
#define State GPIO_PIN_3
#define Select GPIO_PIN_4
/*Comme tous les boutons sont sur le même Port,
 * je n'utilise qu'une seule définition pour tout les boutons*/
#define B_Port GPIOA

Il faut aussi modifier les définitions dans la fonction MX_GPIO_Init(void)

Il faut ensuite enregistrer les fichiers et dans Index, cliquer sur Freshen All Files Et voici mon code dans la boucle while:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
  while (1)
  {
      if(HAL_GPIO_ReadPin(B_Port,Select) == GPIO_PIN_RESET){ColorSelect++;}

      if ((HAL_GPIO_ReadPin(B_Port,State) == GPIO_PIN_RESET) && (ColorSelect == 0)) {
           HAL_GPIO_TogglePin(LED_Port,RED_LED);
    }
      HAL_Delay(1);
      if ((HAL_GPIO_ReadPin(B_Port,State) == GPIO_PIN_RESET) && (ColorSelect == 1)) {
           HAL_GPIO_TogglePin(LED_Port,GREEN_LED);
        }
      if ((HAL_GPIO_ReadPin(B_Port,State) == GPIO_PIN_RESET) && (ColorSelect == 2)) {
           HAL_GPIO_TogglePin(LED_Port,BLUE_LED);
        }

      if(ColorSelect>2){ColorSelect=0;} //contrôle de remise à zéro pour la sélection des leds
      HAL_Delay(180);                   //delais antirebonds
  }

Ne recopiez pas mon code tel qu'il est, pendant les tests des boutons poussoirs, j' ai changé ma configuration des résistances en entrées, je les ai mise en « PULLUP », il faut donc remplacer GPIO_PIN_RESET en GPIO_PIN_SET.

Bien maintenant, mon code est bien plus lisible. Un dernier point, le « debouncing » ou anti rebonds. Malgré le « trigger » configuré automatiquement lors de la déclaration des entrées, ainsi que les condensateurs de découplage des boutons, il m' a fallu rajouter un délais de 180ms dans le programme afin d' arriver à un fonctionnement à peu près correct. Si vous avez des problèmes de rebonds, n' hésitez pas à essayer des valeurs de condensateurs différentes. Et aussi à jouer sur la valeur du délai. Cette méthode n'est pas des plus commode, si vous comptez partir de ce tutoriel pour faire des animations et que vous voulez les changer en appuyant avec les boutons, vous allez vite vous rendre compte du problème. La fonction HAL_Delay est bloquante. Vous pouvez toutefois contourner ce problème en ajoutant les instructions de lectures de boutons un peu partout dans vos futures fonctions. C'est ce qui va nous emmener vers un nouveau tutoriel : Les interruptions et les Timers.

En espérant, que mes tutoriels vous aide à y voir plus clair. Toutefois, ce sont mes premiers tutos, je suis contient qu'ils ne sont pas forcément bien écrit. N'hésitez pas à me faire part d'erreurs, ou de faire des suggestions.

Weetoz.

Derniére modification le par weetoz