首页 > 其他分享 >stm32 使用多串口通信调试总结

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

时间:2023-04-11 19:11:29浏览次数:48  
标签:DMA HAL rx hdma stm32 Init 串口 GPIO 调试

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

标签:DMA,HAL,rx,hdma,stm32,Init,串口,GPIO,调试
From: https://www.cnblogs.com/dylancao/p/17307337.html

相关文章

  • vscode 使用浏览器调试
    launch.json{"version":"0.2.0","configurations":[{"type":"node","request":"launch","name":"node",......
  • Android Debug (调试)注解处理器
     1.addremotedebugconfiguration2.copyjvmoptions:(-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005),andpasteittogradle.propertiesfile.  3.thenclickdebugbuttontoattachlocalhost:5005,expandthegradletasklist......
  • Qt for Android QtQuick应用程序 USB连接手机调试运行错误:adb: failed to *.apk: No s
    1.场景Windows11、Qt6.5.0QtQuick应用程序USB连接手机调试运行。2.错误信息adb:failedto*.apk:NosuchfileordirectoryInstallingtodevicefailed!进程"C:\Users\Administrator\Qt\6.5.0\mingw_64\bin\androiddeployqt.exe"退出,退出代码16。安装应用失败,发生未知错......
  • 没有在线调试功能时,调试代码心得
    1、串口输出数据2、极端情况,没有额外串口时,可以把一个串口先当调试口用,先调试其他功能3、可以控制printf是否可以输出信息4、生成可执行文件时,生成一版带printf输出,一版不带printf输出,调试时两者交替用5、串口发送数据是否正常,接收处理数据是否正常6、串口通信必须保证一端功......
  • Alkaitu:STM32的IO模拟SPI
    #include"user_spi.h"#include"stm32f10x.h"#include"user_config.h"/*移植需改动六处*//***************************************************************//*挂在是SPI总线上的外设的个数和延迟时间,移植修改第一处*//**************************************......
  • C#编程之c#串口(winform、wpf)
    本文主要向大家介绍了C#编程之c#串口通信讲解(一)(winform、wpf),通过具体的内容向大家展示,希望对大家学习C#编程有所帮助。串口操作需要注意的几点如下:1、如果是USB转串口;则需要安装USB转串口驱动,附件有此驱动。2、串口打开状态最好不要直接插拔串口,可能会导致中控板或者串口线烧坏。......
  • 案例详解 | 4.3寸串口屏应用于两轮电动车仪表方案
    近年来,我国部分城市陆续开始改变对两轮车的高压态势,多座大型城市出台解禁令,为两轮车产业的回暖奠定了基础。两轮车因其机动灵活、通行效率高的特点,受到越来越多消费者的支持。经调研发现,消费者购车时除关注电池续航、安全性因素外,对于车辆的舒适性、外观的需求也进一步提升,83.9%的......
  • VS2013关闭调试而不关闭IIS Express
    在VS主面板打开:工具->选项->调试->编辑继续   取消选中[启用"编辑并继续"] 就OK了(英文版的请对应相应的操作)不过这是针对所有的调试,如果你想针对单个项目就还是保留VS的设置,直接去项目属性里设置在你的Web项目上右键->属性->Web 取消选中[启用"编辑并继续"] 就OK了......
  • C++-Ubuntu core dumped(核心已转储)-GDB调试
    C++-Ubuntucoredumped(核心已转储)-GDB调试Linux的可执行程序异常退出时,提示“核心已转储”。此时需要系统生成core文件,并通过GDB调试以确定问题。https://blog.csdn.net/scjdas/article/details/128585787设置系统生成core文件用ulimit-a查看corefilesize项是否......
  • 【 2023 】近期一些编译调试开发 Android7&9 系统的笔记( h616 / imx8m / rk3399 )
    主要就记录一下自己食用过程中遇到的一些问题吧,板子有新有旧,但都差不多。待整理呢。https://stackoverflow.com/questions/67363030/rebuild-android-code-with-error-ssl-error-when-connecting-to-the-jack-server-thttps://note.qidong.name/2017/07/disable-jack-server/......