OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 411|回复: 0

STM32U575板子DMA传输失败的问题

[复制链接]

94

主题

219

帖子

0

精华

高级会员

Rank: 4

积分
714
金钱
714
注册时间
2014-10-15
在线时间
172 小时
发表于 2026-6-3 22:18:15 | 显示全部楼层 |阅读模式
1金钱
我有一块STM32U575的开发板,有一个DMA的例程,把FLASH里的内容传到RAM.
它用的是32位传,也就是字传。
我试图把它改成半字传。
以下是我的一部分程序:
  1. DMA_HandleTypeDef handle_GPDMA1_Channel15;


  2. static const uint16_t aSRC_Const_Buffer1[BUFFER_SIZE] =
  3. {
  4.   0x0102,0x0304, 0x0506,0x0708,
  5.         0x090a,0x0b0c,0x0d0e,0x0f10,
  6.         0x1112,0x1314,0x1516,0x1718,
  7.         0x191a,0x1b1c,0x1d1e,0x1f20,
  8.         0x0102,0x0304, 0x0506,0x0708,
  9.         0x090a,0x0b0c,0x0d0e,0x0f10,
  10.         0x1112,0x1314,0x1516,0x1718,
  11.         0x191a,0x1b1c,0x1d1e,0x1f20
  12.   
  13. };

  14. static uint16_t aDST_Buffer1[BUFFER_SIZE];
复制代码
原来的启动传输函数是按字传的,我改为半字传,所以原来的函数就不能用了,我自己写了一个

  1. HAL_StatusTypeDef HAL_DMA_Start_IT1(DMA_HandleTypeDef *const hdma,
  2.                                    uint16_t SrcAddress,
  3.                                    uint16_t DstAddress,
  4.                                    uint32_t SrcDataSize)
  5. {
  6.   /* Check the DMA peripheral handle parameter */
  7.   if (hdma == NULL)
  8.   {
  9.     return HAL_ERROR;
  10.   }

  11.   /* Check the parameters */
  12.   assert_param(IS_DMA_BLOCK_SIZE(SrcDataSize));

  13.   /* Process locked */
  14.   __HAL_LOCK(hdma);

  15.   /* Check DMA channel state */
  16.   if (hdma->State == HAL_DMA_STATE_READY)
  17.   {
  18.     /* Update the DMA channel state */
  19.     hdma->State = HAL_DMA_STATE_BUSY;

  20.     /* Update the DMA channel error code */
  21.     hdma->ErrorCode = HAL_DMA_ERROR_NONE;

  22.     /* Configure the source address, destination address, the data size and clear flags */
  23.     DMA_SetConfig1(hdma, SrcAddress, DstAddress, SrcDataSize);

  24.     /* Enable common interrupts: Transfer Complete and Transfer Errors ITs */
  25.     __HAL_DMA_ENABLE_IT(hdma, (DMA_IT_TC | DMA_IT_DTE | DMA_IT_ULE | DMA_IT_USE | DMA_IT_TO));

  26.     /* Check half transfer complete callback */
  27.     if (hdma->XferHalfCpltCallback != NULL)
  28.     {
  29.       /* If Half Transfer complete callback is set, enable the corresponding IT */
  30.       __HAL_DMA_ENABLE_IT(hdma, DMA_IT_HT);
  31.     }

  32.     /* Check Half suspend callback */
  33.     if (hdma->XferSuspendCallback != NULL)
  34.     {
  35.       /* If Transfer suspend callback is set, enable the corresponding IT */
  36.       __HAL_DMA_ENABLE_IT(hdma, DMA_IT_SUSP);
  37.     }

  38.     /* Enable DMA channel */
  39.     __HAL_DMA_ENABLE(hdma);
  40.   }
  41.   else
  42.   {
  43.     /* Update the DMA channel error code */
  44.     hdma->ErrorCode = HAL_DMA_ERROR_BUSY;

  45.     /* Process unlocked */
  46.     __HAL_UNLOCK(hdma);

  47.     return HAL_ERROR;
  48.   }

  49.   return HAL_OK;
  50. }
复制代码
DMA_SetConfig1(hdma, SrcAddress, DstAddress, SrcDataSize);这个函数原来也是按32位来写的,我也进行了改写

  1. static void DMA_SetConfig1(DMA_HandleTypeDef const *const hdma,
  2.                           uint16_t SrcAddress,
  3.                           uint16_t DstAddress,
  4.                           uint32_t SrcDataSize)
  5. {
  6.   /* Configure the DMA channel data size */
  7.   MODIFY_REG(hdma->Instance->CBR1, DMA_CBR1_BNDT, (SrcDataSize & DMA_CBR1_BNDT));

  8.   /* Clear all interrupt flags */
  9.   __HAL_DMA_CLEAR_FLAG(hdma, DMA_FLAG_TC | DMA_FLAG_HT | DMA_FLAG_DTE | DMA_FLAG_ULE | DMA_FLAG_USE | DMA_FLAG_SUSP |
  10.                        DMA_FLAG_TO);

  11.   /* Configure DMA channel source address */
  12.   hdma->Instance->CSAR = SrcAddress;

  13.   /* Configure DMA channel destination address */
  14.   hdma->Instance->CDAR = DstAddress;
  15. }
复制代码
初始化DMA函数我把字改为半字:

  1. static void MX_GPDMA1_Init(void)
  2. {

  3.   /* USER CODE BEGIN GPDMA1_Init 0 */

  4.   /* USER CODE END GPDMA1_Init 0 */

  5.   /* Peripheral clock enable */
  6.   __HAL_RCC_GPDMA1_CLK_ENABLE();

  7.   /* GPDMA1 interrupt Init */
  8.     HAL_NVIC_SetPriority(GPDMA1_Channel15_IRQn, 0, 0);
  9.     HAL_NVIC_EnableIRQ(GPDMA1_Channel15_IRQn);

  10.   /* USER CODE BEGIN GPDMA1_Init 1 */

  11.   /* USER CODE END GPDMA1_Init 1 */
  12.   handle_GPDMA1_Channel15.Instance = GPDMA1_Channel15;
  13.   handle_GPDMA1_Channel15.Init.Request = DMA_REQUEST_SW;
  14.   handle_GPDMA1_Channel15.Init.BlkHWRequest = DMA_BREQ_SINGLE_BURST;
  15.   handle_GPDMA1_Channel15.Init.Direction = DMA_MEMORY_TO_MEMORY;
  16.   handle_GPDMA1_Channel15.Init.SrcInc = DMA_SINC_INCREMENTED;
  17.   handle_GPDMA1_Channel15.Init.DestInc = DMA_DINC_INCREMENTED;
  18.   //handle_GPDMA1_Channel15.Init.SrcDataWidth = DMA_SRC_DATAWIDTH_WORD;
  19.         handle_GPDMA1_Channel15.Init.SrcDataWidth = DMA_SRC_DATAWIDTH_HALFWORD;
  20.   //handle_GPDMA1_Channel15.Init.DestDataWidth = DMA_DEST_DATAWIDTH_WORD;
  21.         handle_GPDMA1_Channel15.Init.DestDataWidth = DMA_SRC_DATAWIDTH_HALFWORD;
  22.   handle_GPDMA1_Channel15.Init.Priority = DMA_LOW_PRIORITY_HIGH_WEIGHT;
  23.   handle_GPDMA1_Channel15.Init.SrcBurstLength = 1;
  24.   handle_GPDMA1_Channel15.Init.DestBurstLength = 1;
  25.   handle_GPDMA1_Channel15.Init.TransferAllocatedPort = DMA_SRC_ALLOCATED_PORT0|DMA_DEST_ALLOCATED_PORT1;
  26.         //handle_GPDMA1_Channel15.Init.TransferAllocatedPort = 0x0000|0x4000;
  27.   handle_GPDMA1_Channel15.Init.TransferEventMode = DMA_TCEM_BLOCK_TRANSFER;
  28.   handle_GPDMA1_Channel15.Init.Mode = DMA_NORMAL;
  29.   if (HAL_DMA_Init(&handle_GPDMA1_Channel15) != HAL_OK)
  30.   {
  31.     Error_Handler();
  32.   }
  33.   if (HAL_DMA_ConfigChannelAttributes(&handle_GPDMA1_Channel15, DMA_CHANNEL_NPRIV) != HAL_OK)
  34.   {
  35.     Error_Handler();
  36.   }
  37.   /* USER CODE BEGIN GPDMA1_Init 2 */

  38.   /* USER CODE END GPDMA1_Init 2 */

  39. }
复制代码
结果不成功,什么也没传过去。
还有一点,这句if (HAL_DMA_Start_IT1(&handle_GPDMA1_Channel15, (uint16_t)&aSRC_Const_Buffer1, (uint16_t *)&aDST_Buffer1, (BUFFER_SIZE * 2U)) != HAL_OK)
有两个警告:
3.jpg
我搞不懂,为什么穿不过去?问题出在哪?谢谢!


回复

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /1 下一条

正点原子公众号

如发现本坛存在违规或侵权内容, 请点击这里发送邮件举报 (或致电020-38271790)。请提供侵权说明和联系方式。我们将及时审核依法处理,感谢配合。

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2026-6-14 18:16

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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