L’objectif de cet exercice est de contrôler la mise en route d’un timer à partir d’un bouton poussoir de la carte ( switch center ).
Dans ce mode réglage, l’appui sur le bouton gauche incrémente la durée de fin de comptage ( par secondes ), l’appui sur la bouton droit la décrémente.
Un appui bref sur le bouton central permet de sortir de ce mode réglage.
PROJET SOURCE
WORKSPACE_F411_HAL_STM32CUBE.zip
Q1.1. Modifier le programme ( Fichiers stm32f4xx_hal_msp.c, leds.c, et éventuellement stm32f4xx_hal_gpio.c ) afin de permettre l’alumage et l’extinction des LEDs RGB de la carte Mbed.
Q2.1. Modifier le programme afin de déclencher une interruption Externe en appuyant et en relachant le bouton ‘center’ ( mode GPIO_MODE_IT_RISING_FALLING ). La fonction de callback associée à cette interruption doit alors mettre à 1 la variable globale pushButton quand on appuie sur le bouton, et à 0 quand on relache le bouton.
Q2.2 Modifier le programme afin de configurer les boutons gauche et droite en entrées logiques ( input ), et compléter les fonctions sw_left_raw() et sw_right_raw() dans le fichier sw.c ( ces fonctions doivent retourner ‘1’ sur le bit de poids faible quand on appuie sur le bouton, ‘0’ sinon ).
REMARQUE : Les fonctions sw_right_debounce() et sw_left_debounce() sont déjà complétées et permettent de gérer les problèmes liés aux rebonds.
Q3.1. Configurer le Timer 2 afin de déclencher une interruption toutes les 3s ; le compteur principal doit s’incrémenter de 1 toutes les 100 µs ( la période de remise à zéro du précompteur est 100µs ). Les fonctions suivantes doivent être utilisées :
HAL_TIM_Base_Init() : Configuration des registres PSC et ARR HAL_TIM_Base_Reset() : désactivation du comptage, remise à zéro des compteurs HAL_TIM_Base_Start_IT() : autorisation de comptage, activation de l’interruption update event.
REMARQUE : Il sera nécessaire de compléter le fichier stm32f4xx_hal_msp.c pour autoriser l’interruption du timer 2 au niveau du NVIC.
Q3.2. Compléter la fonction de callback associée à cette interruption afin de faire clignoter la led Rouge.
Q3.3. Compléter la fonction HAL_TIM_Base_Pause() permettant de suspendre le comptage ( sans remise à zéro )
Q4.1. Configurer les broches pour utiliser UART2, et initialiser ce périphérique en appelant la fonction HAL_UART_Init()
Q4.2. Compléter la fonction HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size) permettant d’envoyer Size caractères situés à l’adresse pData avec le périphérique huart
Q4.3. Compléter les fonctions uart_putc() et uart_puts() permettant d’envoyer respectivement un caractère et une chaine de caractères se terminant par le caractère nul ( code ascii 0x00 )
Une fois ces fonctions correctement complétées, la fonction uart_printf doit être utilisable. Q4.4. Vérifier le bon fonctionnement de la fonction uart_printf() en affichant un message dans le terminal série ( avec gtkterm ou minicom : minicom -D /dev/ttyACM0 -b 115200 )
Le programme ci dessous permet d’incrémenter ou de décrémenter la variable duree_totale en appuyant respectivement sur le bouton droite et gauche.
Q5.1. Modifier ce programme afin que la variable duree_totale soit comprise entre 0 et 10.
while(1)
{
red_led(1) ; green_led(0) ; blue_led(0);
if(sw_right_debounce() == 1)
{
duree_totale = ( duree_totale + 1 );
}
if(sw_left_debounce() == 1)
{
duree_totale = ( duree_totale - 1 );
}
uart_printf(&huart2, "Reglage fin de comptage %d\n\r", duree_totale );
HAL_Delay(10);
}
La fonction HAL_Delay(n) permet d’attendre n millisecondes.
La durée de l’appui sur le bouton correspondra a un nombre d’itérations ( tours de boucles ) de la boucle while(1).
Ainsi, si n=10, une durée de 2s correspondra à 200 itérations ; on notera nb_bt ce nombre d’itérations.
Q6.1. Modifier le programme de la boucle while(1) du programme principal afin de respecter le fonctionnement décrit dans le diagramme d’états ci dessous :
// TEST DU TEMPS D'APPUI
while(1)
{
switch(state)
{
case INIT_STATE :
nb_bt = 0;
if(pushButton == 1)
{
state = EVAL_DUREE_PUSH_STATE;
}
break;
case EVAL_DUREE_PUSH_STATE :
// A COMPLETER
if( (pushButton == 0) && (nb_bt < 200) && ( run == 0) )
{
state = RUN_STATE;
}
// A COMPLETER
break;
// A COMPLETER
}
HAL_Delay(10);
}
Codage d’une machine d’états avec des sorties de Mealy
Afin d’exécuter une seule fois une fonction ( par exemple pour gérer le timer ),
on peut ajouter un état intermédiaire ou alors appeler cette fonction lors du passage d’un état à l’autre.
Cette deuxième option fait gagner un coup d’horloge.
On appelle alors cela des sorties de Mealy
while(1)
{
switch(state)
{
case ETAT_1 : if (condition sur les entrées) {détermination de l’état futur ; sorties de mealy}
sorties de moore ;
break ;
case ETAT_2 : ...
}
HAL_Delay(10) ;
}
Q7.1. Modifier le programme de la boucle while(1) du programme principal afin de respecter le fonctionnement décrit dans le diagramme d’états ci dessous :