硬汉嵌入式论坛

 找回密码
 立即注册
查看: 130|回复: 4
收起左侧

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

[复制链接]

1

主题

2

回帖

5

积分

新手上路

积分
5
发表于 5 天前 | 显示全部楼层 |阅读模式
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

USART2 TX直接接在了RX上。










10ebc053-ecce-41f0-8ab8-c576f4fc8c96.png
st.png
回复

使用道具 举报

1万

主题

7万

回帖

12万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
121537
QQ
发表于 5 天前 | 显示全部楼层
U5应该是没有DCache的,不需要操作这个SCB_InvalidateDCache_by_Addr
回复

使用道具 举报

1

主题

2

回帖

5

积分

新手上路

积分
5
 楼主| 发表于 5 天前 | 显示全部楼层
谢谢回复,屏蔽SCB_InvalidateDCache_by_Addr后现象仍然是一样的,有没有什么可能的方向去排查呢?
回复

使用道具 举报

1

主题

2

回帖

5

积分

新手上路

积分
5
 楼主| 发表于 5 天前 | 显示全部楼层
谢谢回复,可是我去掉之后结果还是以一样,有什么可能的方向去排查呢?
回复

使用道具 举报

1万

主题

7万

回帖

12万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
121537
QQ
发表于 4 天前 | 显示全部楼层
simonkoo 发表于 2026-3-9 12:30
谢谢回复,可是我去掉之后结果还是以一样,有什么可能的方向去排查呢?

CubeU5软件包里面有个UART DMA的例子,简单测试下,看看正常不。

还有就是处理姿势问题

使用函数HAL_UARTEx_ReceiveToIdle_DMA做超时接收整理:
1、半DMA传输完成中断UART_DMARxHalfCplt     调用  HAL_UARTEx_RxEventCallback,标识继续为HAL_UART_RECEPTION_TOIDLE
2、DMA传输完成中断UART_DMAReceiveCplt       调用   HAL_UARTEx_RxEventCallback,标识继续为HAL_UART_RECEPTION_TOIDLE
3、如果传输期间触发了空闲,DMA又没有传输完成,调用串口中断HAL_UART_IRQHandler,空闲标识处理的HAL_UARTEx_RxEventCallback,并设置HAL_UART_RECEPTION_STANDARD
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2026-3-14 08:45 , Processed in 0.303474 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表