STM32CubeMX est l’outil graphique de configuration des microcontrôleurs STM32 : on y affecte les broches, on y règle l’arbre d’horloge, on y paramètre les périphériques, puis CubeMX génère le code d’initialisation correspondant. C’est le cœur de la porte native du STM32, et l’apport le plus distinctif de la famille : on ne programme pas d’abord, on configure le microcontrôleur : le code vient ensuite. CubeMX s’utilise seul ou intégré dans STM32CubeIDE (la vue .ioc rencontrée à la prise en main). L’API que ce code emploie est détaillée dans la HAL.
À quoi ça sert ?
Un STM32 a des dizaines de broches, plusieurs horloges, et des périphériques aux nombreux réglages. Écrire à la main toute l’initialisation (quels bits dans quels registres, dans quel ordre) est long et source d’erreurs. CubeMX rend cette configuration visuelle et vérifiée :
- Voir et résoudre les conflits. Le brochage graphique montre quelles fonctions sont possibles sur chaque broche et signale les conflits (une broche déjà prise par un autre périphérique).
- Maîtriser l’horloge. L’arbre d’horloge, panneau emblématique du STM32, permet de régler la fréquence du cœur et de chaque bus, en calculant les diviseurs et en alertant sur les valeurs invalides.
- Générer une base saine. Le code d’initialisation produit est cohérent avec la configuration, et préserve votre propre code à chaque régénération.
CubeMX ne remplace pas la compréhension du matériel : il l’outille. Lire la datasheet reste utile pour savoir quoi configurer (voir lire une datasheet).
Le fichier .ioc
Toute la configuration vit dans un fichier .ioc (un par projet). C’est un fichier texte : il se versionne dans Git au même titre que le code, et deux états de configuration se comparent. « Générer le code » lit le .ioc et écrit l’initialisation. Modifier la configuration et régénérer met le code à jour sans toucher à ce que vous avez écrit dans les zones réservées.
Configurer le brochage
Dans la vue Pinout & Configuration, chaque broche du boîtier est cliquable. Un clic propose ses fonctions possibles : GPIO_Output, GPIO_Input, USART2_TX, TIM3_CH1, I2C1_SCL… On affecte les fonctions dont le projet a besoin. CubeMX colore les broches utilisées et refuse une affectation en conflit.
Sur un projet créé depuis une carte Nucleo, le brochage est déjà partiellement rempli (LD2, bouton, port série du ST-LINK). On part de là et on ajoute ce qu’il faut.
Prendre capture d’écran de la vue Pinout & Configuration de CubeMX, avec quelques broches affectées en surbrillance : LD2 en GPIO_Output, PA2 et PA3 en USART2.
Configurer l’arbre d’horloge
L’onglet Clock Configuration affiche l’arbre d’horloge : la source (oscillateur interne HSI, ou quartz externe HSE), la PLL qui multiplie la fréquence, l’horloge système SYSCLK, et les prédiviseurs qui alimentent les bus AHB et APB et, à travers eux, les périphériques.
On saisit la fréquence cible (souvent le maximum de la puce) dans la case SYSCLK. CubeMX résout les multiplicateurs et diviseurs ou signale en rouge une combinaison impossible. C’est un panneau à comprendre : une horloge mal réglée donne des vitesses fausses partout en aval : un UART qui n’a pas le bon débit, un timer qui ne mesure pas la bonne durée.
Prendre capture d’écran de l’onglet Clock Configuration de CubeMX, montrant l’arbre HSE vers PLL, SYSCLK et les prédiviseurs AHB et APB, avec la fréquence du cœur affichée.
Configurer les périphériques
Chaque périphérique activé ouvre un panneau de paramètres : débit et format pour un UART, prédiviseur et période pour un timer, résolution et canaux pour un ADC, vitesse pour un bus SPI… Deux onglets transverses complètent le réglage :
- NVIC — pour activer l’interruption d’un périphérique. Sans cocher la ligne NVIC correspondante, le code en mode interruption ne sera jamais appelé (piège classique).
- DMA — pour configurer un transfert par accès direct à la mémoire, qui décharge le cœur.
Prendre capture d’écran du panneau de configuration d’un USART dans CubeMX, réglé à 115200 bauds et 8 bits de données, avec l’onglet NVIC Settings visible.
HAL ou LL, puis générer
Avant de générer, le Project Manager → Advanced Settings → Driver Selector offre un choix important par périphérique : générer l’init en HAL (l’API portable, par défaut) ou en LL (la couche bas niveau, plus proche du registre et plus légère). On peut mélanger d’un périphérique à l’autre : HAL pour la plupart, LL pour un périphérique critique en performance. (L’onglet voisin Code Generator porte d’autres réglages — un fichier par périphérique, conservation du code utilisateur — pas le choix du pilote.)
« Generate Code » écrit alors main.c, un fichier d’init par périphérique, et les fonctions MX_<PERIPH>_Init(). Tout est jalonné de balises /* USER CODE BEGIN/END */ : votre code n’y survit que dans ces balises.
Exemple — Configurer LED + port série, puis générer
Sur une Nucleo, configurons de quoi clignoter et écrire sur le port série, en partant d’un projet de carte :
- Brochage —
LD2est déjà enGPIO_Output. Vérifier queUSART2est activé surPA2/PA3(le port série du ST-LINK sur Nucleo-64). - Horloge — laisser la configuration par défaut de la carte (déjà proche du maximum).
- USART2 — Baud Rate à
115200, format8N1. - Générer le code.
Dans main.c, CubeMX a produit MX_GPIO_Init() et MX_USART2_UART_Init(), et déclaré un handle huart2. Il ne reste qu’à compléter la boucle, dans la zone réservée :
/* USER CODE BEGIN 3 */
HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin); // inverse l'état de la LED
HAL_UART_Transmit(&huart2, (uint8_t *)"tick\r\n", 6, 100); // 6 = octets à envoyer, 100 = délai d'attente en ms
HAL_Delay(1000); // attend une seconde
/* USER CODE END 3 */La LED bat la seconde, et le moniteur série (115200) affiche tick chaque seconde. Le handle huart2 est l’objet généré par CubeMX que les fonctions HAL manipulent (détaillé dans la HAL). On a configuré le microcontrôleur, puis seulement écrit la logique : c’est tout l’esprit de la porte native.
Au moniteur réglé sur 115200 :
tick
tick
tick
tick
Si les lignes défilent trop vite ou trop lentement, c’est l’arbre d’horloge qu’il faut rouvrir, pas le HAL_Delay.
Pièges
Code écrit hors des zones USER CODE. Le piège récurrent du STM32 natif : tout code hors des balises /* USER CODE BEGIN/END */ disparaît à la prochaine génération. Toujours écrire entre les balises, et regénérer sans crainte une fois la règle acquise.
Arbre d’horloge mal réglé. Une fréquence système fausse propage des vitesses fausses partout : UART au mauvais débit, timer à la mauvaise durée, attentes erronées. Vérifier la source (HSI interne vs HSE externe) et lire les fréquences calculées par CubeMX.
Interruption activée dans le code mais pas dans le NVIC. Utiliser un périphérique en mode interruption (HAL_..._IT) sans cocher sa ligne dans l’onglet NVIC : la fonction de rappel n’est jamais appelée, et rien ne le signale à la compilation.
Conflit de broche ignoré. Affecter à une broche une fonction alors qu’une autre l’occupe : CubeMX le signale, ne pas passer outre.
Mauvaise référence de puce. Créer le projet pour une variante différente de la puce réelle : les broches et périphériques ne correspondent pas. Partir du Board Selector pour une carte connue évite l’erreur.
Oublier de régénérer. Modifier la configuration dans le .ioc sans relancer « Generate Code » : le code ne reflète pas le changement.
Exercices
Exercice 1 — Le port série du ST-LINK
Dans CubeMX, quel périphérique correspond au port série virtuel d’une Nucleo-64, et sur quelles broches ? Que se passe-t-il si vous réglez son débit à 9600 dans CubeMX mais ouvrez le moniteur à 115200 ?
Corrigé
Sur la plupart des Nucleo-64, c’est USART2, câblé sur
PA2(TX) etPA3(RX), relié au ST-LINK qui l’expose comme port série virtuel sur l’USB. Si le débit configuré (9600) ne correspond pas à celui du moniteur (115200), les caractères s’affichent en charabia : les deux extrémités doivent partager exactement le même débit. C’est l’exemple direct d’un réglage de périphérique dont dépend le bon fonctionnement.
Exercice 2 — Ajouter un timer
Vous voulez faire clignoter la LED sans
HAL_Delaybloquant, à l’aide d’un timer matériel. Dans CubeMX, quel réglage de TIM vise une période de 1 s, et quel onglet faut-il penser à activer si vous comptez utiliser son interruption ?
Corrigé
On active un TIMx en Internal Clock, puis on règle son prédiviseur (Prescaler) et sa période (Counter Period) pour obtenir 1 s : par exemple, avec une horloge de timer à 84 MHz, un prescaler de
8400-1ramène le compteur à 10 kHz, et une période de10000-1donne un débordement chaque seconde. Pour réagir à ce débordement, il faut cocher la ligne du timer dans l’onglet NVIC (sinon le rappelHAL_TIM_PeriodElapsedCallbackne sera jamais appelé). Le détail des valeurs et des timers se règle ensuite. Ici, l’essentiel est le couple prescaler × période et l’activation NVIC.
Raccrochage projet
- Étape 4 de la phase de preuve de concept. CubeMX est l’outil qui transforme un choix de microcontrôleur (fait en concept) en base logicielle prête à coder. Configurer proprement l’horloge et les périphériques en début de PoC évite des bugs de timing difficiles à diagnostiquer plus tard.
- Traçabilité. Le fichier
.iocversionné documente la configuration matérielle du projet : un coéquipier retrouve d’un coup d’œil quelles broches font quoi, ce qui nourrit le dossier technique.
Comprendre que CubeMX configure et que la HAL est l’API que le code généré utilise sépare clairement les deux gestes : on règle le microcontrôleur d’un côté, on écrit la logique de l’autre.
Aller plus loin
- Programmer avec la HAL — l’API qu’emploie le code généré par CubeMX.
- Descendre au registre — quand la HAL ne suffit pas, ou pour comprendre ce que CubeMX configure réellement.
- Page STM32CubeMX sur st.com — documentation, arbres d’horloge, exemples.
Voir aussi
- STM32 — hub des tutoriels STM32
- Prise en main du STM32 — la vue
.iocrencontrée pour la première fois - Programmer avec la HAL — l’API du code généré, ses trois modes
- Descendre au registre — la couche sous la HAL
- Timers · ADC · Bus de communication — périphériques configurés dans CubeMX (transverses)