先借用正点原子HAL库串口中断流程
HAL_UART_Receive(); | 串口轮询模式接收,使用超时管理机制 |
HAL_UART_Receive_IT(); | 串口中断模式接收 |
带有_IT的函数是中断模式的,当收到数据发生中断的时候会执行这个函数USART1_IRQHandler(void),而在这个函数中又会调用HAL_UART_IRQHandler(&huart1),如下图所示:
而在HAL_UART_IRQHandler(&huart1)函数中又会调用UART_Receive_IT,进行中断是否结束的判断,若中断结束,从而再调用中断回调函数HAL_UART_RxCpltCallBack();
但是,我在CubeMX所生成的头文件中并没有找到按上述流程的中断流程?找到的是下述流程的中断流程:
首先是我们在main.c中自己添加的HAL_UART_Receive_IT()函数
在HAL_UART_Receive_IT()中进行判断,判断完成后又调用了UART_Start_Receive_IT()函数
在UART_Start_Receive_IT()函数中又使 huart->RxISR 函数指针映射到了UART_RxISR_8BIT(数据位为8位),这时直接进入UART_RxISR_8BIT函数做接收处理。
最后在UART_RxISR_8BIT函数中,调用HAL_UART_RxCpltCallback()函数进行中断处理。
static void UART_RxISR_8BIT(UART_HandleTypeDef *huart)
{
uint16_t uhMask = huart->Mask;
uint16_t uhdata;
/* Check that a Rx process is ongoing */
if (huart->RxState == HAL_UART_STATE_BUSY_RX)
{
uhdata = (uint16_t) READ_REG(huart->Instance->RDR);
*huart->pRxBuffPtr = (uint8_t)(uhdata & (uint8_t)uhMask);
huart->pRxBuffPtr++;
huart->RxXferCount--;
if (huart->RxXferCount == 0U)
{
/* Disable the UART Parity Error Interrupt and RXNE interrupts */
ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
/* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */
ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
/* Rx process is completed, restore huart->RxState to Ready */
huart->RxState = HAL_UART_STATE_READY;
/* Clear RxISR function pointer */
huart->RxISR = NULL;
/* Check current reception Mode :
If Reception till IDLE event has been selected : */
if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
{
/* Set reception type to Standard */
huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
/* Disable IDLE interrupt */
ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
if (__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE) == SET)
{
/* Clear IDLE Flag */
__HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF);
}
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
/*Call registered Rx Event callback*/
huart->RxEventCallback(huart, huart->RxXferSize);
#else
/*Call legacy weak Rx Event callback*/
HAL_UARTEx_RxEventCallback(huart, huart->RxXferSize);
#endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
}
else
{
/* Standard reception API called */
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
/*Call registered Rx complete callback*/
huart->RxCpltCallback(huart);
#else
/*Call legacy weak Rx complete callback*/
HAL_UART_RxCpltCallback(huart);
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
}
}
}
else
{
/* Clear RXNE interrupt flag */
__HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
}
}
最后回到HAL_UART_RxCpltCallback()函数。
(希望大佬指正!)