Cancellare i flag di interruzione USART (UART) in un STM32?


8

Sto usando un STM32F105 per comunicare con un chip Linx GPS usando un UART.

Se non utilizzo gli interrupt (se eseguo semplicemente il polling del flag RX), allora funziona perfettamente. Ma sto ottenendo risultati inaspettati quando provo a usare gli interrupt.

Ad esempio, se abilito solo l'interruzione RXNE ("RX non vuoto") utilizzando USART_ITConfig(USARTx, USART_IT_RXNE), il codice dovrebbe essere vettoriale per l'ISR solo per questo evento specifico. Ma anche l'interrupt viene attivato per una condizione di Overrun.

Per quanto riguarda la cancellazione delle bandiere, sembra che il metodo dipenda dalla bandiera. Per cancellare il flag Overrun ( USART_IT_ORE), il Manuale dell'utente spiega che dovrei prima leggere il USARTx_SRregistro, quindi leggere il USARTx_DRregistro. Questo funziona; la bandiera è cancellata.

C'è anche una USART_ClearITPendingBit()funzione, ma accetta solo un piccolo sottoinsieme di flag.

Esistono otto diverse origini di interrupt che possono essere abilitate in modo selettivo e dieci flag diversi. C'è un riassunto da qualche parte su come gestire tutte queste bandiere?

Risposte:


16

Generalmente, devi solo gestire i flag di interrupt con cui hai abilitato in modo specifico USART_ITConfig().

Tuttavia, se si abilita l'interruzione RXNE ( USART_ITConfig(USARTx, USART_IT_RXNE)), questo abilita anche l'interruzione Overrun! Quindi devi gestirli entrambi.

intmap

I flag USART possono essere fonte di confusione. Esistono flag di stato e flag di interruzione separati e condividono nomi simili. Ad esempio: USART_IT_RXNEe USART_FLAG_RXNE.

Inoltre, ci sono vari metodi per cancellare queste bandiere. Ad esempio, la USART_ClearITPendingBit()funzione funziona solo per quattro (dei dieci) possibili flag.

Ecco un riepilogo dei flag di interrupt e come usarli. Questi sono specifici per STM32F105, ma sono rappresentativi:


USART_IT_TXE - "Trasmetti registro dati vuoto"

  • Si cancella automaticamente quando si chiama USART_SendData()

USART_IT_RXNE - "Il registro dei dati di ricezione non è vuoto"

  • Si cancella automaticamente quando si chiama USART_ReceiveData(USARTx)

  • Può essere cancellato manualmente chiamando USART_ClearITPendingBit(USARTx, USART_IT_RXNE)


USART_IT_TC - "Trasmissione completata"

  • Viene cancellato automaticamente da:

    • USART_GetITStatus(USARTx, USART_IT_TC) seguito da
    • USART_SendData()
  • Può anche essere cancellato manualmente chiamando USART_ClearITPendingBit(USARTx, USART_IT_TC)


USART_IT_CTS - "Modifica CTS"

  • Cancellato chiamando USART_ClearITPendingBit(USARTx, USART_IT_CTS)

USART_IT_LBD - " Rilevata interruzione LIN"

  • Cancellato chiamando USART_ClearITPendingBit(USARTx, USART_IT_LBD)

USART_IT_PE - "Errore di parità"

  • Cancellato da:
    • USART_GetITStatus(USARTx, USART_IT_PE) seguito da
    • USART_ReceiveData(USARTx)

USART_IT_NE - "Errore rumore"

  • Cancellato da:
    • USART_GetITStatus(USARTx, USART_IT_NE) seguito da
    • USART_ReceiveData(USARTx)

USART_IT_ORE - "Errore di sovraccarico"

  • Cancellato da:
    • USART_GetITStatus(USARTx, USART_IT_ORE) seguito da
    • USART_ReceiveData(USARTx)()

USART_IT_IDLE - " Rilevata linea inattiva"

  • Cancellato da:
    • USART_GetITStatus(USARTx, USART_IT_IDLE) seguito da
    • USART_ReceiveData(USARTx)()

Sì, ho risposto alla mia domanda :) Se avessi trovato un elenco come questo in precedenza, mi avrebbe fatto risparmiare un bel po 'di tempo. Spero che aiuti qualcuno!
bitsmack

2
Questa risposta è oro; riferimento molto chiaro su come cancellare ciascuno di questi interrupt.
jjmilburn,

2

Voglio solo aggiungere un po 'della mia esperienza su questo problema, seguo le istruzioni:

USART_IT_ORE - "Errore di sovraccarico"

Cancellato da: USART_GetITStatus (USARTx, USART_IT_ORE) seguito da USART_ReceiveData (USARTx) ()

Sembra non funzionare, e invece il seguente comando funziona per me:

USART_GetFlagStatus (USARTx, USART_IT_ORE) seguito da USART_ReceiveData (USARTx)

Se guardi nelle funzioni:

USART_GetFlagStatus () e USART_ReceiveData ()

Troverai cosa ha scritto esattamente Bitsmack prima ... "Prima leggi il registro USARTx_SR, quindi leggi il registro USARTx_DR."

Spero che funzioni per te e risparmi molto più tempo su questo problema. =)


Grazie per le informazioni! Non riconosco USART_GetFlat (). Puoi dirmi da dove viene?
bitsmack,

Mi dispiace di aver erroneamente digitato il comando, dovrebbe essere USART_GetFlagStatus () seguito da USART_ReceiveData (), il post originale è stato corretto. Grazie Bitsmack.
LostInCoding

Eccellente grazie! Sembra che i nomi delle funzioni siano cambiati. Stai utilizzando una libreria periferica standard o uno degli HAL STMCube? Per quale famiglia di microcontrollori?
bitsmack,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.