void HAL_UART_IRQHandler(UART_HandleTypeDef *huart)
{
uint32_t isrflags = READ_REG(huart->Instance->ISR);
uint32_t cr1its = READ_REG(huart->Instance->CR1);
uint32_t cr3its = READ_REG(huart->Instance->CR3);
uint32_t errorflags;
uint32_t errorcode;
errorflags = (isrflags & (uint32_t)(USART_ISR_PE | USART_ISR_FE | USART_ISR_ORE | USART_ISR_NE | USART_ISR_RTOF));
if (errorflags == 0U)
{
if (((isrflags & USART_ISR_RXNE) != 0U)
&& ((cr1its & USART_CR1_RXNEIE) != 0U))
{
if (huart->RxISR != NULL)
{
huart->RxISR(huart);
}
return;
}
}
if ((errorflags != 0U)
&& (((cr3its & USART_CR3_EIE) != 0U)
|| ((cr1its & (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_RTOIE)) != 0U)))
{
if (((isrflags & USART_ISR_PE) != 0U) && ((cr1its & USART_CR1_PEIE) != 0U))
{
__HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_PEF);
huart->ErrorCode |= HAL_UART_ERROR_PE;
}
if (((isrflags & USART_ISR_FE) != 0U) && ((cr3its & USART_CR3_EIE) != 0U))
{
__HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_FEF);
huart->ErrorCode |= HAL_UART_ERROR_FE;
}
if (((isrflags & USART_ISR_NE) != 0U) && ((cr3its & USART_CR3_EIE) != 0U))
{
__HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_NEF);
huart->ErrorCode |= HAL_UART_ERROR_NE;
}
if (((isrflags & USART_ISR_ORE) != 0U)
&& (((cr1its & USART_CR1_RXNEIE) != 0U) ||
((cr3its & USART_CR3_EIE) != 0U)))
{
__HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF);
huart->ErrorCode |= HAL_UART_ERROR_ORE;
}
if (((isrflags & USART_ISR_RTOF) != 0U) && ((cr1its & USART_CR1_RTOIE) != 0U))
{
__HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_RTOF);
huart->ErrorCode |= HAL_UART_ERROR_RTO;
}
if (huart->ErrorCode != HAL_UART_ERROR_NONE)
{
if (((isrflags & USART_ISR_RXNE) != 0U)
&& ((cr1its & USART_CR1_RXNEIE) != 0U))
{
if (huart->RxISR != NULL)
{
huart->RxISR(huart);
}
}
errorcode = huart->ErrorCode;
if ((HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) ||
((errorcode & (HAL_UART_ERROR_RTO | HAL_UART_ERROR_ORE)) != 0U))
{
UART_EndRxTransfer(huart);
if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
{
CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
if (huart->hdmarx != NULL)
{
huart->hdmarx->XferAbortCallback = UART_DMAAbortOnError;
if (HAL_DMA_Abort_IT(huart->hdmarx) != HAL_OK)
{
huart->hdmarx->XferAbortCallback(huart->hdmarx);
}
}
else
{
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
huart->ErrorCallback(huart);
#else
HAL_UART_ErrorCallback(huart);
#endif
}
}
else
{
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
huart->ErrorCallback(huart);
#else
HAL_UART_ErrorCallback(huart);
#endif
}
}
else
{
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
huart->ErrorCallback(huart);
#else
HAL_UART_ErrorCallback(huart);
#endif
huart->ErrorCode = HAL_UART_ERROR_NONE;
}
}
return;
}
if ((huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
&& ((isrflags & USART_ISR_IDLE) != 0U)
&& ((cr1its & USART_ISR_IDLE) != 0U))
{
__HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF);
if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
{
uint16_t nb_remaining_rx_data = (uint16_t) __HAL_DMA_GET_COUNTER(huart->hdmarx);
if ((nb_remaining_rx_data > 0U)
&& (nb_remaining_rx_data < huart->RxXferSize))
{
huart->RxXferCount = nb_remaining_rx_data;
if (huart->hdmarx->Init.Mode != DMA_CIRCULAR)
{
CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE);
CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
huart->RxState = HAL_UART_STATE_READY;
huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
(void)HAL_DMA_Abort(huart->hdmarx);
}
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
huart->RxEventCallback(huart, (huart->RxXferSize - huart->RxXferCount));
#else
HAL_UARTEx_RxEventCallback(huart, (huart->RxXferSize - huart->RxXferCount));
#endif
}
return;
}
else
{
uint16_t nb_rx_data = huart->RxXferSize - huart->RxXferCount;
if ((huart->RxXferCount > 0U)
&& (nb_rx_data > 0U))
{
CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
huart->RxState = HAL_UART_STATE_READY;
huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
huart->RxISR = NULL;
CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
huart->RxEventCallback(huart, nb_rx_data);
#else
HAL_UARTEx_RxEventCallback(huart, nb_rx_data);
#endif
}
return;
}
}
#if defined(USART_CR1_UESM)
#if defined(USART_CR3_WUFIE)
if (((isrflags & USART_ISR_WUF) != 0U) && ((cr3its & USART_CR3_WUFIE) != 0U))
{
__HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_WUF);
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
huart->WakeupCallback(huart);
#else
HAL_UARTEx_WakeupCallback(huart);
#endif
return;
}
#endif
#endif
if (((isrflags & USART_ISR_TXE) != 0U)
&& ((cr1its & USART_CR1_TXEIE) != 0U))
{
if (huart->TxISR != NULL)
{
huart->TxISR(huart);
}
return;
}
if (((isrflags & USART_ISR_TC) != 0U) && ((cr1its & USART_CR1_TCIE) != 0U))
{
UART_EndTransmit_IT(huart);
return;
}
}
串口中断在发生HAL_UART_ERROR_RTO(接收器超时)或者HAL_UART_ERROR_ORE(溢出错误)中断后程序进入UART_EndRxTransfer(huart)失能USART_CR1_RXNEIE 、USART_CR1_PEIE、USART_CR3_EIE,导致串口无法再接收数据
static void UART_EndRxTransfer(UART_HandleTypeDef *huart)
{
CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
{
CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
}
huart->RxState = HAL_UART_STATE_READY;
huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
huart->RxISR = NULL;
}
解决办法: 出现上述现象后,HAL库会调用__weak void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)函数,在此函数中重新初始化串口
|