最新要闻

广告

手机

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

家电

看热讯:stm32 使用多串口通信调试总结

来源:博客园


(资料图)

前记:stm32使用多个串口通信,这个项目遇到了不少问题,值得反思和深入总结一下。提纲:这次的问题,主要有几个部分组成:A 多串口的DMA配置,这个需要注意,尽量不要使用同一个DMA通道,这个高速的接收数据的时候会出问题。B 串口的tx和rx配置一定要检查好,不要被复用了。这个是经常遇到的坑。C 串口的接收完成中断里面尽量少做事情。源码解析:这里面注意几个细节:一个是串口中断的设置,如源码所示:
/**  * @brief This function handles DMA1 channel6 global interrupt.  */void DMA1_Channel6_IRQHandler(void){  /* USER CODE BEGIN DMA1_Channel6_IRQn 0 */  /* USER CODE END DMA1_Channel6_IRQn 0 */  HAL_DMA_IRQHandler(&hdma_usart2_rx);  /* USER CODE BEGIN DMA1_Channel6_IRQn 1 */  /* USER CODE END DMA1_Channel6_IRQn 1 */}/**  * @brief This function handles DMA1 channel6 global interrupt.  */void DMA1_Channel3_IRQHandler(void){  /* USER CODE BEGIN DMA1_Channel6_IRQn 0 */  /* USER CODE END DMA1_Channel6_IRQn 0 */  HAL_DMA_IRQHandler(&hdma_usart3_rx);  /* USER CODE BEGIN DMA1_Channel6_IRQn 1 */  /* USER CODE END DMA1_Channel6_IRQn 1 */}

另外一个是串口的配置,如下所示:

void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle){  GPIO_InitTypeDef GPIO_InitStruct = {0};  RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};  if(uartHandle->Instance==USART2)  {  /* USER CODE BEGIN USART2_MspInit 0 */  /* USER CODE END USART2_MspInit 0 */  /** Initializes the peripherals clock  */    PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART2;    PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1;    if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)    {      Error_Handler();    }    /* USART2 clock enable */    __HAL_RCC_USART2_CLK_ENABLE();    __HAL_RCC_GPIOA_CLK_ENABLE();    /**USART2 GPIO Configuration    PA2     ------> USART2_TX    PA3     ------> USART2_RX    */    GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_3;    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;    GPIO_InitStruct.Pull = GPIO_NOPULL;    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;    GPIO_InitStruct.Alternate = GPIO_AF7_USART2;    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);    /* USART2 DMA Init */    /* USART2_RX Init */    hdma_usart2_rx.Instance = DMA1_Channel6;    hdma_usart2_rx.Init.Request = DMA_REQUEST_2;    hdma_usart2_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;    hdma_usart2_rx.Init.PeriphInc = DMA_PINC_DISABLE;    hdma_usart2_rx.Init.MemInc = DMA_MINC_ENABLE;    hdma_usart2_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;    hdma_usart2_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;    hdma_usart2_rx.Init.Mode = DMA_NORMAL;    hdma_usart2_rx.Init.Priority = DMA_PRIORITY_LOW;    if (HAL_DMA_Init(&hdma_usart2_rx) != HAL_OK)    {      Error_Handler();    }    __HAL_LINKDMA(uartHandle,hdmarx,hdma_usart2_rx);    /* USART2 interrupt Init */    HAL_NVIC_SetPriority(USART2_IRQn, 8, 0);    HAL_NVIC_EnableIRQ(USART2_IRQn);  /* USER CODE BEGIN USART2_MspInit 1 */     __HAL_UART_CLEAR_IDLEFLAG(&huart2);     HAL_UART_Receive_DMA(&huart2, SENSOR_RX_BUFF, GPS_RX_BUFF_SIZE);     __HAL_UART_ENABLE_IT(&huart2,UART_IT_IDLE);  /* USER CODE END USART2_MspInit 1 */  }  else if(uartHandle->Instance==USART3)  {  /* USER CODE BEGIN USART2_MspInit 0 */  /* USER CODE END USART2_MspInit 0 */  /** Initializes the peripherals clock  */    PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART3;    PeriphClkInit.Usart3ClockSelection = RCC_USART3CLKSOURCE_PCLK1;    if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)    {      Error_Handler();    }    /* USART2 clock enable */    __HAL_RCC_USART3_CLK_ENABLE();    __HAL_RCC_GPIOB_CLK_ENABLE();    /**USART2 GPIO Configuration    PB10     ------> USART3_TX    PB11     ------> USART3_RX    */    GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_11;    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;    GPIO_InitStruct.Pull = GPIO_NOPULL;    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;    GPIO_InitStruct.Alternate = GPIO_AF7_USART3;    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);    /* USART2 DMA Init */    /* USART2_RX Init */    hdma_usart3_rx.Instance = DMA1_Channel3;    hdma_usart3_rx.Init.Request = DMA_REQUEST_2;    hdma_usart3_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;    hdma_usart3_rx.Init.PeriphInc = DMA_PINC_DISABLE;    hdma_usart3_rx.Init.MemInc = DMA_MINC_ENABLE;    hdma_usart3_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;    hdma_usart3_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;    hdma_usart3_rx.Init.Mode = DMA_NORMAL;    hdma_usart3_rx.Init.Priority = DMA_PRIORITY_LOW;    if (HAL_DMA_Init(&hdma_usart3_rx) != HAL_OK)    {      Error_Handler();    }    __HAL_LINKDMA(uartHandle,hdmarx,hdma_usart3_rx);    /* USART2 interrupt Init */    HAL_NVIC_SetPriority(USART3_IRQn, 8, 0);    HAL_NVIC_EnableIRQ(USART3_IRQn);    // /* USER CODE BEGIN USART2_MspInit 1 */    __HAL_UART_CLEAR_IDLEFLAG(&huart3);    HAL_UART_Receive_DMA(&huart3, GPS_RX_BUFF, GPS_RX_BUFF_SIZE);    __HAL_UART_ENABLE_IT(&huart3,UART_IT_IDLE);    /* USER CODE END USART2_MspInit 1 */  }  else if(uartHandle->Instance==USART1)  {  /* USER CODE BEGIN USART2_MspInit 0 */  /* USER CODE END USART2_MspInit 0 */  /** Initializes the peripherals clock  */    PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART1;    PeriphClkInit.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK2;    if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)    {      Error_Handler();    }    /* USART1 clock enable */    __HAL_RCC_USART1_CLK_ENABLE();    __HAL_RCC_GPIOA_CLK_ENABLE();    /**USART2 GPIO Configuration    PA9     ------> USART1_TX    PA10     ------> USART1_RX    */    GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_9;    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;    GPIO_InitStruct.Pull = GPIO_PULLUP;    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;    GPIO_InitStruct.Alternate = GPIO_AF7_USART3;    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);    // /* USART2 DMA Init */    // /* USART2_RX Init */    // hdma_usart1_rx.Instance = DMA1_Channel6;    // hdma_usart1_rx.Init.Request = DMA_REQUEST_2;    // 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_NORMAL;    // 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);    /* USART2 interrupt Init */    HAL_NVIC_SetPriority(USART1_IRQn, 8, 0);    HAL_NVIC_EnableIRQ(USART1_IRQn);  /* USER CODE BEGIN USART2_MspInit 1 */  /* USER CODE END USART2_MspInit 1 */  }}
总结:这个是三个串口正常工作的版本,有一个串口不需要接受数据,就把接收毙掉了。目前三个串口有好的同时工作。

关键词: