STM32串口用DMA接收不定长数据
原文链接:https://blog.csdn.net/llq_the7/article/details/108649569
这篇博客的细思还是有缺点,先给出自己的方案。
仅针对大数据量,其余没有必要使用dma。
1. 解决不定长数据的处理,还是开启dma,并使用空闲中断。
在下面的中断函数里面
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size) { if(huart->Instance == USART1) { #if DMA_USE HAL_UARTEx_ReceiveToIdle_DMA(&huart1,Uart_ReadCache,RECEIVE_DEFAULT_LEN); #else HAL_UARTEx_ReceiveToIdle_IT(&huart1,Uart_ReadCache,RECEIVE_DEFAULT_LEN); #endif HAL_UART_Transmit_DMA(&huart1,Uart_ReadCache,Size); } }
这个函数会在两种情况下面被调用:1.接收到指定长度的报文;2:空闲中断
/** * @brief Receive an amount of data in DMA mode till either the expected number of data is received or an IDLE event occurs. * @note Reception is initiated by this function call. Further progress of reception is achieved thanks * to DMA services, transferring automatically received data elements in user reception buffer and * calling registered callbacks at half/end of reception. UART IDLE events are also used to consider * reception phase as ended. In all cases, callback execution will indicate number of received data elements. * @note When the UART parity is enabled (PCE = 1), the received data contain * the parity bit (MSB position). * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M = 01), * the received data is handled as a set of uint16_t. In this case, Size must indicate the number * of uint16_t available through pData. * @param huart UART handle. * @param pData Pointer to data buffer (uint8_t or uint16_t data elements). * @param Size Amount of data elements (uint8_t or uint16_t) to be received. * @retval HAL status */ HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
2.针对一帧数据特别长,超过设定的接受长度时,那么等接收到指定长度的时候,进中断,那么dma收到新数据可能会覆盖接收buffer前面的数据,
即使CPU处于中断状态,因此最好使用半中断,把之前里面的数据先拷走,就不怕被覆盖了。
__HAL_DMA_ENABLE_IT(&hdma_usart1_rx, DMA_IT_HT);
打开半满中断,中断函数处理这里省略,自行百度完善。
3.针对数据量密集的情况,可能空闲中断不能及时相应,那么也不用担心,上面已经能把这种情况处理了。