Page Personnelle de Vincent Kerhoas
Vincent Kerhoas
Enseignant du Supérieur
Professeur Agrégé
Page Personnelle de Vincent Kerhoas

Liaison UART

Back                  << Index >>


DOCUMENTATION


La liaison UART (Universal Asynchronous Receiver Transceiver ) est une vieille liaison, peu performante, historiquement utilisée pour le dialogue entre un PC et un modem.
Cette liaison est malgré tout toujours présente dans les microprocesseurs en raison de sa simplicité de mise en oeuvre, dans un contexte de Debug ou pour un dialogue avec un capteur.


La trame UART

Une trame UART permet d’envoyer un seul caractère, de longueur 7,8 ou 9 bits.

Pour chaque caractère, il faut ajouter :


Configuration du périphérique UART

Configuration d’une trame

Le microcontrôleur STM32F411 présente 3 registres de contrôle/configuration.

Dans ces 3 registres, les bits importants pour une utilisation minimale sont :

Configuration du baud rate ( débit sur la ligne )

Le débit sur la ligne est plus lent que l’horloge du périphérique UART.
Il va donc falloir diviser la fréquence afin de définir le baud rate.
On a vu dans le chapitre ‘liaison série’ qu’il fallait attendre T/2 pour faire l’acquisition d’un bit ( T étant la durée d’un bit ), afin d’être sûr d’avoir un état stabilisé.
Pour garantir ce positionnement par rapport au débit sur la ligne, on divise le temps en quantums de temps 16 fois plus rapides que le débit.

Il faut donc régler dans le registre BRR un ratio tel que :

\( USARTDIV = \frac{F_{CK}}{16.baudrate} \)

Le registre BRR contient une valeur au format virgule fixe 12.4

soit \( F_{CK} = 42MHz \)

Je souhaite baudrate = 9600

J’ai donc :
\( USARTDIV= \frac{F_{CK}}{baudrate} \)
\( USARTDIV= \frac{42.10^6}{16*9600} \)
\( USARTDIV= 273.4375 \)

Comme on est au format 12.4, le codage de 273.4375 est le même que celui de \( 273.7375*2^4 = 4375 \)

Conclusion :

\( BRR = \frac{F_{CK}}{baudrate} \)


Le périphérique UART en action

Emission d’un octet

Pour simplifier On fait l’hypothèse que les données font toujours 8 bits, qu’il n’y a pas de bit de parité, et qu’il y a un bit de stop.

Réception d’un octet ( avec interruption )


Programmation du périphérique UART

RAPPEL : Les registres sont détaillés dans la documentation RefManual_STM32F411.pdf

Configuration des Broches

Le STM32F411 comporte 3 périphériques UART ( USART1, USART2, USART6 ).
USART2 est relié au processeur gérant l’interface de debug de la carte ( STLINK ) , de telle sorte qu’il y ait conversion UART –> USB.
Ainsi la liaison UART2 est accessible directement par le cable USB.

Extrait de la documentation de la carte Nucleo F411 :

Les broches à configurer sont donc PA2 (TX) et PA3 (RX) ( Datasheet STM32F411 ) :

PA2 et PA3 doivent donc être configurées en Alternate Function 07

REMARQUE : PA3 est une entrée d’un périphérique, elle peut être également configurée en Input

stm32f4xx_hal_msp.c

Configuration du périphérique

Nous allons considérer la structure UART_HandleTypeDef suivante :

stm32f4xx_hal_uart.h

USART_TypeDef Permet d’accéder aux différents registres de UART :

stm32f411xe.h

UART_InitTypeDef Permet de définir les différents éléments de configuration :

stm32f4xx_hal_uart.h

La fonction HAL_UART_Init() permet de configurer les registres du périphérique à partir des éléments définis dans le champ Init de la structure UART_HandleTypeDef

Appel de HAL_UART_Init() en début du main() :

main.c

Emission d’un Caractère

Dès lors que j’ai branché ma carte sur le PC, il se crée un fichier /dev/ttyACM0 auquel je ferai référence côté PC pour désigner l’émission et la réception de caractère sur l’UART.
Ouvrons sur le PC un terminal série ( gtkterm ou avec la commande minicom -D /dev/ttyACM0 -b 115200 )

Si j’écris, dans le programme de la carte :

main.c

J’écris le codage ASCII de ‘a’ dans le registre de transmission, ce caractère est sérialisé.

Si maintenant j’écris :

main.c

seul le caractère ‘c’ s’affiche, je n’ai pas attendu qu’un caractère soit sérialisé pour envoyer le suivant.
Il faut donc tester la bonne émission de chaque caractère avant d’écrire dans DR.
Le bit TXE ( registre USART_SR, bit 7 ) Transmit data register empty vaut 1 quand le registre TX est vide, autrement dit la donnée a bien été transmise au registre sérialisateur, on peut écrire une nouvelle donnée dans DR.

Ainsi on peut écrire :

main.c

Réception d’un Caractère sur Interruption

Autorisation de l’Interruption USART2 niveau NVIC :

stm32f4xx_hal_msp.c

Autorisation de l’Interruption USART2 niveau Périphérique :

stm32f4xx_hal_uart.c

IRQ Handler :

REMARQUE : La lecture du registre DR est dans tous les cas nécessaire afin d’acquiter la demande d’interruption.

stm32f4xx_hal_uart.c

Fonction de Callback liée à la réception d’un caractère :

main.c

Travaux Pratiques

PROJET SOURCE


WORKSPACE_F411_HAL_STM32CUBE


Vérification de la configuration

Q1. Compléter le fichier stm32f4xx_hal_msp.c afin de configurer les broches PA2 et PA3 en tant que broches TX et RX du périphérique USART2.
La réception d’un caractère devant déclencher une interruption, le NVIC doit être configuré.

Q1. Véfifier à l’aide du debugger la valeurs des bits UE, M, PCE, TE, RE, STOP à l’issue de l’appel de la fonction HAL_UART_Init()

Envoi d’une chaine de caractères : HAL_UART_Transmit()

Q2. 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

Q3. Tester la fonction HAL_UART_Transmit() :

Q4. 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 )

Q5. Réaliser l’enregistrement d’une trame UART avec un analyseur logique.

Réception de caractères sur interruptions

Q6. Placer un point d’arrêt dans la routine d’interruption HAL_USART_IRQHandler() et vérfier qu’à chaque caractère reçu on s’y arrête bien.
Vérifier que le caractère reçu est bien celui qui a été envoyé depuis le PC avec le terminal série.

Gestion d’un buffer Circulaire en réception

Q7. On veut faire varier la vitesse de clignotement d’une led ( R, G ou B ) depuis le PC.
Pour cela nous devons envoyer via la liaison UART des ordres au format suivant :

La durée de clignotement est comprise entre 0 et 5000ms, cette donnée est envoyée sous forme de valeur ( et non en chaine de caractères ).

Le codage de cette valeur n’est donc pas possible sur 8 bits, il faut 2 octets.

Pour répartir notre valeur sur 2 octets, on fera donc :

A.N : valeur = 1000 = 0x03E8

Comme il faut recevoir et interpréter un message de plusieurs caractères, une méthode peut consister à :

main.c

Pour envoyer les ordres depuis le PC, nous pouvons utiliser le programme python suivant :

sendOrder.py

Pour lancer le programme, dans un terminal :


Back                  << Index >>