你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

求助STM32 HAL库使用IRDA串口IDLE+DMA发送出现的问题

[复制链接]
深山夕照 提问时间:2020-12-8 17:47 /
最近在把标准库的项目移植到HAL库中,同时使用freeRTOS进行任务管理,HAL库属于初学。
硬件:STM32F103RCT6+IRDA
简介:使用SMT32F103RCT6+IRDA模块作为上位机与STM32F103C8T6+IRDA下位机通过modbus通讯
软件:STM32CUBEIDE开发工具和生成的软件,freeRTOS

问题概要:正常运行时,收到命令A的回复,对回复进行解析后,再发送命令B,会出现命令发送失败的情况,但是单步调试时,发送可以成功,添加延时函数还是不行。

还请论坛各位同仁帮忙看看,提一下意见,谢谢

相关代码如下:
  1. void HAL_IRDA_MspInit(IRDA_HandleTypeDef* irdaHandle)
  2. {

  3.   GPIO_InitTypeDef GPIO_InitStruct = {0};
  4.   if(irdaHandle->Instance==USART1)
  5.   {
  6.   /* USER CODE BEGIN USART1_MspInit 0 */
  7.   /* USER CODE END USART1_MspInit 0 */
  8.     /* USART1 clock enable */
  9.     __HAL_RCC_USART1_CLK_ENABLE();

  10.     __HAL_RCC_GPIOA_CLK_ENABLE();
  11.     /**USART1 GPIO Configuration
  12.     PA9     ------> USART1_TX
  13.     PA10     ------> USART1_RX
  14.     */
  15.     GPIO_InitStruct.Pin = GPIO_PIN_9;
  16.     GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  17.     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  18.     HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

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

  23.     /* USART1 DMA Init */
  24.     /* USART1_RX Init */
  25.     hdma_usart1_rx.Instance = DMA1_Channel5;
  26.     hdma_usart1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
  27.     hdma_usart1_rx.Init.PeriphInc = DMA_PINC_DISABLE;
  28.     hdma_usart1_rx.Init.MemInc = DMA_MINC_ENABLE;
  29.     hdma_usart1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
  30.     hdma_usart1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
  31.     hdma_usart1_rx.Init.Mode = DMA_NORMAL;
  32.     hdma_usart1_rx.Init.Priority = DMA_PRIORITY_MEDIUM;
  33.     if (HAL_DMA_Init(&hdma_usart1_rx) != HAL_OK)
  34.     {
  35.       Error_Handler();
  36.     }

  37.     __HAL_LINKDMA(irdaHandle,hdmarx,hdma_usart1_rx);

  38.     /* USART1_TX Init */
  39.     hdma_usart1_tx.Instance = DMA1_Channel4;
  40.     hdma_usart1_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
  41.     hdma_usart1_tx.Init.PeriphInc = DMA_PINC_DISABLE;
  42.     hdma_usart1_tx.Init.MemInc = DMA_MINC_ENABLE;
  43.     hdma_usart1_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
  44.     hdma_usart1_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
  45.     hdma_usart1_tx.Init.Mode = DMA_NORMAL;
  46.     hdma_usart1_tx.Init.Priority = DMA_PRIORITY_MEDIUM;
  47.     if (HAL_DMA_Init(&hdma_usart1_tx) != HAL_OK)
  48.     {
  49.       Error_Handler();
  50.     }

  51.     __HAL_LINKDMA(irdaHandle,hdmatx,hdma_usart1_tx);
  52.     /* USER CODE BEGIN USART1_MspInit 1 */
  53.     HAL_IRDA_Receive_DMA(irdaHandle, irda1_rx_buffer, IRDA_UART_RX_SIZE);        //使能DMA接受,将接受到的数据放到irda1_rx_buffer
  54.     /* USER CODE BEGIN USART1_MspInit 1 */

  55.     /* USART1 interrupt Init */
  56.     HAL_NVIC_SetPriority(USART1_IRQn, 5, 0);
  57.     HAL_NVIC_EnableIRQ(USART1_IRQn);

  58.   /* USER CODE BEGIN USART1_MspInit 1 */
  59.     __HAL_UART_ENABLE_IT(irdaHandle, IRDA_IT_IDLE);                                                   //usart1, 使能空闲中断
  60.                 __HAL_UART_CLEAR_IDLEFLAG(irdaHandle);
  61.   /* USER CODE END USART1_MspInit 1 */
  62.   }
复制代码
  1. void USART1_IRQHandler(void)
  2. {
  3.   /* USER CODE BEGIN USART1_IRQn 0 */
  4.         if (__HAL_UART_GET_FLAG(&hirda1, UART_FLAG_IDLE))
  5.         {
  6.                 __HAL_UART_CLEAR_IDLEFLAG(&hirda1);
  7.                 HAL_IRDA_DMAStop (&hirda1);

  8.                 irda1_data_cnt = IRDA_UART_RX_SIZE - __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);
  9.                 if (irda1_data_cnt < 6)
  10.                 {
  11.                         print_hex(irda1_rx_buffer, irda1_data_cnt);
  12.                 }
  13.                 else
  14.                 {
  15.                         BaseType_t xHigherPriorityTaskWoken = pdFALSE;
  16.                         xEventGroupSetBitsFromISR (irda_event_gourpHandler,
  17.                         EVENT_GROUP_BIT_IRDA1_DATA,
  18.                                                                                                                                  &xHigherPriorityTaskWoken);
  19.                 }

  20.                 hdma_usart1_rx.Instance->CNDTR = IRDA_UART_RX_SIZE;
  21.                 HAL_IRDA_Receive_DMA (&hirda1, irda1_rx_buffer, IRDA_UART_RX_SIZE);
  22.         }
  23.   /* USER CODE END USART1_IRQn 0 */
  24.   HAL_IRDA_IRQHandler(&hirda1);
  25.   /* USER CODE BEGIN USART1_IRQn 1 */

  26.   /* USER CODE END USART1_IRQn 1 */
  27. }
复制代码
  1. void irda_modbus_parse_task(void const *argument)
  2. {
  3.         irda_event_gourpHandler = xEventGroupCreate();

  4.         if(irda_event_gourpHandler == NULL)
  5.         {
  6.                 app_err("create irda_event_gourp fail!\r\n");
  7.                 goto error;
  8.         }

  9.         xEventGroupClearBits(irda_event_gourpHandler, EVENT_GROUP_BIT_IRDA1_DATA|EVENT_GROUP_BIT_IRDA2_DATA);

  10.         while(1)
  11.         {
  12.                 EventBits_t bits = xEventGroupWaitBits(irda_event_gourpHandler, EVENT_GROUP_BIT_IRDA1_DATA|EVENT_GROUP_BIT_IRDA2_DATA, pdFALSE, pdFALSE, portMAX_DELAY);

  13.                 if(bits & EVENT_GROUP_BIT_IRDA1_DATA)
  14.                 {
  15.                         app_debug("irda1 recv data\r\n");
  16.                         xEventGroupClearBits(irda_event_gourpHandler, EVENT_GROUP_BIT_IRDA1_DATA);
  17.                         Modbus_Master_Service(irda1_rx_buffer, irda1_data_cnt, 1);
  18.                         memset(irda1_rx_buffer, 0, sizeof(irda1_rx_buffer));
  19.                 }
  20.                 else if(bits & EVENT_GROUP_BIT_IRDA2_DATA)
  21.                 {
  22.                         app_debug("irda2 recv data\r\n");
  23.                         xEventGroupClearBits(irda_event_gourpHandler, EVENT_GROUP_BIT_IRDA2_DATA);
  24.                 }
  25.                 else
  26.                 {
  27.                         xEventGroupClearBits(irda_event_gourpHandler, ~(EVENT_GROUP_BIT_IRDA1_DATA|EVENT_GROUP_BIT_IRDA2_DATA));
  28.                         app_err("UNEXPECTED EVENT\r\n");
  29.                 }
  30.         }

  31.         error:
  32.         vEventGroupDelete(irda_event_gourpHandler);
  33.         osThreadTerminate (irda_modbus_parseTaskHandle);
  34. }
复制代码
  1. void Modbus_SendData(uint8_t *buf, int len, char direction)
  2. {
  3.         int res  = 0;

  4.          if(direction == 1)
  5.          {
  6.                  res = HAL_IRDA_Transmit_DMA(&hirda1, buf, len);
  7.                  if(res != 0)
  8.                  {
  9.                          app_err("uart1 error: %d\r\n", res);
  10.                  }
  11.          }
  12.          else if(direction == 2)
  13.          {
  14.                  HAL_IRDA_Transmit_DMA (&hirda2, buf, len);
  15.          }
  16.          else if(direction == 3)
  17.          {
  18.                  HAL_IRDA_Transmit_DMA (&hirda1, buf, len);
  19.                  HAL_IRDA_Transmit_DMA (&hirda2, buf, len);
  20.          }
  21. }
复制代码


收藏 评论2 发布时间:2020-12-8 17:47

举报

2个回答
深山夕照 回答时间:2020-12-8 17:48:59
现象就是正常运行,命令A发送成功,收到回复,在解析回复并执行发送命令B后,出现B发送失败情况,且单步调试发送时,反而是正常的可以发送成功的
深山夕照 回答时间:2020-12-8 18:10:59
暂时搞定了,正在琢磨为什么,解决方法就是在串口发送数据前后各加20ms左右延时

所属标签

相似问题

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版