串口DMA空闲接收

第一步、在串口初始化过程中手动添加:

if(uartHandle->Instance==USART1)
  {
  /* USER CODE BEGIN USART1_MspInit 0 */
        MX_DMA_Init();
  /* USER CODE END USART1_MspInit 0 */
    /* USART1 clock enable */
    __HAL_RCC_USART1_CLK_ENABLE();
 
    __HAL_RCC_GPIOA_CLK_ENABLE();
    /**USART1 GPIO Configuration    
    PA9     ------> USART1_TX
    PA10     ------> USART1_RX
    */
    GPIO_InitStruct.Pin = GPIO_PIN_9;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    GPIO_InitStruct.Pin = GPIO_PIN_10;
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    /* USART1 DMA Init */
    /* USART1_RX Init */
    hdma_usart1_rx.Instance = DMA1_Channel5;
    hdma_usart1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
    hdma_usart1_rx.Init.PeriphInc = DMA_PINC_DISABLE;
    hdma_usart1_rx.Init.MemInc = DMA_MINC_ENABLE;
    hdma_usart1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
    hdma_usart1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
    hdma_usart1_rx.Init.Mode = DMA_CIRCULAR;
    hdma_usart1_rx.Init.Priority = DMA_PRIORITY_LOW;
    if (HAL_DMA_Init(&hdma_usart1_rx) != HAL_OK)
    {
      Error_Handler();
    }

    __HAL_LINKDMA(uartHandle,hdmarx,hdma_usart1_rx);

    /* USART1 interrupt Init */
    HAL_NVIC_SetPriority(USART1_IRQn, 5, 0);
    HAL_NVIC_EnableIRQ(USART1_IRQn);
  /* USER CODE BEGIN USART1_MspInit 1 */
        __HAL_UART_ENABLE_IT(&huart1,UART_IT_IDLE);
  /* USER CODE END USART1_MspInit 1 */
  }

第二步、在main函数中添加:

  /* USER CODE BEGIN 2 */

  HAL_UART_Receive_DMA(&huart1,RxBuf,UARTRXBUFFSIZE);

 /* USER CODE END 2 */

第三步、在串口中断函数添加:

void USART1_IRQHandler(void)
{
  /* USER CODE BEGIN USART1_IRQn 0 */
    #if            Custom_Uart==true    //定义宏   Custom_Uart  

     Custom_UartDMAHandler(&huart1,&hdma_usart1_rx);
    #else

  /* USER CODE END USART1_IRQn 0 */
  HAL_UART_IRQHandler(&huart1);
  /* USER CODE BEGIN USART1_IRQn 1 */
    #endif
  /* USER CODE END USART1_IRQn 1 */
}

第四步、串口空闲接收自定义函数:

      

void Custom_UartDMAHandler(UART_HandleTypeDef *huart,DMA_HandleTypeDef *hdma_rx)
{
    //数据接收完成
    if((__HAL_UART_GET_FLAG(huart,UART_FLAG_IDLE)!=RESET)) //进入空闲中断
    { 
        HAL_UART_AbortReceive(huart);

        if(huart->Instance==USART1){
            huart->RxXferCount= UARTRXBUFFSIZE - __HAL_DMA_GET_COUNTER(hdma_rx);
            osMessageQueuePut(DEBUGHandle,RxBuf,NULL,0);//发送消息至线程
            HAL_UART_Receive_DMA(huart,RxBuf,UARTRXBUFFSIZE);//重新打开DMA接收  
         }
    }
}



已邀请:

uouo00 - 80后精辟

赞同来自:

搜狗截图20191111141035.png

要回复问题请先登录注册