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

STM32u575 USART 用GPDMA接收,DMA中断,usart 中断正常来,ROR数据正确,接收缓冲却不变

[复制链接]
simonlkoo 提问时间:2026-3-8 20:15 / 未解决
main代码:while (1) {    /* First transmit data, then start DMA receive */
    if (loop_TX < 0xFF) {
      loop_TX++;
      HAL_UART_Transmit(&huart2, &loop_TX, 1, 100);
      HAL_Delay(100);
      /* Start DMA receive with IDLE detection */
      HAL_UARTEx_ReceiveToIdle_DMA(&huart2, &loop_RX, 1);
      /* Wait for DMA transfer to complete */
      HAL_Delay(100);
      /* Flush cache to ensure DMA data is visible to CPU */
      SCB_InvalidateDCache_by_Addr(&loop_RX, sizeof(loop_RX));
      printf("[MAIN] TX: %02X, RX: %02X\r\n", loop_TX, loop_RX);
    }
  }
void GPDMA1_Channel0_IRQHandler(void)
{
  /* USER CODE BEGIN GPDMA1_Channel0_IRQn 0 */
  printf("[GPDMA1_Channel0] DMA done, CNDTR=%u, CSAR=0x%08lX, CDAR=0x%08lX, CTR1=0x%08lX\r\n",
         __HAL_DMA_GET_COUNTER(&handle_GPDMA1_Channel0),
         handle_GPDMA1_Channel0.Instance->CSAR,
         handle_GPDMA1_Channel0.Instance->CDAR,
         handle_GPDMA1_Channel0.Instance->CTR1);
  /* USER CODE END GPDMA1_Channel0_IRQn 0 */
  HAL_DMA_IRQHandler(&handle_GPDMA1_Channel0);
  /* USER CODE BEGIN GPDMA1_Channel0_IRQn 1 */

  /* USER CODE END GPDMA1_Channel0_IRQn 1 */
}
void USART2_IRQHandler(void)
{
  /* USER CODE BEGIN USART2_IRQn 0 */
  if (__HAL_UART_GET_FLAG(&huart2, UART_FLAG_IDLE)) {

    __HAL_UART_CLEAR_IDLEFLAG(&huart2);

    uint16_t dma_cntr = __HAL_DMA_GET_COUNTER(huart2.hdmarx);

    /* Flush cache to ensure DMA data is visible to CPU */
    SCB_InvalidateDCache_by_Addr(&loop_RX, sizeof(loop_RX));

    printf("[USART2] IDLE, DMA CNDTR=%u, RX=%02X, RDR=%02X\r\n",
           dma_cntr, loop_RX, huart2.Instance->RDR);
  }
  /* USER CODE END USART2_IRQn 0 */
  HAL_UART_IRQHandler(&huart2);
  /* USER CODE BEGIN USART2_IRQn 1 */
  /* USER CODE END USART2_IRQn 1 */
}
打印信息看DMA中断进去了,IDLE中断进去了,ROR是正确的,loop_RX却维持初始化的值。
[MAIN] loop_RX addr=0x20000029[GPDMA1_Channel0] DMA done, CNDTR=0, CSAR=0x40004424, CDAR=0x20000029, CTR1=0x00000000[MAIN] TX: B4, RX: 0F[USART2] IDLE, DMA CNDTR=0, RX=0F, RDR=B5[MAIN] loop_RX addr=0x20000029[GPDMA1_Channel0] DMA done, CNDTR=0, CSAR=0x40004424, CDAR=0x20000029, CTR1=0x00000000[MAIN] TX: B5, RX: 0F[USART2] IDLE, DMA CNDTR=0, RX=0F, RDR=B6[MAIN] loop_RX addr=0x20000029[GPDMA1_Channel0] DMA done, CNDTR=0, CSAR=0x40004424, CDAR=0x20000029, CTR1=0x00000000









st.png
收藏 评论2 发布时间:2026-3-8 20:15

举报

2个回答
simonlkoo 回答时间:昨天 20:19
补充中断优先级
10ebc053-ecce-41f0-8ab8-c576f4fc8c96.png
xmshao 回答时间:4 分钟前

你目前UART2是自发自收吗?

while (1) {    / First transmit data, then start DMA receive /     if (loop_TX < 0xFF) {       loop_TX++;       HAL_UART_Transmit(&huart2, &loop_TX, 1, 100);       HAL_Delay(100);       / Start DMA receive with IDLE detection /       HAL_UARTEx_ReceiveToIdle_DMA(&huart2, &loop_RX, 1);       / Wait for DMA transfer to complete /    HAL_Delay(100);       / Flush cache to ensure DMA data is visible to CPU /       SCB_InvalidateDCache_by_Addr(&loop_RX, sizeof(loop_RX));       printf("[MAIN] TX: %02X, RX: %02X\r\n", loop_TX, loop_RX);     }

感觉又不像,你发生完100ms后才去开启基于UART2的接收。

你基于空闲中断做UART的DMA接收,接收长度才1个,意义何在?如何使用空闲事件?

一般来讲基于空闲事件做UART接收的话,接收数据长度相对设置比较长,以空闲事件表征当前数据接收完毕。在空闲中断里读取接收到的数据。

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版