You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

STM32WL HAL_UARTEx_RxEventCallback无法触发问题求助

问题:STM32WL搭配SIM800L时UART DMA空闲检测回调不触发

我用STM32WL搭配SIM800L模块做通信,之前遇到UART缓冲区接收问题,遂改用带空闲线检测的UART DMA方案。现在能看到HAL_UARTEx_ReceiveToIdle_DMA执行后RxBuf数据有变化,但始终触发不了HAL_UARTEx_RxEventCallback回调函数,无法定位原因。以下是我的代码及UART、DMA配置:


应用代码

#define RxBuf_SIZE   60
#define MainBuf_SIZE 120

uint8_t RxBuf[RxBuf_SIZE];
uint8_t MainBuf[MainBuf_SIZE];

void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
    if (huart->Instance == USART1)
    {
        oldPos = newPos;  // 复制新数据前更新上次位置
        /* 如果数据量较大,当前位置+新数据长度超过主缓冲区大小,就绕回缓冲区开头
         * 这是为了维护环形缓冲区,旧数据会被覆盖
         */
        if (oldPos+Size > MainBuf_SIZE)  // 当前位置+新数据长度超过主缓冲区
        {
            uint16_t datatocopy = MainBuf_SIZE-oldPos;  // 计算主缓冲区剩余空间
            memcpy ((uint8_t *)MainBuf+oldPos, RxBuf, datatocopy);  // 把数据复制到剩余空间

            oldPos = 0;  // 指向缓冲区开头
            memcpy ((uint8_t *)MainBuf, (uint8_t *)RxBuf+datatocopy, (Size-datatocopy));  // 复制剩余数据
            newPos = (Size-datatocopy);  // 更新当前位置
        }
        /* 如果当前位置+新数据长度小于主缓冲区大小
         * 直接复制数据并更新位置即可
         */
        else
        {
            memcpy ((uint8_t *)MainBuf+oldPos, RxBuf, Size);
            newPos = Size+oldPos;
        }
        /* 重新启动DMA接收 */
        HAL_UARTEx_ReceiveToIdle_DMA(&huart1, (uint8_t *) RxBuf, RxBuf_SIZE);
        __HAL_DMA_DISABLE_IT(&hdma_usart1_rx, DMA_IT_HT);
    }
    /****************** 在这里处理数据 *********************/

    /* 示例:检测接收数据中是否包含"OK"关键词 */
    for (int i=0; i<Size; i++)
    {
        if ((RxBuf[i] == 'O') && (RxBuf[i+1] == 'K'))
        {
            isOK = 1;
        }
    }
}

/* USER CODE BEGIN 2 */

  HAL_Delay(2000);
  sprintf(cmd,"AT\r\n");
  HAL_UART_Transmit(&huart1,(uint8_t *)cmd,strlen(cmd),1000);
  HAL_Delay(1000);
  HAL_UARTEx_ReceiveToIdle_DMA(&huart1, RxBuf, RxBuf_SIZE);
  __HAL_DMA_DISABLE_IT(&hdma_usart1_rx, DMA_IT_HT);


  sprintf(cmd,"AT+SAPBR=3,1,Contype,GPRS\r\n");
  HAL_UART_Transmit(&huart1,(uint8_t *)cmd,strlen(cmd),1000);


  /* USER CODE END 2 */

USART1初始化代码

static void MX_USART1_UART_Init(void)
{

  /* USER CODE BEGIN USART1_Init 0 */

  /* USER CODE END USART1_Init 0 */

  /* USER CODE BEGIN USART1_Init 1 */

  /* USER CODE END USART1_Init 1 */
  huart1.Instance = USART1;
  huart1.Init.BaudRate = 9600;
  huart1.Init.WordLength = UART_WORDLENGTH_8B;
  huart1.Init.StopBits = UART_STOPBITS_1;
  huart1.Init.Parity = UART_PARITY_NONE;
  huart1.Init.Mode = UART_MODE_TX_RX;
  huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart1.Init.OverSampling = UART_OVERSAMPLING_16;
  huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
  huart1.Init.ClockPrescaler = UART_PRESCALER_DIV1;
  huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
  if (HAL_UART_Init(&huart1) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_UARTEx_SetTxFifoThreshold(&huart1, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_UARTEx_SetRxFifoThreshold(&huart1, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_UARTEx_DisableFifoMode(&huart1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN USART1_Init 2 */

  /* USER CODE END USART1_Init 2 */

}

DMA初始化代码

static void MX_DMA_Init(void)
{

  /* DMA控制器时钟使能 */
  __HAL_RCC_DMAMUX1_CLK_ENABLE();
  __HAL_RCC_DMA1_CLK_ENABLE();

  /* DMA中断初始化 */
  /* DMA1_Channel1_IRQn中断配置 */
  HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);

}

内容的提问来源于stack exchange,提问作者Tryingtogetsome

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 09:59:53