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?

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)()

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


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
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.