loading

stm32 使用多串口通信调试总结

  • Home
  • Blog
  • stm32 使用多串口通信调试总结

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 */

}

}

总结:

这个是三个串口正常工作的版本,有一个串口不需要接受数据,就把接收毙掉了。目前三个串口有好的同时工作。