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

STM32L010F4 UART DMA接收IRQ未触发问题求助

STM32L010F4 UART DMA接收失效排查

我基于STM32L010F4开发项目,需通过UART接收6字节数据。中断模式工作正常,但切换为DMA模式后完全失效:IRQ未触发,回调函数也未被调用。已按要求先初始化DMA再初始化外设,依旧无任何反应。请问遗漏了哪些配置?

相关代码如下:

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_DMA_Init(void);
static void MX_USART2_UART_Init(void);

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */
uint8_t RX_Data[6] = {6};
  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* Configure the system clock */
  SystemClock_Config();

  /* Initialize all configured peripherals */
  MX_DMA_Init();
  MX_GPIO_Init();
  MX_USART2_UART_Init();

  uint8_t Result = HAL_UART_Receive_DMA(&huart2, RX_Data, 6);

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
      //uint8_t Result = HAL_UART_Receive_DMA(&huart2, RX_Data, 6);
      //uint8_t Result = HAL_UART_Receive_IT(&huart2, RX_Data, 6);

      if( Result == HAL_OK )
      {
          HAL_Delay(20);
      }
  }
}


void HAL_UART_RxCpltCallback (UART_HandleTypeDef *huart)
{
    HAL_Delay(20);
}


/**
  * @brief USART2 Initialization Function
  * @param None
  * @retval None
  */
static void MX_USART2_UART_Init(void)
{
    huart2.Instance = USART2;
    huart2.Init.BaudRate = 57600;
    huart2.Init.WordLength = UART_WORDLENGTH_8B;
    huart2.Init.StopBits = UART_STOPBITS_1;
    huart2.Init.Parity = UART_PARITY_NONE;
    huart2.Init.Mode = UART_MODE_TX_RX;
    huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
    huart2.Init.OverSampling = UART_OVERSAMPLING_16;
    huart2.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
    huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
    if (HAL_UART_Init(&huart2) != HAL_OK)
    {
      Error_Handler();
    } 
}

/**
  * Enable DMA controller clock
  */
static void MX_DMA_Init(void)
{

  /* DMA controller clock enable */
  __HAL_RCC_DMA1_CLK_ENABLE();

  /* DMA interrupt init */
  /* DMA1_Channel2_3_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMA1_Channel2_3_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(DMA1_Channel2_3_IRQn);

}

/**
 * @brief UART MSP Initialization
 * This function configures the hardware resources used in this example
 * @param huart: UART handle pointer
 * @retval None
 */
void HAL_UART_MspInit(UART_HandleTypeDef* huart)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  if(huart->Instance==USART2)
  {
    /* Peripheral clock enable */
    __HAL_RCC_USART2_CLK_ENABLE();

    __HAL_RCC_GPIOA_CLK_ENABLE();
    /**USART2 GPIO Configuration
    PA0-CK_IN     ------> USART2_RX
    PA2     ------> USART2_TX
    */
    GPIO_InitStruct.Pin = GPIO_PIN_0;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF0_USART2;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    GPIO_InitStruct.Pin = GPIO_PIN_2;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF4_USART2;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    /* USART2 DMA Init */
    /* USART2_RX Init */
    hdma_usart2_rx.Instance = DMA1_Channel3;
    hdma_usart2_rx.Init.Request = DMA_REQUEST_4;
    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(huart,hdmarx,hdma_usart2_rx);

    /* USART2_TX Init */
    hdma_usart2_tx.Instance = DMA1_Channel2;
    hdma_usart2_tx.Init.Request = DMA_REQUEST_4;
    hdma_usart2_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
    hdma_usart2_tx.Init.PeriphInc = DMA_PINC_DISABLE;
    hdma_usart2_tx.Init.MemInc = DMA_MINC_ENABLE;
    hdma_usart2_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
    hdma_usart2_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
    hdma_usart2_tx.Init.Mode = DMA_NORMAL;
    hdma_usart2_tx.Init.Priority = DMA_PRIORITY_LOW;
    if (HAL_DMA_Init(&hdma_usart2_tx) != HAL_OK)
    {
       Error_Handler();
    }

    __HAL_LINKDMA(huart,hdmatx,hdma_usart2_tx);

    /* USART2 interrupt Init */
    HAL_NVIC_SetPriority(USART2_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(USART2_IRQn);
  }

 }

遗漏的配置点及修复方案

  • RX引脚GPIO配置错误
    USART2_RX对应的PA0被配置为GPIO_MODE_AF_PP(复用推挽输出),但RX是输入引脚,应改为GPIO_MODE_AF_INPUT,同时建议开启上拉(GPIO_PULLUP)以避免电平不稳定导致接收失败。修改后的PA0配置代码:

    GPIO_InitStruct.Pin = GPIO_PIN_0;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_INPUT;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF0_USART2;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
    
  • DMA传输完成中断未显式开启
    虽然已开启DMA1_Channel2_3_IRQn的NVIC中断,但需确保DMA通道本身的传输完成中断被使能。在HAL_DMA_Init(&hdma_usart2_rx)之后添加:

    __HAL_DMA_ENABLE_IT(&hdma_usart2_rx, DMA_IT_TC);
    

    这样DMA在接收完成后才会触发中断,进而调用回调函数。

  • DMA请求映射需确认匹配
    核对STM32L010F4参考手册,确认USART2_RX对应的DMA请求号是否为DMA_REQUEST_4。如果请求号不匹配,DMA无法响应UART的接收触发信号,需修改hdma_usart2_rx.Init.Request为正确值。

  • DMA_NORMAL模式下需重新启动接收(可选,针对连续接收)
    当前使用DMA_NORMAL模式,单次传输完成后DMA会自动停止。如果需要持续接收数据,需在HAL_UART_RxCpltCallback中重新启动DMA接收:

    void HAL_UART_RxCpltCallback (UART_HandleTypeDef *huart)
    {
        if(huart->Instance == USART2)
        {
            // 处理接收到的数据
            HAL_UART_Receive_DMA(&huart2, RX_Data, 6); // 重启DMA接收
        }
    }
    
  • 确认USART DMA接收使能
    虽然HAL_UART_Receive_DMA会自动设置USART_CR3寄存器的DMAR位,但可手动添加确认代码,在调用HAL_UART_Receive_DMA前执行:

    __HAL_UART_ENABLE_DMA(&huart2, UART_DMA_RX);
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 14:05:04