|
|
(11 révisions intermédiaires par 3 utilisateurs non affichées) |
Ligne 46 : |
Ligne 46 : |
| [[ 1 - Premier programme “blinky”]] | | [[ 1 - Premier programme “blinky”]] |
| <br> | | <br> |
− | [[ 2 - Commander une LED avec un variateur PWM”]] | + | [[ 2 - Commander l'intensité lumineuse d'une LED (PWM)”]] |
| <br> | | <br> |
| [[ 3 - Commander une LED RGB par PWM”]] | | [[ 3 - Commander une LED RGB par PWM”]] |
Ligne 52 : |
Ligne 52 : |
| [[ 4 - Contrôle d’un moteur "servo à rotation continue" avec un variateur PWM”]] | | [[ 4 - Contrôle d’un moteur "servo à rotation continue" avec un variateur PWM”]] |
| <br> | | <br> |
− | | + | [[ 5 - Utiliser un "bouton poussoir" avec un "GPIO in"]] |
− | | + | |
− | | + | |
− | Commander une led Rgb par PWM
| + | |
− | | + | |
− | =='''Commander une LED avec un variateur PWM'''==
| + | |
− | | + | |
− | Si on connecte une LED à des broches digitales comme vu dans le programme "blinky", on a seulement deux possibilités : "on" avec la pleine luminosité et "off" éteint.
| + | |
| <br> | | <br> |
− | En utilisant le PWM (en anglais "pulse wide modulation"), on peux faire varier la luminosité de la LED.
| + | [[ 6 - Contrôle d’un moteur "pas à pas" avec quatres "GPIO out" ]] |
− | | + | |
− | ===Explication du PWM===
| + | |
− | Si on allume la LED, il y a une tension de 3.3 volt sur la broche, pour éteindre, on applique 0 volt:
| + | |
| <br> | | <br> |
| + | [[ 7 - Afficher des infos avec le "Virtual COM port" ]] |
| <br> | | <br> |
− | [[Fichier:PWM_OnOff.png|sans_cadre|600px]] | + | [[ 8 - I2C (Inter Integrated Circuit) ]] |
| <br> | | <br> |
− | <br>
| |
− | Si on change rapidement (par exemple 100 fois par seconde) entre "on" et "off", l’œil humain ne distingue plus ce changement et on a l’impression, que la LED brille avec une luminosité moindre:
| |
− | <br>
| |
− | <br>
| |
− | [[Fichier:PWM_OnOff100.png|sans_cadre|600px]]
| |
− | <br>
| |
− | <br>
| |
− | A partir d’une certaine fréquence (25 fois par seconde), celle ci n’est plus importante car elle n'est plus perceptible à l’œil.
| |
− | <br>
| |
− | <br>
| |
− | [[Fichier:PWM_OnOff25.png|sans_cadre|600px]]
| |
− | <br>
| |
− | <br>
| |
− | Une periode "T" est défini par le temps entre deux allumage "on" (front montant du signal).
| |
− | <br>
| |
− | Maintenant, on peut diminuer ou augmenter le temps "t1" de l’état "on" par rapport à l’état "off". Par exemple dans le dessin, "t1" est à un quart de "T".
| |
− | <br>
| |
− | <br>
| |
− | [[Fichier:PWM_Tt.png|sans_cadre|600px]]
| |
− | <br>
| |
− | <br>
| |
− | Ce rapport t1/T est appelé le rapport cyclique ("duty cycle").
| |
− | * S’il est à 0 ( t1 = 0 ), la LED est "off" en continue.
| |
− | * S’il est à 1 ( t1 = T ), la LED est "on" en continue.
| |
− | * Si on modifie le rapport de "t1 beaucoup plus petit que T" (la LED brille très peu) à "t1 presque égale à T" (la LED brille beaucoup), on peux varier la luminosité de la LED.
| |
− |
| |
− | ===Support du PWM par les STM32===
| |
− | Sur STM32, le PWM est supporté par l’utilisation du timer et des drivers HAL (source code "Hardware Abstraction Layer" distribué par ST).
| |
− | <br>
| |
− | Il faut savoir que les STM32 contiennent plusieurs types de timer avec des fonctionnalités différentes. Une description des timers se trouve dans les fichiers (en anglais) de STMicroelectronics:
| |
− | * [http://www.st.com/content/ccc/resource/technical/document/application_note/54/0f/67/eb/47/34/45/40/DM00042534.pdf/files/DM00042534.pdf/jcr:content/translations/en.DM00042534.pdf Application Note 4013] et
| |
− | *[http://www.st.com/resource/en/application_note/dm00236305.pdf Application Note 4776].
| |
− | <br>
| |
− | <br>
| |
− | On va utiliser l’outil STM32CubeMx pour générer le code source de base.
| |
− | * Première étape: Créer un nouveau projet en sélectionnant la carte sur laquelle on va travailler.
| |
− | * Dans l’onglet "Pinout" de la fenêtre principale, on sélectionne un timer (par exemple "TIM2"), qui propose plusieurs "Channel" avec la fonction "PWM Generation".
| |
− | <br>
| |
− | <br>
| |
− | [[Fichier:PWM_Pinout.png]]
| |
− | <br>
| |
− | <br>
| |
− | On peut voir sur l’image de la puce que la broche PA5 est utiliser pour le canal 1 du timer 2: "TIM2_CH1".
| |
− | <br>
| |
− | Pour calculer des valeurs "t1" et "T", il faut configurer le timer dans l’onglet "Configuration" en cliquant sur le bouton "TIM2" dans la rubrique "Control".
| |
− | <br>
| |
− | <br>
| |
− | [[Fichier:PWM_Config.png]]
| |
− | <br>
| |
− | <br>
| |
− | Dans l’onglet « Parameter Settings » de la boite de dialogue, il faut configurer le timer.
| |
− | <br>
| |
− | Pour cela, il faut savoir que le timer est sequencé par l’horloge du CPU. Dans le cas de la carte sélectionné, cette fréquence est de 80 MHz.
| |
− | <br>
| |
− | Si on configure le "Prescaler" (voir image) du timer à 80, le timer va déclencher l’incrémentation du compteur avec une fréquence de 1 MHz (80 MHz / 80). Il faut configurer une deuxième valeur "Counter Periode" à 100.
| |
− | <br>
| |
− | Ainsi, chaque micro seconde, le timer va incrémenter (en commençant à 0 jusqu’à 100). Ce temps (100 micro secondes) corresponds au "T".
| |
− | Maintenant on peut générer le code source.
| |
− | <br>
| |
− | <br>
| |
− | Pour le contrôle du timer, il faut trois fonctions:
| |
− | * Démarrer le timer: HAL_TIM_PWM_Start( &htim2, TIM_CHANNEL_1 );
| |
− | * Arrêter le timer: HAL_TIM_PWM_Stop( &htim2, TIM_CHANNEL_1 );
| |
− | * Modifier la valeur de "t1": __HAL_TIM_SET_COMPARE( &htim2, TIM_CHANNEL_1, Value );
| |
− |
| |
− | ===Allumage d’une LED===
| |
− | La valeur de la variable "Value" peut être réglée entre 0 (LED éteint) et 100 (LED allumé avec 100 % puissance). Avec de simples boucles, on peut réaliser un "blinkly en continue":
| |
− | <br>
| |
− | HAL_TIM_PWM_Start( &htim2, TIM_CHANNEL_1 );
| |
− | /* Infinite loop */
| |
− | while (1)
| |
− | {
| |
− | for ( int i = 0; i < 100; i ++ )
| |
− | {
| |
− | __HAL_TIM_SET_COMPARE( &htim2, TIM_CHANNEL_1, i );
| |
− | HAL_Delay( 10 );
| |
− | }
| |
− | for ( int i = 100; i > 0; i -- )
| |
− | {
| |
− | __HAL_TIM_SET_COMPARE( &htim2, TIM_CHANNEL_1, i );
| |
− | HAL_Delay( 10 );
| |
− | }
| |
− | }
| |
− |
| |
− | =='''Commander une led Rgb par PWM'''==
| |
− | <br>
| |
− | <br>
| |
− | Nous allons poussez un peu plus loin l'exploration du PWM en pilotant l’éclairage d'une led RGB.
| |
− |
| |
− | Réaliser le montage suivant à l'aide de :
| |
− |
| |
− | - 2 résistances de 100 Ω pour les broches Vert et Bleu
| |
− |
| |
− | - 1 résistance de 200 Ω pour la broche rouge
| |
− |
| |
− | Voici l'emplacement des différentes broches de la led RGB
| |
− | <br>
| |
− | [[Fichier:RGB-LED.png|center|]]
| |
− | <br>
| |
− | Et le schéma de câblage
| |
− | <br>
| |
− | [[Fichier:STM32-RGB1-LED4.PNG|center|]]
| |
− | <br>
| |
− | Nous devons comme précédemment pré-configurer les broches du STM32 sous CubeMx comme ceci
| |
− | <br>
| |
− | [[Fichier:STM32-RGB-LED1.PNG|center|]]
| |
− | <br>
| |
− | Dans l'onglet "Configuration" , régler les Timer 2 et 3 avec le "Prescaler" à 80 et le "Counter Periode" à 100
| |
− | <br>
| |
− | [[Fichier:STM32-RGB-LED5.PNG|center|]]
| |
− | [[Fichier:STM32-RGB-LED6.PNG|center|]]
| |
− | <br>
| |
− |
| |
− | Et le code à incorporer dans votre fichier main.c
| |
− |
| |
− | <syntaxhighlight lang="cpp" enclose="div">
| |
− |
| |
− | /* Initialize all configured peripherals */
| |
− | MX_GPIO_Init();
| |
− | MX_TIM3_Init();
| |
− | MX_TIM2_Init();
| |
− |
| |
− | /* USER CODE BEGIN 2 */
| |
− | HAL_TIM_PWM_Start( &htim3, TIM_CHANNEL_1 ); // Green
| |
− | HAL_TIM_PWM_Start( &htim3, TIM_CHANNEL_2 ); // Red
| |
− | HAL_TIM_PWM_Start( &htim2, TIM_CHANNEL_1 ); // Blue
| |
− | /* USER CODE END 2 */
| |
− |
| |
− | /* Infinite loop */
| |
− | /* USER CODE BEGIN WHILE */
| |
− | while (1)
| |
− | {
| |
− | for ( int i = 0; i < 100; i ++ )
| |
− | {
| |
− | /* USER CODE END WHILE */
| |
− | __HAL_TIM_SET_COMPARE( &htim3, TIM_CHANNEL_1, i); // Green
| |
− | __HAL_TIM_SET_COMPARE( &htim3, TIM_CHANNEL_2, i); // Red
| |
− | __HAL_TIM_SET_COMPARE( &htim2, TIM_CHANNEL_1, i); // Blue
| |
− | HAL_Delay( 20 );
| |
− | }
| |
− | for ( int i = 100; i > 0; i -- )
| |
− | {
| |
− | /* USER CODE END WHILE */
| |
− | __HAL_TIM_SET_COMPARE( &htim3, TIM_CHANNEL_1, i); // Green
| |
− | __HAL_TIM_SET_COMPARE( &htim3, TIM_CHANNEL_2, i); // Red
| |
− | __HAL_TIM_SET_COMPARE( &htim2, TIM_CHANNEL_1, i); // Blue
| |
− | HAL_Delay( 20 );
| |
− | }
| |
− | /* USER CODE BEGIN 3 */
| |
− |
| |
− | }
| |
− | /* USER CODE END 3 */
| |
− |
| |
− | }
| |
− |
| |
− | </syntaxhighlight>
| |
− |
| |
− | =='''Contrôle d’un moteur "servo à rotation continue" avec un variateur PWM'''==
| |
− |
| |
− | Le PWM peut être utilisé pour le contrôle d’un moteur "servo à rotation continue", comme ceux qui sont intégrés dans le robot du lab.
| |
− | <br>
| |
− | Dans ce tutoriel, on va utiliser le moteur de adafruit (https://www.adafruit.com/product/154). Sur la page internet, on trouve une information importante dans la section des détails techniques: "Required Pulse: 500us-2500us".
| |
− | <br>
| |
− | ===Configuration du timer du STM32===
| |
− | L'utilisation/configuration du timer se fait exactement la même façon comme pour commander une LED, mais il nous faut alors générer des pulses d’une longueur "t1" de 500 à 2500 micro secondes.
| |
− | <br>
| |
− | Ainsi dans la boite de dialogue de configuration du timer, il faut maintenant configurer la deuxième valeur "Counter Periode" à 2500. Ainsi la periode "T" est 2500 micro secondes.
| |
− | <br>
| |
− | Le fonctionnement du moteur est la suivante:
| |
− | * Si on envoie une impulsion "plus petite que la moitié" égale à (2500 + 500 ) / 2 = 1500 micro secondes, le moteur tourne "à gauche".
| |
− | * Si elle est "plus grande que la moitié", le moteur tourne "à droite".
| |
− | <br>
| |
− | <br>
| |
− | Avec un peu de marge sur les valeurs, on peut décrire le scénario suivant:
| |
− |
| |
− | HAL_TIM_PWM_Start( &htim2, TIM_CHANNEL_1 );
| |
− | /* Infinite loop */
| |
− | while (1)
| |
− | {
| |
− | /* tourne à gauche... */
| |
− | __HAL_TIM_SET_COMPARE( &htim2, TIM_CHANNEL_1, 1000 );
| |
− | /* … pendant 5 secondes */
| |
− | HAL_Delay( 5000 );
| |
− | /* tourne à droite... */
| |
− | __HAL_TIM_SET_COMPARE( &htim2, TIM_CHANNEL_1, 2000 );
| |
− | /* … pendant 5 secondes */
| |
− | HAL_Delay( 5000 );
| |
− | }
| |