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.针对数据量密集的情况,可能空闲中断不能及时相应,那么也不用担心,上面已经能把这种情况处理了。

 

posted @ 2024-03-26 11:23  njit-sam  阅读(17)  评论(0编辑  收藏  举报