串口接收有两个中断标志
RXNE
接收不为空receive not Empty。
这个标志是硬件置位当RDR移位寄存器被传送到RDR寄存器时就被置位,当RDR被读取就会被自动清空,或者手动写1到usart_RQR->RXFRQ。
IDLE
空闲标志位
标志一段连续数据接收的完成,可以理解为信号线电平的无数据,串口总是一串高低电平的传送,数据发送完无数据的时候就代表IDLE。
串口与DMA的配合
如果我们不用DMA的话,那么CPU会被串口的每一个字节打断进入中断,也就是IT模式,这样系统运行效率会很低,因此使用DMA设置好源地址为RDR,目的地址为系统缓冲器。当一串数据从usart发送到DMA完成,当然这个过程是自动的我们代码层面是透明的,我们需要做的就是等DMA的接收完成通知。DMA其实就是自动完成RDR或者TDR到BUFFER的操作提高了效率。
/* Configure the source, destination address and the data length & clear flags*/
DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength);
开启DMA传输完成中断
__HAL_DMA_DISABLE_IT(hdma, DMA_IT_HT);
__HAL_DMA_ENABLE_IT(hdma, (DMA_IT_TC | DMA_IT_TE));
DMA完成后操作
dma完成后数据就在系统的接收缓冲区内了。
可以自己重写HAL_UART_RxCpltCallback回调处理函数,或者在里面调用自己的处理函数。
/**
* @brief DMA UART receive process complete callback.
* @param hdma DMA handle.
* @retval None
*/
static void UART_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
{
UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent);
/* DMA Normal mode */
if (HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC))
{
huart->RxXferCount = 0U;
/* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */
CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE);
CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
/* Disable the DMA transfer for the receiver request by resetting the DMAR bit
in the UART CR3 register */
CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
/* At end of Rx process, restore huart->RxState to Ready */
huart->RxState = HAL_UART_STATE_READY;
}
#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 */
}
/* NOTE: This function should not be modified, when the callback is needed,
the HAL_UART_TxHalfCpltCallback can be implemented in the user file.
*/
}
/**
* @brief Rx Transfer completed callback.
* @param huart UART handle.
* @retval None
*/
__weak void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(huart);
/* NOTE : This function should not be modified, when the callback is needed,
the HAL_UART_RxCpltCallback can be implemented in the user file.
*/
}
以上是关于STM32CUBEMX生成的uart+DMA的一点阅读代码心得。
参考连接:
STM32之CubeL4(二)---USART + DMA + HAL_stm32l4 lpuart dma-CSDN博客