[STM32U5] STM32U575板子DMA的问题

[复制链接]
229|54
xch 发表于 2026-6-17 17:11 | 显示全部楼层
Tom952331 发表于 2026-6-17 17:03
还是不行,我都快放弃了。

你是不是还保留一些残留的代码没去掉?
xch 发表于 2026-6-17 17:16 | 显示全部楼层
用它复位GPDMA1: RCC_AHB1RSTR_GPDMA1RST。
还有 RCC_AHB1ENR_GPDMA1EN 置一没?

另外单步跟踪一下代码,看看GPDMA1 寄存器值是否正常。
调用后状态位有啥异常。CBR1值有没有减少
 楼主| Tom952331 发表于 2026-6-17 18:04 | 显示全部楼层
xch 发表于 2026-6-17 17:16
用它复位GPDMA1: RCC_AHB1RSTR_GPDMA1RST。
还有 RCC_AHB1ENR_GPDMA1EN 置一没?

我的程序改成这样了:

  1. typedef struct{

  2.   uint32_t BR1; //数据量

  3.   uint32_t DAR; //填充仅需要更新目标地址

  4.   uint32_t DSR; //填充仅需要更新目标地址

  5.   uint32_t LLR; //数据链

  6. }tDMA_LLS;

  7. #define DMA_MEM_CH              GPDMA1_Channel0

  8. #define DMA_MEM_LLS_CH              GPDMA1_Channel0


  9. //tDMA_LLS DMA_MEM_LLS[MAX_LLS_ARRAY_NUM] __@0x20000000 ;
  10. tDMA_LLS DMA_MEM_LLS[MAX_LLS_ARRAY_NUM];
  11. /****************************************

  12. 填充一片区域,超出65535需要使用动态链表

  13. size 是 uint32_t 的数量,按照字节数计算一个传输链

  14. 不得超出16383*4 字节

  15. ***********************************************/

  16. static void DMA_LLS_Config ( tDMA_LLS *plls,uint32_t bytes,uint32_t dar, uint32_t sar, uint32_t lls)

  17. {

  18.   uint8_t max = (bytes +MAXIUM_DMA_BLOCK_SIZE-1)/MAXIUM_DMA_BLOCK_SIZE-1;

  19.   uint8_t i =0;

  20.   for (;i<max;i++){

  21.     plls[i].DAR = dar +i*(MAXIUM_DMA_BLOCK_SIZE);

  22.     //plls[i].SAR = sar +i*(MAXIUM_DMA_BLOCK_SIZE);
  23.                 plls[i].DSR = sar +i*(MAXIUM_DMA_BLOCK_SIZE);

  24.     plls[i].BR1 = MAXIUM_DMA_BLOCK_SIZE;   //当前传输数量

  25.     plls[i].LLR = lls|(uint16_t)(uint64_t)&plls[i+1];//指向下一个链表的低16位

  26.   }

  27.   plls[i].DAR = dar +i*(MAXIUM_DMA_BLOCK_SIZE); //新内存地址

  28.   plls[i].DSR = sar +i*(MAXIUM_DMA_BLOCK_SIZE); //新内存地址

  29.   plls[i].BR1 = bytes % MAXIUM_DMA_BLOCK_SIZE; //剩余数据量

  30.   plls[i].LLR = 0;  //表示链表结束

  31. }

  32. void DmaCopyHalfWordBlock (uint32_t bytes, uint16_t * dst ,uint16_t *src)

  33. {

  34.   

  35.   DMA_MEM_CH->CTR1 = DMA_CTR1_SAP|DMA_CTR1_DINC|DMA_CTR1_SINC|\

  36.     (DMA_DEST_DATAWIDTH_HALFWORD)|(DMA_DEST_DATAWIDTH_HALFWORD);

  37.   DMA_MEM_CH ->CTR2 = DMA_REQUEST_SW|DMA_BREQ_BLOCK|DMA_TCEM_EACH_LL_ITEM_TRANSFER;    //使用软件 DMA请求

  38.   DMA_MEM_CH ->CSAR = (uint32_t)(uint64_t)src;

  39.   DMA_MEM_CH ->CDAR = (uint32_t)(uint64_t)dst;



  40.   if( bytes <=MAXIUM_DMA_BLOCK_SIZE ){

  41.     DMA_MEM_CH ->CBR1 = bytes ;

  42.   }

  43.   else{

  44.     DMA_MEM_CH ->CBR1 = MAXIUM_DMA_BLOCK_SIZE;

  45.     uint32_t lls = DMA_CLLR_UB1|DMA_CLLR_UDA|DMA_CLLR_USA|DMA_CLLR_ULL;

  46.     uint32_t base = (uint32_t )(uint64_t)DMA_MEM_LLS;

  47.     DMA_MEM_CH ->CLLR = lls|(uint16_t)base;

  48.     DMA_MEM_CH ->CLBAR = (uint32_t)base&0xffff0000; //MSB,LLS BASE

  49.     DMA_LLS_Config ( DMA_MEM_LLS,\

  50.       bytes - MAXIUM_DMA_BLOCK_SIZE,\

  51.         (uint32_t)(uint64_t)dst+MAXIUM_DMA_BLOCK_SIZE,  (uint32_t)(uint64_t)src+MAXIUM_DMA_BLOCK_SIZE,lls);

  52.   }

  53.   //启动传输

  54.   DMA_MEM_CH ->CCR  = DMA_CCR_EN;

  55. }


  56. /**
  57.   * [url=/u/brief]@brief[/url]  The application entry point.
  58.   * @retval int
  59.   */
  60. int main(void)
  61. {

  62.   /* USER CODE BEGIN 1 */
  63.   /* STM32U5xx HAL library initialization:
  64.        - Configure the Flash prefetch
  65.        - Configure the Systick to generate an interrupt each 1 msec
  66.        - Set NVIC Group Priority to 3
  67.        - Low Level Initialization
  68.      */
  69.   /* USER CODE END 1 */

  70.   /* MCU Configuration--------------------------------------------------------*/

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

  73.   /* USER CODE BEGIN Init */

  74.   /* USER CODE END Init */

  75.   /* Configure the System Power */
  76.   SystemPower_Config();

  77.   /* Configure the system clock */
  78.   SystemClock_Config();
  79.         __HAL_RCC_GPDMA1_CLK_ENABLE();
  80.         //RCC_AHB1ENR_GPDMA1EN
  81.         RCC_AHB1RSTR_GPDMA1RST;
  82.   /* USER CODE BEGIN SysInit */
  83.         handle_GPDMA1_Channel10.Instance = GPDMA1_Channel10;

  84.   handle_GPDMA1_Channel10.Init.Request = DMA_REQUEST_SW;

  85.   handle_GPDMA1_Channel10.Init.BlkHWRequest = DMA_BREQ_SINGLE_BURST;

  86.   handle_GPDMA1_Channel10.Init.Direction = DMA_MEMORY_TO_MEMORY;

  87.   handle_GPDMA1_Channel10.Init.SrcInc = DMA_SINC_FIXED;

  88.   handle_GPDMA1_Channel10.Init.DestInc = DMA_DINC_FIXED;

  89.   handle_GPDMA1_Channel10.Init.SrcDataWidth = DMA_SRC_DATAWIDTH_BYTE;

  90.   handle_GPDMA1_Channel10.Init.DestDataWidth = DMA_DEST_DATAWIDTH_BYTE;

  91.   handle_GPDMA1_Channel10.Init.Priority = DMA_LOW_PRIORITY_LOW_WEIGHT;

  92.   handle_GPDMA1_Channel10.Init.SrcBurstLength = 1;

  93.   handle_GPDMA1_Channel10.Init.DestBurstLength = 1;

  94.   handle_GPDMA1_Channel10.Init.TransferAllocatedPort = DMA_SRC_ALLOCATED_PORT0|DMA_DEST_ALLOCATED_PORT0;

  95.   handle_GPDMA1_Channel10.Init.TransferEventMode = DMA_TCEM_BLOCK_TRANSFER;

  96.   handle_GPDMA1_Channel10.Init.Mode = DMA_NORMAL;

  97.   if (HAL_DMA_Init(&handle_GPDMA1_Channel10) != HAL_OK)

  98.   {

  99.    // Error_Handler();

  100.   }

  101.   if (HAL_DMA_ConfigChannelAttributes(&handle_GPDMA1_Channel10, DMA_CHANNEL_NPRIV) != HAL_OK)

  102.   {

  103. //    Error_Handler();

  104.   }
  105.   /* USER CODE END SysInit */

  106.   /* Initialize all configured peripherals */
  107.   //MX_GPDMA1_Init();
  108.   MX_ICACHE_Init();
  109.          
  110.   /* USER CODE BEGIN 2 */
  111.   /* Initialize LEDs */

  112.   
  113.   /* Reset transferErrorDetected to 0, it will be set to 1 if a transfer error is detected */

  114. //  /* Reset transferCompleteDetected to 0, it will be set to 1 if a transfer is correctly completed */


  115. //  /* Select Callbacks functions called after Transfer complete and Transfer error */


  116.         DmaCopyHalfWordBlock (BUFFER_SIZE,(uint16_t *)aSRC_Const_Buffer1,aDST_Buffer1);
  117.   /* Configure the source, destination and buffer size DMA fields and Start DMA Channel/Stream transfer */
  118.   /* Enable All the DMA interrupts */
  119.   

  120.   /* Wait for end of transmission or an error occurred */
  121.   
  122.   /* USER CODE END 2 */

  123.   /* Infinite loop */
  124.   /* USER CODE BEGIN WHILE */
  125.   while (1)
  126.   {
  127.     /* USER CODE END WHILE */

  128.     /* USER CODE BEGIN 3 */
  129.     HAL_Delay(250);
  130.     BSP_LED_Toggle(LED1);
  131.   }
  132.   /* USER CODE END 3 */
  133. }


AloneKaven 发表于 2026-6-17 18:27 | 显示全部楼层
搞清楚地址对齐问题,确保地址是2的倍数。同时检查DMA配置,确保半字传输设置正确。
xch 发表于 2026-6-17 21:35 | 显示全部楼层
Tom952331 发表于 2026-6-17 18:04
我的程序改成这样了:

我买了块 STM32U575VGT6 开发板跑DMA 正常啊!

my_dma.zip (1.6 KB, 下载次数: 1)





main.zip (5.46 KB, 下载次数: 1)





U575VGT6_TFT2.0_EVK.ioc.zip (3.68 KB, 下载次数: 1)



传输1000字节,擦除100字节。循环。
xch 发表于 2026-6-17 21:40 | 显示全部楼层
#pragma data_alignment=65536
tDMA_LLS DMA_MEM_LLS[MAX_LLS_ARRAY_NUM];// @0x20000000 ;
换了编译器版本,这里对齐改一下
xch 发表于 2026-6-18 09:37 | 显示全部楼层
Tom952331 发表于 2026-6-17 18:04
我的程序改成这样了:

你的板子上的MCU不会是假货吧?

我买这家的:

730916a334bc13e6cd.png



xch 发表于 2026-6-18 09:38 | 显示全部楼层
X Pulse企业店
xch 发表于 2026-6-18 09:42 | 显示全部楼层
在XB上买到过两次假冒ST 的 mcu。程序可以跑起来就是不正常。

用ST 的cubeprogrammer连接 mcu 就会告诉你是假货不认识。

一投诉商家就知道肉馅了赶紧退钱不退货。明知故犯的
 楼主| Tom952331 发表于 2026-6-18 10:11 | 显示全部楼层
xch 发表于 2026-6-17 21:35
我买了块 STM32U575VGT6 开发板跑DMA 正常啊!

谢谢
 楼主| Tom952331 发表于 2026-6-18 10:11 | 显示全部楼层
xch 发表于 2026-6-18 09:37
你的板子上的MCU不会是假货吧?

我买这家的:

不是假货。是NUCLEO-U575ZI-Q
 楼主| Tom952331 发表于 2026-6-18 10:43 | 显示全部楼层
xch 发表于 2026-6-17 21:40
#pragma data_alignment=65536
tDMA_LLS DMA_MEM_LLS[MAX_LLS_ARRAY_NUM];// @0x20000000 ;
换了编译器版 ...

再次感谢,好啦。
我把源地址和目的地址弄反了。
改成这样就好了:
  1. DmaCopyHalfWordBlock (BUFFER_SIZE,aDST_Buffer1,(uint16_t *)aSRC_Const_Buffer1);


xch 发表于 2026-6-18 11:04 | 显示全部楼层
Tom952331 发表于 2026-6-18 10:43
再次感谢,好啦。
我把源地址和目的地址弄反了。
改成这样就好了:

我没仔细看。

朝生 发表于 2026-6-18 15:53 | 显示全部楼层
STM32U575板DMA问题可能是配置参数设置不当,检查初始化代码,确认地址和传输方向等设置正确。
Henryko 发表于 2026-6-18 20:35 | 显示全部楼层
改用uint32_t类型地址,确保32位地址正确。检查DMA控制器是否支持半字传输,否则需用其他方式。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 在线客服 返回列表 返回顶部
0