前记:
  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 */
}
}
总结:
这个是三个串口正常工作的版本,有一个串口不需要接受数据,就把接收毙掉了。目前三个串口有好的同时工作。

stm32 使用多串口通信调试总结的更多相关文章

  1. stm32中的串口通信你了解多少

    在基础实验成功的基础上,对串口的调试方法进行实践.硬件代码顺利完成之后,对日后调试需要用到的printf重定义进行调试,固定在自己的库函数中. b) 初始化函数定义: void USART_Confi ...

  2. 记一次串口通信调试,慎用SerialPort.Close

    做项目是遇到了串口通信,真是遇到了一个大坑,不知道是微软的坑还是我的坑. 让我慢慢道来完整的经历. 项目中以前是vb 写的,是vb与vb 之间进行串口通信,现在改成C#和之前的vb程序进行串口通信. ...

  3. 嵌入式02 STM32 实验07 串口通信

    STM32串口通信(F1系列包含3个USART和2个UART) 一.单片机与PC机串行通信研究目的和意义: 单片机自诞生以来以其性能稳定,价格低廉.功能强大.在智能仪器.工业装备以及日用电子消费产品中 ...

  4. pandaboard串口通信调试

    1.在PC上的pyserial程序,到pandaboard后报错,读取和写入会报错 2.使用的是pandaboard的ttyO2串口 3.ls -l /dev/ttyO2,发现是tty,而不是dial ...

  5. stm32 hal库串口通信资料汇集

    串口的发送接收函数:HAL_UART_Transmit();串口轮询模式发送,使用超时管理机制.HAL_UART_Receive();串口轮询模式发送,使用超时管理机制.HAL_UART_Transm ...

  6. stm32开发之串口的调试

    总的函数如下 void USART1Configuration(void){    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Peri ...

  7. 嵌入式驱动开发之spi---spi串口通信调试

    一. 概念 SPI是 Serial Peripheral Interface(串型外部接口)的缩写.SPI接口有4根PIN脚,分别是:          * SPICLK     : 用于传输数据的同 ...

  8. stm32与三菱PLC通信

    一.三菱PLC通讯概要   三菱PLC FX系列通信结构如下图所示: 三菱PLC FX系列的通信规格如下图所示: 三菱PLC FX系列一般有以下几种通信模块,以FX2N为例: FX2N-232-BD ...

  9. STM32学习笔记:【004】USART串口通信

    版本:STM32F429 Hal库v1.10 串口通信能够实现两块电路之间不同的通信,在开发中作为打印调试也是一门利器(printf重定向). 补充一点小知识: 1. weak修饰符修饰的函数,说明这 ...

  10. stm32学习笔记之串口通信

    在基础实验成功的基础上,对串口的调试方法进行实践.硬件代码顺利完成之后,对日后调试需要用到的printf重定义进行调试,固定在自己的库函数中. b) 初始化函数定义: void USART_Confi ...

随机推荐

  1. CentOS7设置防火墙

    ①查看防火状态 systemctl status firewalld service iptables status ②暂时关闭防火墙 systemctl stop firewalld service ...

  2. Delphi中的注释,仅此一篇

    在Pascal中,注释括在大括号中或带星号的圆括号中.Delphi 也认可C++ 风格的注释,即把注释放在双斜线后.例如: {this is a comment} (* this is another ...

  3. 一个让java程序员有杀人的冲动的Xerces冲突问题

    History Xerces是Java生态圈使用最广泛的XML解析器,基本上所有的类库和框架都会在一定程度上使用它(即使没有直接引用,也有可能间接引用) Xerces在官网中发布的包是没有标注版本的, ...

  4. test-02-java 单元测试框架 junit5 入门介绍

    拓展阅读 junit5 系列 基于 junit5 实现 junitperf 源码分析 Auto generate mock data for java test.(便于 Java 测试自动生成对象信息 ...

  5. Ubuntu下SSH管理及SFTP下载工具Muon(Snowflake)

    简介 Muon其实更像是一个基于ssh的服务器管理工具, 界面中有PAC Manager的影子, 集成了文件管理, ssh命令行, 服务器性能监测和工具包等功能. 因为这个工具的编写语言是Java, ...

  6. 【Unity3D】固定管线着色器二

    1 前言 ​ 固定管线着色器一 中介绍了 Shader 中外部属性.光照.贴图等基础用法,本文将进一步讲解固定管线着色器,介绍正面与反面剔除.Alpha 测试.深度测试.混合.渲染队列等用法.渲染管线 ...

  7. js中返回今天是星期几的方法

    var weeks=["星期日","星期一","星期二","星期三","星期四","星期五 ...

  8. Idea:Fetch failed: fatal: Could not read from remote repository

    今天在idea工具中fetch github仓库报错:Fetch failed: fatal: Could not read from remote repository 查了以下需要调整下setti ...

  9. win32 - 使用GDI+从资源中获取图像并加载

    很多时候我们习惯使用GDI+中Image类来加载本地文件,但是有时候我们需要资源中从加载png格式的图片时,却无法使用该类. 我们可以使用FindResource,LoadResource和LockR ...

  10. uber-go guide,uber的go编码规范

    uber-go guide,uber的go语言编码规范 感谢翻译者和原作们 本文转自:https://github.com/xxjwxc/uber_go_guide_cn (特此感谢作者的翻译,感谢他 ...