Estou usando UART IO baseado em interrupção (sem DMA).
HAL_UART_Transmit_IT
A função define o EIE
bit no CR3
registro. De acordo com a folha de dados do STM32F407 (e comportamento real), isso gera interrupção apenas no modo de buffer múltiplo (quando o DMAR
bit está definido). EIE
ativa a geração de interrupção para erro de quadro ( FE
), erro de saturação ( ORE
), erro de ruído ( NE
). Este erro, pelo que entendi, apenas para receber.
Parte da HAL_UART_IRQHandler
função:
tmp1 = __HAL_UART_GET_FLAG(huart, UART_FLAG_ORE);
tmp2 = __HAL_UART_GET_IT_SOURCE(huart, UART_IT_ERR);
/* UART Over-Run interrupt occurred ----------------------------------------*/
if((tmp1 != RESET) && (tmp2 != RESET))
{
__HAL_UART_CLEAR_OREFLAG(huart);
huart->ErrorCode |= HAL_UART_ERROR_ORE;
}
if(huart->ErrorCode != HAL_UART_ERROR_NONE)
{
/* Set the UART state ready to be able to start again the process */
huart->State = HAL_UART_STATE_READY;
HAL_UART_ErrorCallback(huart);
}
HAL_UART_IRQHandler
verifica cada erro. Se o erro ocorreu e o EIE
bit está definido, ele redefine o estado UART, mas não redefine os bits de ativação de interrupção, portanto a TXE
interrupção será sempre gerada, mas a UART_Transmit_IT
função trata o estado HAL_UART_STATE_READY
como inválido e não faz nada. Loop infinito.
Parte da UART_Transmit_IT
função:
static HAL_StatusTypeDef UART_Transmit_IT(UART_HandleTypeDef *huart)
{
uint16_t* tmp;
uint32_t tmp1 = 0;
tmp1 = huart->State;
if((tmp1 == HAL_UART_STATE_BUSY_TX) || (tmp1 == HAL_UART_STATE_BUSY_TX_RX))
{
}
else
{
return HAL_BUSY;
}
}
É um bug no Cube HAL?
fonte
Respostas:
Isso é um bug.
Fiz a mesma pergunta no fórum ST: https://my.st.com/d5c15f59
Eles confirmaram isso.
fonte
Você tentou baixar a versão mais recente do Cube HAL para o seu MCU?
Minha função HAL_UART_Transmit_IT () parece muito diferente da sua. Talvez você tenha uma versão mais antiga com erros.
Tente acessar st.com e procure a versão mais recente do Cube HAL. Dentro do arquivo, você encontrará alguns exemplos com o USART.
fonte
HAL_UART_Transmit_IT
eUART_Transmit_IT
são funções diferentes. Primeiro apenas estabelece-se interrupções, enquanto o segundo realmente transmite dados