Limpando sinalizadores de interrupção USART (UART) em um STM32?

8

Estou usando um STM32F105 para me comunicar com um chip GPS Linx usando um UART.

Se eu não usar interrupções (se eu apenas pesquisar o sinalizador RX), ele funcionará perfeitamente. Mas estou obtendo resultados inesperados ao tentar usar interrupções.

Por exemplo, se eu habilitar apenas a interrupção do RXNE ("O RX não está vazio") usando USART_ITConfig(USARTx, USART_IT_RXNE), o código deverá ser vetorizado apenas para o ISR para esse evento específico. Mas a interrupção também está sendo acionada para uma condição de superação.

Tanto quanto limpar as bandeiras, parece que o método depende da bandeira. Para limpar o sinalizador Overrun ( USART_IT_ORE), o Manual do Usuário explica que eu deveria primeiro ler o USARTx_SRregistro e, em seguida, ler o USARTx_DRregistro. Isso funciona; a bandeira está limpa.

Há também uma USART_ClearITPendingBit()função, mas ela aceita apenas um pequeno subconjunto de sinalizadores.

Existem oito fontes de interrupção diferentes que podem ser ativadas seletivamente e dez sinalizadores diferentes. Existe um resumo em algum lugar de como gerenciar todos esses sinalizadores?

bitsmack
fonte

Respostas:

16

Geralmente, você só precisa manipular os sinalizadores de interrupção com os quais você ativou especificamente USART_ITConfig().

No entanto, se você ativar a interrupção RXNE ( USART_ITConfig(USARTx, USART_IT_RXNE)), isso também ativará a interrupção Overrun! Então você deve lidar com ambos.

intmap

As bandeiras USART podem ser confusas. Existem sinalizadores de status separados e sinalizadores de interrupção e eles compartilham nomes semelhantes. Por exemplo: USART_IT_RXNEe USART_FLAG_RXNE.

Além disso, existem vários métodos para limpar esses sinalizadores. Por exemplo, a USART_ClearITPendingBit()função funciona apenas para quatro (dos dez) sinalizadores possíveis.

Aqui está um resumo dos sinalizadores de interrupção e como usá-los. Eles são específicos para o STM32F105, mas são representativos:


USART_IT_TXE - "Transmitir registro de dados vazio"

  • É apagado automaticamente ao chamar USART_SendData()

USART_IT_RXNE - "O registro de dados de recebimento não está vazio"

  • É apagado automaticamente ao chamar USART_ReceiveData(USARTx)

  • Pode ser limpo manualmente chamando USART_ClearITPendingBit(USARTx, USART_IT_RXNE)


USART_IT_TC - "Transmissão concluída"

  • É limpo automaticamente por:

    • USART_GetITStatus(USARTx, USART_IT_TC) Seguido por
    • USART_SendData()
  • Também pode ser limpo manualmente chamando USART_ClearITPendingBit(USARTx, USART_IT_TC)


USART_IT_CTS - "Alteração do CTS"

  • Apagado chamando USART_ClearITPendingBit(USARTx, USART_IT_CTS)

USART_IT_LBD - "Quebra de LIN detectada"

  • Apagado chamando USART_ClearITPendingBit(USARTx, USART_IT_LBD)

USART_IT_PE - "Erro de paridade"

  • Autorizada por:
    • USART_GetITStatus(USARTx, USART_IT_PE) Seguido por
    • USART_ReceiveData(USARTx)

USART_IT_NE - "Erro de ruído"

  • Autorizada por:
    • USART_GetITStatus(USARTx, USART_IT_NE) Seguido por
    • USART_ReceiveData(USARTx)

USART_IT_ORE - "Erro de saturação "

  • Autorizada por:
    • USART_GetITStatus(USARTx, USART_IT_ORE) Seguido por
    • USART_ReceiveData(USARTx)()

USART_IT_IDLE - "Linha ociosa detectada"

  • Autorizada por:
    • USART_GetITStatus(USARTx, USART_IT_IDLE) Seguido por
    • USART_ReceiveData(USARTx)()
bitsmack
fonte
Sim, eu respondi minha própria pergunta :) Se eu tivesse encontrado uma lista como essa anteriormente, isso me pouparia um bom tempo. Eu espero que isso ajude alguém!
bitsmack
2
Esta resposta é ouro; referência muito clara de como limpar cada uma dessas interrupções.
Jjmilburn # 22/16
2

Só quero adicionar um pouco da minha experiência com esse problema, sigo as instruções:

USART_IT_ORE - "Erro de saturação"

Desmarcado por: USART_GetITStatus (USARTx, USART_IT_ORE) seguido por USART_ReceiveData (USARTx) ()

Parece não funcionar, e o seguinte comando funciona para mim:

USART_GetFlagStatus (USARTx, USART_IT_ORE) seguido por USART_ReceiveData (USARTx)

Se você olhar para as funções:

USART_GetFlagStatus () e USART_ReceiveData ()

Você encontrará o que exatamente o Bitsmack escreveu antes ... "Primeiro leia o registro USARTx_SR e, em seguida, leia o registro USARTx_DR."

Espero que funcione para você e economize muito mais tempo com esse problema. =)

LostInCoding
fonte
Obrigado pela sua informação! Não reconheço USART_GetFlat (). Você pode me dizer de onde vem?
bitsmack
Sinto muito por eu ter digitado incorretamente o comando, deve ser USART_GetFlagStatus () seguido de USART_ReceiveData (), a postagem original foi corrigida. Obrigado Bitsmack.
LostInCoding 18/10/19
Excelente, obrigado! Parece que os nomes das funções foram alterados. Você está usando uma biblioteca periférica padrão ou um dos HALs do STMCube? Para qual família de microcontroladores?
bitsmack