Comment utiliser le port série virtuel du Nucléo

Lorsque le Nucléo est relié au PC à l’aide du port USB, il créé un port série virtuel qui permet d’échanger des données (ou messages). Pour voir le nom du port série dans Windows, il suffit d’aller dans Périphériques et imprimantes. Vous verrez alors un périphérique du nom de STM32 STlink.

Dans les propriétés de ce périphérique, vous verrez l’ensemble des fonctions de ce dernier, dont Virtual COM Port. Sur mon ordinateur, il apparaît sur le COM6.

Comme pour le Arduino, c’est le UART qui est relié à D0 et D1 qui est utilisé. Dans le cas du Nucléo F446RE, c’est le UART2 avec les pins A2 et A3 qu’il faut utiliser.

Pour utiliser des périphériques du microcontrôleur, il faut d’abord activer l’horloge. Nous allons donc débuter par activer l’horloge sur UART2 et le port A.

 /* Active le clock sur UART2 et GPIOA */
 RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);

Ensuite, nous allons configurer A2 et A3 qui sont respectivement TX et RX pour le UART2. Cette assignation est une fonction alternative de A2 et A3. Nous allons donc spécifier qu’ils utilisent une fonction alternative (AF) puis nous allons spécifier que la fonction alternative est UART2.

  /* Configuration des GPIO*/
 GPIO_InitTypeDef GPIO_InitStructure;
 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3; 
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
 GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
 GPIO_Init(GPIOA, &GPIO_InitStructure);
 GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_USART2);
 GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_USART2);

La prochaine étape consiste à configurer UART2. Dans cette exemple, la configuration sera 115200 bauds, 8 bits de données, aucune parité et 1 stop bit. La dernière ligne active le UART2.

 /* Configuration du UART2 */
 USART_InitTypeDef USART_InitStructure;
 USART_InitStructure.USART_BaudRate = 115200;
 USART_InitStructure.USART_WordLength = USART_WordLength_8b;
 USART_InitStructure.USART_StopBits = USART_StopBits_1;
 USART_InitStructure.USART_Parity = USART_Parity_No;
 USART_InitStructure.USART_HardwareFlowControl =          USART_HardwareFlowControl_None;
 USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
 USART_Init(USART2, &USART_InitStructure);
 USART_Cmd(USART2, ENABLE);

Afin de vérifier le fonctionnement du programme, voici une fonction qui affiche envoie une chaîne de caractères. La boucle vérifie que le caractère courant est différent de zéro (le caractère de fin). Elle attend ensuite que le transmetteur soit libre, puis elle envoie un caractère et repositionne le curseur pour le prochain caractère.

void uart2Puts(char *s)
{
 while(*s)
 {
 while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET);
 USART_SendData(USART2, *s++);
 }
}

Le programme suivant envoie le message « Bonjour le mode » puis il retourne en écho les caractères qu’il reçoit. La fonction uart2Init() regroupe l’ensemble du code d’initialisation présenté au début de cet article.

int main(void)
{
 uart2Init();
 uart2Puts("Bonjour le monde \r\n");
 while(1) // Faire un écho à l'infini
 {
   uint16_t rxData;
   while(USART_GetFlagStatus(USART2, USART_FLAG_RXNE) == RESET);
   rxData = USART_ReceiveData(USART2);
   while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET);
   USART_SendData(USART2, rxData);
 }
}