Articles récents
STM32 : Les entrées-sorties
Après avoir vu quelques articles de présentation du STM32 et de son environnement de développement, il est temps de rentrer dans le vif du sujet.
Nous allons commencer petit bras, avec un programme de commande d'entrées/sorties. Il faut bien débuter par quelque chose. L'objectif de notre programme sera simplement de faire clignoter une led, et nous verrons qu'il y a déjà beaucoup de choses à prendre en compte.
Le schéma ci-dessous décrit le principe GPIO. On notera le montage push-pull en sortie.
Préparation du programme
Donc ici, l'idée est de faire clignoter une led et de la commander par un des deux boutons poussoirs de la carte. Pour cela, on va prendre BP1 de la carte Nucleo (qui est rattaché à un GPIO, on verra cela plus tard).Donc, la première étape consiste à ouvrir le STM32CubeMx en sélectionnant la carte Nucléo F-401RE. A noter, la très grande variété dans le choix des cartes de développement, c'est vraiment impressionnant.
Sur la représentation graphique du STM32, on remarque que la pin PA5 est marqué LD2 [Green led], ce qui semble vouloir indiquer que cette pin est connectée à la led LED2 de la carte par construction. C'est parfait pour notre expérience.
L'onglet Clock configuration est configuré avec les paramètres par défaut de la carte Nucléo. Dans l'onglet Project, il faut préciser le nom et l'emplacement du projet, ainsi que la toolchain en MDK-ARM.
Ensuite, il suffit de cliquer sur le bouton Generate code en haut à droite de l'interface. Un menu apparaît, il faut choisir l'option Open project. Keil UVision s'ouvre sur notre programme généré.
La génération du code par le STM32CubeMX produit un fichier main.c qui est le programme principal, on y trouve des fonctions génériques comme :
Le code utilisateur doit être impérativement intégré entre les différentes balises BEGIN et END. Tout ce qui sera ajouté au mauvais endroit (c'est à dire en dehors de ces balises) sera écrasé lors de la compilation. |
La fonction MX_GPIO_Init() initialise les GPIO du STM32, ici nous avons besoin de la LED2 et du bouton B1 pour stopper le clignotement de la LED.
static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOH_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, GPIO_PIN_RESET);
/*Configure GPIO pin : B1_Pin */
GPIO_InitStruct.Pin = B1_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(B1_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pin : LD2_Pin */
GPIO_InitStruct.Pin = LD2_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(LD2_GPIO_Port, &GPIO_InitStruct);
}
La première étape consiste à activer les horloges sur les ports du STM32.
Ensuite, on configure la LED sur PA5 Ã la valeur 0 par HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, GPIO_PIN_RESET) :
Enfin, on configure les GPIO en initialisant les données dans la structure. A noter que les champs :
Enfin, la fonction HAL_GPIO_Init() configure la broche avec les données initialisées dans la structure.
Le programme
La documentation du HAL pour les microcontroleurs STM32F4XX est ici. Vous trouverez toutes les fonctions du HAL utiles pour notre programme, et bien plus même! . Globalement, on peut presque considérer que STM produit un framework pour chacun de ses microcontrôleurs. C'est quand même impressionnant cette documentation, avec presque 2000 pages, c'est là que l'on voit que le STM32 est un petit bijou de technologie.int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_USART2_UART_Init();
/* USER CODE BEGIN 2 */
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
if (HAL_GPIO_ReadPin(B1_GPIO_Port,B1_Pin)==0)
HAL_GPIO_WritePin(LD2_GPIO_Port,LD2_Pin,GPIO_PIN_RESET);
else
{
HAL_GPIO_TogglePin(LD2_GPIO_Port,LD2_Pin);
HAL_Delay(500);
HAL_GPIO_TogglePin(LD2_GPIO_Port,LD2_Pin);
HAL_Delay(500);
}
}
/* USER CODE END 3 */
}
Notre code est placé entre les balises USER CODE 3. En résumé, on teste la valeur du bouton, s'il est à 0, on éteint la led, sinon on fait changer l'état de la led avec la fonction HAL_GPIO_TogglePin qui spécifie les broches à basculer. HAL_Delay(500) réalise une temporisation de 500ms (0.5s). Et si on appuie sur le BP1, cela arrête le clignotement de LED2.
Attention, une fois que l'on a chargé le programme, il est nécessaire d’appuyer sur le bouton de reset pour charger et exécuter le code.
Conclusion
Voilà , nous avons réalisé notre premier programme. J'ai pris soin de bien décrire toute la démarche avec l'environnement de développement. A vous de jouer. Je conseille vivement l'acquisition de la carte Nucléo qui est vraiment peu coûteuse pour se faire la main.
© 2024 www.doritique.fr par Robert DORIGNY