Effacer les drapeaux d'interruption USART (UART) dans un STM32?

8

J'utilise un STM32F105 pour communiquer avec une puce GPS Linx à l'aide d'un UART.

Si je n'utilise pas d'interruptions (si j'interroge simplement l'indicateur RX), cela fonctionne très bien. Mais j'obtiens des résultats inattendus lorsque j'essaie d'utiliser des interruptions.

Par exemple, si j'active uniquement l'interruption RXNE ("RX not empty") à l'aide USART_ITConfig(USARTx, USART_IT_RXNE), le code ne doit être vecteur que vers l'ISR pour cet événement spécifique. Mais l'interruption est également déclenchée pour une condition de dépassement.

En ce qui concerne la suppression des drapeaux, il semble que la méthode dépende du drapeau. Pour effacer l'indicateur de dépassement ( USART_IT_ORE), le manuel de l'utilisateur explique que je devrais d'abord lire le USARTx_SRregistre, puis lire le USARTx_DRregistre. Cela fonctionne; le drapeau est effacé.

Il existe également une USART_ClearITPendingBit()fonction, mais elle n'accepte qu'un petit sous-ensemble de drapeaux.

Il existe huit sources d'interruption différentes qui peuvent être activées de manière sélective et dix drapeaux différents. Y a-t-il un résumé quelque part de la façon de gérer tous ces indicateurs?

bitsmack
la source

Réponses:

16

En règle générale, il vous suffit de gérer les indicateurs d'interruption que vous avez spécifiquement activés avec USART_ITConfig().

Cependant, si vous activez l'interruption RXNE ( USART_ITConfig(USARTx, USART_IT_RXNE)), cela active également l'interruption Overrun! Vous devez donc gérer les deux.

intmap

Les drapeaux USART peuvent prêter à confusion. Il existe des indicateurs d'état et des indicateurs d'interruption distincts et ils partagent des noms similaires. Par exemple: USART_IT_RXNEet USART_FLAG_RXNE.

En outre, il existe différentes méthodes pour effacer ces indicateurs. Par exemple, la USART_ClearITPendingBit()fonction ne fonctionne que pour quatre (des dix) indicateurs possibles.

Voici un résumé des indicateurs d'interruption et comment les utiliser. Ils sont spécifiques au STM32F105, mais sont représentatifs:


USART_IT_TXE - "Le registre de transmission des données est vide"

  • Il est effacé automatiquement lors de l'appel USART_SendData()

USART_IT_RXNE - "Le registre de réception des données n'est pas vide"

  • Il est effacé automatiquement lors de l'appel USART_ReceiveData(USARTx)

  • Il peut être effacé manuellement en appelant USART_ClearITPendingBit(USARTx, USART_IT_RXNE)


USART_IT_TC - "Transmission terminée"

  • Il est effacé automatiquement par:

    • USART_GetITStatus(USARTx, USART_IT_TC) suivi par
    • USART_SendData()
  • Il peut également être effacé manuellement en appelant USART_ClearITPendingBit(USARTx, USART_IT_TC)


USART_IT_CTS - "Changement CTS"

  • Effacé en appelant USART_ClearITPendingBit(USARTx, USART_IT_CTS)

USART_IT_LBD - "Rupture LIN détectée"

  • Effacé en appelant USART_ClearITPendingBit(USARTx, USART_IT_LBD)

USART_IT_PE - "Erreur de parité"

  • Autorisé par:
    • USART_GetITStatus(USARTx, USART_IT_PE) suivi par
    • USART_ReceiveData(USARTx)

USART_IT_NE - "Erreur de bruit"

  • Autorisé par:
    • USART_GetITStatus(USARTx, USART_IT_NE) suivi par
    • USART_ReceiveData(USARTx)

USART_IT_ORE - "Erreur de dépassement "

  • Autorisé par:
    • USART_GetITStatus(USARTx, USART_IT_ORE) suivi par
    • USART_ReceiveData(USARTx)()

USART_IT_IDLE - "Ligne inactive détectée"

  • Autorisé par:
    • USART_GetITStatus(USARTx, USART_IT_IDLE) suivi par
    • USART_ReceiveData(USARTx)()
bitsmack
la source
Oui, j'ai répondu à ma propre question :) Si j'avais trouvé une liste comme celle-ci plus tôt, cela m'aurait fait gagner beaucoup de temps. J'espère que ça aide quelqu'un!
bitsmack
2
Cette réponse est or; référence très claire sur la façon d'effacer chacune de ces interruptions.
jjmilburn
2

Je veux juste ajouter mon expérience sur ce problème, je suis les instructions:

USART_IT_ORE - "Erreur de dépassement"

Effacé par: USART_GetITStatus (USARTx, USART_IT_ORE) suivi de USART_ReceiveData (USARTx) ()

Cela ne semble pas fonctionner, et la commande suivante fonctionne pour moi à la place:

USART_GetFlagStatus (USARTx, USART_IT_ORE) suivi de USART_ReceiveData (USARTx)

Si vous regardez les fonctions:

USART_GetFlagStatus () et USART_ReceiveData ()

Vous trouverez ce qu'écrivait exactement Bitsmack avant ... "Lisez d'abord le registre USARTx_SR, puis lisez le registre USARTx_DR."

J'espère que cela fonctionnera pour vous et vous fera gagner beaucoup plus de temps sur ce problème. =)

LostInCoding
la source
Merci pour ton information! Je ne reconnais pas USART_GetFlat (). Pouvez-vous me dire d'où ça vient?
bitsmack
Je suis désolé d'avoir mal tapé sur la commande, cela devrait être USART_GetFlagStatus () suivi de USART_ReceiveData (), le message d'origine a été corrigé. Merci Bitsmack.
LostInCoding
Excellent merci! Il semble que les noms des fonctions aient changé. Utilisez-vous une bibliothèque périphérique standard ou l'un des HAL STMCube? Pour quelle famille de microcontrôleurs?
bitsmack