硬汉嵌入式论坛

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

[DMA] 区分STM32H7的DMAMUX中同步触发源和外部触发源以及配套的几个实战案例

  [复制链接]

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106649
QQ
发表于 2020-7-15 08:47:50 | 显示全部楼层 |阅读模式
问题:

大家初次看手册的话,会看到同步触发源和外部触发源支持的触发基本都是一样的,难免有所疑惑

QQ图片20200715084044.png

1、基础知识普及:

http://www.armbbs.cn/forum.php?mod=viewthread&tid=86980

7.jpg

2、同步触发源和外部触发源在DMAMUX中所处的位置。

2.jpg

3、外部触发源作用:

外部触发源就是在原有的外设请求(如SPI,串口,定时器等)的基础上,再增加一批额外的请求,而且用户可以通过外部触发源来控制如何触发

5.jpg


4、同步触发源作用:

同步触发是处理外设触发请求和新增的触发(通过外部触发)的后级阶段。可以设置外设触发和新增触发何时执行。

1.jpg





回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106649
QQ
 楼主| 发表于 2020-7-15 08:50:38 | 显示全部楼层
对应的例子:

http://www.armbbs.cn/forum.php?mod=viewthread&tid=86980



外部触发案例两个:

1.jpg


同步触发案例两个:

23.jpg


回复

使用道具 举报

3

主题

1222

回帖

1231

积分

至尊会员

积分
1231
发表于 2020-7-15 09:02:47 | 显示全部楼层
这么细的研究,赞硬汉大哥
回复

使用道具 举报

23

主题

1403

回帖

1472

积分

至尊会员

积分
1472
发表于 2020-7-15 12:18:57 | 显示全部楼层
看似简单的问题,其实很多人都不理解
代码不规范,亲人两行泪!
回复

使用道具 举报

1

主题

10

回帖

13

积分

新手上路

积分
13
发表于 2020-9-26 15:29:08 | 显示全部楼层
那么问题来了:如何利用一个GPIO或EXTI触发一次DMA搬运?十年前的TI的片子很好弄,H7我实在搞不定……
回复

使用道具 举报

1

主题

10

回帖

13

积分

新手上路

积分
13
发表于 2020-9-26 15:32:57 | 显示全部楼层
那么问题来了:如何实现一个GPIO或EXTI的边沿触发一个DMA搬运呢?十年前的TI的片子很好弄,但是H7实在没搞定……
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106649
QQ
 楼主| 发表于 2020-9-26 15:33:17 | 显示全部楼层
ragen 发表于 2020-9-26 15:29
那么问题来了:如何利用一个GPIO或EXTI触发一次DMA搬运?十年前的TI的片子很好弄,H7我实在搞不定……

这个很简单,回头我做个案例分享给大家。
回复

使用道具 举报

1

主题

10

回帖

13

积分

新手上路

积分
13
发表于 2020-9-27 11:10:31 | 显示全部楼层
eric2013 发表于 2020-9-26 15:33
这个很简单,回头我做个案例分享给大家。

硬汉哥,啥时候弄个出例子来啊,我已经迫不及待了啊
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106649
QQ
 楼主| 发表于 2020-9-27 11:16:47 | 显示全部楼层
ragen 发表于 2020-9-27 11:10
硬汉哥,啥时候弄个出例子来啊,我已经迫不及待了啊

争取早点安排上。
回复

使用道具 举报

1

主题

10

回帖

13

积分

新手上路

积分
13
发表于 2020-9-28 09:11:03 | 显示全部楼层
eric2013 发表于 2020-9-27 11:16
争取早点安排上。

或者汉哥你先说一下流程,我先试一下看能不能折腾出来,先趟趟水
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106649
QQ
 楼主| 发表于 2020-9-29 05:19:21 | 显示全部楼层
ragen 发表于 2020-9-28 09:11
或者汉哥你先说一下流程,我先试一下看能不能折腾出来,先趟趟水

DMAMMUX有个外部EXTI触发的,使用这个即可。
回复

使用道具 举报

1

主题

10

回帖

13

积分

新手上路

积分
13
发表于 2020-9-30 08:59:52 | 显示全部楼层
eric2013 发表于 2020-9-29 05:19
DMAMMUX有个外部EXTI触发的,使用这个即可。

这个EXTI看着只有EXTI0,另外俩是syscfg_exti0/2,不知道是个啥东西。
如果只有EXTI0的话,那这个IO触发DMA的功能受限太大了啊
回复

使用道具 举报

1

主题

10

回帖

13

积分

新手上路

积分
13
发表于 2020-9-30 09:06:09 | 显示全部楼层
eric2013 发表于 2020-9-29 05:19
DMAMMUX有个外部EXTI触发的,使用这个即可。

dmamux_trgx可不可以跟GPIO关联起来的呢?
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106649
QQ
 楼主| 发表于 2020-9-30 09:42:37 | 显示全部楼层
ragen 发表于 2020-9-30 08:59
这个EXTI看着只有EXTI0,另外俩是syscfg_exti0/2,不知道是个啥东西。
如果只有EXTI0的话,那这个IO触发 ...

GPIOA PIN0,GPIOA PIN1,GPIOB,,,依次。

设计的时候一定要注意。
回复

使用道具 举报

1

主题

10

回帖

13

积分

新手上路

积分
13
发表于 2020-10-9 15:02:12 | 显示全部楼层
eric2013 发表于 2020-9-30 09:42
GPIOA PIN0,GPIOA PIN1,GPIOB,,,依次。

设计的时候一定要注意。

汉哥你的意思是syscfg_exti0/1可以配置成GPA_0/GPA_1或GPB_0/GPB_1?
STM32H7 Reference Manual哪一章节有介绍呢?我研究下
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106649
QQ
 楼主| 发表于 2020-10-9 16:11:03 | 显示全部楼层
ragen 发表于 2020-10-9 15:02
汉哥你的意思是syscfg_exti0/1可以配置成GPA_0/GPA_1或GPB_0/GPB_1?
STM32H7 Reference Manual哪一章节 ...

DMAMUX
回复

使用道具 举报

0

主题

124

回帖

124

积分

初级会员

积分
124
发表于 2020-12-15 16:04:40 | 显示全部楼层
是syscfg_exti0/1 ?好象是syscfg_exti0/2
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106649
QQ
 楼主| 发表于 2020-12-16 09:08:08 | 显示全部楼层
Edmund1964 发表于 2020-12-15 16:04
是syscfg_exti0/1 ?好象是syscfg_exti0/2


HAL_DMAMUX1_SYNC_EXTI0
HAL_DMAMUX2_SYNC_EXTI0
HAL_DMAMUX2_SYNC_EXTI2
回复

使用道具 举报

55

主题

131

回帖

296

积分

高级会员

积分
296
发表于 2021-3-30 10:35:29 | 显示全部楼层
eric2013 发表于 2020-9-26 15:33
这个很简单,回头我做个案例分享给大家。

用外部中断触发DMA搬运数据,使一个IO口翻转,DMA发生错误中断,用的是STM32G0

hdma_memtomem_dma1_channel1.Instance = DMA1_Channel1;
  hdma_memtomem_dma1_channel1.Init.Request = DMA_REQUEST_GENERATOR0;
  hdma_memtomem_dma1_channel1.Init.Direction = DMA_MEMORY_TO_PERIPH;
  hdma_memtomem_dma1_channel1.Init.PeriphInc = DMA_PINC_DISABLE;
  hdma_memtomem_dma1_channel1.Init.MemInc = DMA_MINC_ENABLE;
  hdma_memtomem_dma1_channel1.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
  hdma_memtomem_dma1_channel1.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
  hdma_memtomem_dma1_channel1.Init.Mode = DMA_CIRCULAR;
  hdma_memtomem_dma1_channel1.Init.Priority = DMA_PRIORITY_LOW;
  if (HAL_DMA_Init(&hdma_memtomem_dma1_channel1) != HAL_OK)
  {
    Error_Handler( );
  }
       
  /* DMA interrupt init */
  /* DMA1_Channel1_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 0, 1);
  HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
       
        /*##-3- Configure and enable the DMAMUX Request generator  ####################*/
  dmamux_ReqGenParams.SignalID  = HAL_DMAMUX1_REQ_GEN_EXTI7;    /* External request signal is EXTI0 signal */
  dmamux_ReqGenParams.Polarity  = HAL_DMAMUX_REQ_GEN_FALLING;    /* External request signal edge is falling  */
  dmamux_ReqGenParams.RequestNumber = 1;                        /* 1 requests on each edge of the external request signal  */

  HAL_DMAEx_ConfigMuxRequestGenerator(&hdma_memtomem_dma1_channel1, &dmamux_ReqGenParams);
  HAL_DMAEx_EnableMuxRequestGenerator (&hdma_memtomem_dma1_channel1);
       
  /* NVIC configuration for DMAMUX request generator overrun errors*/
  HAL_NVIC_SetPriority(DMA1_Ch4_7_DMAMUX1_OVR_IRQn, 0, 1);
  HAL_NVIC_EnableIRQ(DMA1_Ch4_7_DMAMUX1_OVR_IRQn);


BSP_PB_Init(BUTTON_USER,BUTTON_MODE_EXTI);//PB5

if (HAL_DMA_Start_IT(&hdma_memtomem_dma1_channel1, (uint32_t)temp, (uint32_t)&LED4_GPIO_PORT->ODR, 2) != HAL_OK)
  {
    /* Transfer Error */
    Error_Handler();
  }


不知道错在哪了
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106649
QQ
 楼主| 发表于 2021-3-30 14:40:17 | 显示全部楼层
lindahnu 发表于 2021-3-30 10:35
用外部中断触发DMA搬运数据,使一个IO口翻转,DMA发生错误中断,用的是STM32G0

hdma_memtomem_dma1_cha ...

发个稍完整点的程序,我看下。
回复

使用道具 举报

55

主题

131

回帖

296

积分

高级会员

积分
296
发表于 2021-3-30 17:03:20 | 显示全部楼层
eric2013 发表于 2021-3-30 14:40
发个稍完整点的程序,我看下。

static void MX_DMA_Init(void)
{
        HAL_DMA_MuxRequestGeneratorConfigTypeDef dmamux_ReqGenParams;
       
  /* DMA controller clock enable */
  __HAL_RCC_DMA1_CLK_ENABLE();

        hdma_memtomem_dma1_channel1.Instance = DMA1_Channel1;
  hdma_memtomem_dma1_channel1.Init.Request = DMA_REQUEST_GENERATOR0;
  hdma_memtomem_dma1_channel1.Init.Direction = DMA_MEMORY_TO_PERIPH;
  hdma_memtomem_dma1_channel1.Init.PeriphInc = DMA_PINC_DISABLE;
  hdma_memtomem_dma1_channel1.Init.MemInc = DMA_MINC_ENABLE;
  hdma_memtomem_dma1_channel1.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
  hdma_memtomem_dma1_channel1.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
  hdma_memtomem_dma1_channel1.Init.Mode = DMA_CIRCULAR;
  hdma_memtomem_dma1_channel1.Init.Priority = DMA_PRIORITY_LOW;
  if (HAL_DMA_Init(&hdma_memtomem_dma1_channel1) != HAL_OK)
  {
    Error_Handler( );
  }
       
  /* DMA interrupt init */
  /* DMA1_Channel1_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 0, 1);
  HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
       
        /*##-3- Configure and enable the DMAMUX Request generator  ####################*/
  dmamux_ReqGenParams.SignalID  = HAL_DMAMUX1_REQ_GEN_EXTI7;    /* External request signal is EXTI7 signal */
  dmamux_ReqGenParams.Polarity  = HAL_DMAMUX_REQ_GEN_FALLING;    /* External request signal edge is falling  */
  dmamux_ReqGenParams.RequestNumber = 1;                        /* 1 requests on each edge of the external request signal  */

  HAL_DMAEx_ConfigMuxRequestGenerator(&hdma_memtomem_dma1_channel1, &dmamux_ReqGenParams);
  HAL_DMAEx_EnableMuxRequestGenerator (&hdma_memtomem_dma1_channel1);
       
  /* NVIC configuration for DMAMUX request generator overrun errors*/
  HAL_NVIC_SetPriority(DMA1_Ch4_7_DMAMUX1_OVR_IRQn, 0, 1);
  HAL_NVIC_EnableIRQ(DMA1_Ch4_7_DMAMUX1_OVR_IRQn);
  

}

int main(void)
{
  uint32_t temp[2]={0,LED4_PIN};

   HAL_Init();

  SystemClock_Config();

  BSP_LED_Init(LED4);
        MX_DMA_Init();


  /* Reset transferErrorDetected to 0, it will be set to 1 if a transfer error is detected */
  transferErrorDetected = 0;


  /* Select Callbacks functions called after Transfer complete and Transfer error */
  HAL_DMA_RegisterCallback(&hdma_memtomem_dma1_channel1, HAL_DMA_XFER_ERROR_CB_ID, TransferError);
  
  BSP_PB_Init(BUTTON_USER,BUTTON_MODE_EXTI);


  if (HAL_DMA_Start_IT(&hdma_memtomem_dma1_channel1, (uint32_t)temp, (uint32_t)&LED4_GPIO_PORT->ODR, 2) != HAL_OK)
  {
    /* Transfer Error */
    Error_Handler();
  }
       
  /* Infinite loop */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
    if (transferErrorDetected == 1)
    {
      /* Toggle LED4 with a period of 200 ms */
      //BSP_LED_Toggle(LED4);
      transferErrorDetected = 0;
    }
   
  }
  /* USER CODE END 3 */
}


/**
  * @brief This function handles DMA1 channel 1 interrupt.
  */
void DMA1_Ch4_7_DMAMUX1_OVR_IRQHandler(void)
{
  /* USER CODE BEGIN DMA1_Channel1_IRQn 0 */

  /* USER CODE END DMA1_Channel1_IRQn 0 */
  HAL_DMA_IRQHandler(&hdma_memtomem_dma1_channel1);
  /* USER CODE BEGIN DMA1_Channel1_IRQn 1 */

  /* USER CODE END DMA1_Channel1_IRQn 1 */
}
/**
  * @brief  This function handles DMA1_Channel1 interrupt request.
  * @param  None
  * @retval None
  */
void DMA1_Channel1_IRQHandler(void)
{
  HAL_DMA_IRQHandler(&hdma_memtomem_dma1_channel1);
}

/* USER CODE BEGIN 1 */
/**
  * @brief  This function handles external line 4_15 interrupt request.
  * @param  None
  * @retval None
  */
void EXTI4_15_IRQHandler(void)
{
  HAL_GPIO_EXTI_IRQHandler(USER_BUTTON_PIN);
}

static void TransferError(DMA_HandleTypeDef *hdma_memtomem_dma1_channel1)
{
  transferErrorDetected = 1;
}


回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106649
QQ
 楼主| 发表于 2021-3-31 11:21:58 | 显示全部楼层
lindahnu 发表于 2021-3-30 17:03
static void MX_DMA_Init(void)
{
        HAL_DMA_MuxRequestGeneratorConfigTypeDef dmamux_ReqGenParams;
...

1、HAL_DMA_MuxRequestGeneratorConfigTypeDef dmamux_ReqGenParams;清零下。
2、IO寄存器使用BSRR
3、别的问题暂未看出来
回复

使用道具 举报

55

主题

131

回帖

296

积分

高级会员

积分
296
发表于 2021-5-19 14:44:27 | 显示全部楼层
eric2013 发表于 2020-9-26 15:33
这个很简单,回头我做个案例分享给大家。

这个现在有例子吗?
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106649
QQ
 楼主| 发表于 2021-5-20 08:16:32 | 显示全部楼层
lindahnu 发表于 2021-5-19 14:44
这个现在有例子吗?

没有。
回复

使用道具 举报

2

主题

87

回帖

93

积分

初级会员

积分
93
发表于 2022-1-14 16:08:32 | 显示全部楼层
/*##-4- 启动DMA双缓冲传输 ################################################*/
    /*
        1、此函数会开启DMA的TC,TE和DME中断
        2、如果用户配置了回调函数DMA_Handle.XferHalfCpltCallback,那么函数HAL_DMA_Init会开启半传输完成中断。
        3、如果用户使用了DMAMUX的同步模式,此函数会开启同步溢出中断。
        4、如果用户使用了DMAMUX的请求发生器,此函数会开始请求发生器溢出中断。
    */
    HAL_DMAEx_MultiBufferStart_IT(&DMA_Handle, (uint32_t)IO_Toggle, (uint32_t)&GPIOB->BSRRL,(uint32_t)IO_Toggle1, 8);
编译不过去,还是BSRR问题,硬汉的没问题。改了BSRR只有高电平
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106649
QQ
 楼主| 发表于 2022-1-14 18:37:05 | 显示全部楼层
EastWind 发表于 2022-1-14 16:08
/*##-4- 启动DMA双缓冲传输 ################################################*/
    /*
        1、此 ...

这个是早期的定义方式,是新版库的,手动修改下即可。

现在所有系列都改成下面这种玩法了。

F4系列HAL库GPIO的BSRR寄存器怎么不按照BSRRH和BSRRL定义了,使用很不方便
https://www.armbbs.cn/forum.php? ... 3422&fromuid=58
(出处: 硬汉嵌入式论坛)
回复

使用道具 举报

23

主题

1403

回帖

1472

积分

至尊会员

积分
1472
发表于 2022-1-17 16:43:38 | 显示全部楼层
最近使用这个,差点绕进去,要搞一个ADC SPI DMA方式。
代码不规范,亲人两行泪!
回复

使用道具 举报

4

主题

32

回帖

44

积分

新手上路

积分
44
发表于 2022-8-30 09:40:20 | 显示全部楼层
eric2013 发表于 2020-9-26 15:33
这个很简单,回头我做个案例分享给大家。

硬汉哥赶紧做这个案例吧,太需要了
回复

使用道具 举报

0

主题

3

回帖

3

积分

新手上路

积分
3
发表于 2022-9-15 21:12:03 | 显示全部楼层
触发一次,DMA只能搬运一次数据,如果要发送16个数据,是不是要触发16次?
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106649
QQ
 楼主| 发表于 2022-9-16 11:29:42 | 显示全部楼层
29877318 发表于 2022-9-15 21:12
触发一次,DMA只能搬运一次数据,如果要发送16个数据,是不是要触发16次?

可以使用突发模式,DMA可以设置突发次数,DMAMUX也可以设置突发次数。
回复

使用道具 举报

3

主题

13

回帖

22

积分

新手上路

积分
22
发表于 2023-2-27 17:45:11 | 显示全部楼层
eric2013 发表于 2020-9-26 15:33
这个很简单,回头我做个案例分享给大家。

硬汉哥 这个案例有做吗 好像没找到
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106649
QQ
 楼主| 发表于 2023-2-28 10:34:53 | 显示全部楼层
zzy 发表于 2023-2-27 17:45
硬汉哥 这个案例有做吗 好像没找到

还没做。
回复

使用道具 举报

8

主题

8

回帖

32

积分

新手上路

积分
32
发表于 2024-3-25 17:02:42 | 显示全部楼层
硬汉哥,请问如果不配置DMAMUX的同步触发的话,当来了一个DMA请求后,DMA会传输吗?
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106649
QQ
 楼主| 发表于 2024-3-27 09:24:33 | 显示全部楼层
永恒丶 发表于 2024-3-25 17:02
硬汉哥,请问如果不配置DMAMUX的同步触发的话,当来了一个DMA请求后,DMA会传输吗?

必须配置,他前一级。
回复

使用道具 举报

8

主题

8

回帖

32

积分

新手上路

积分
32
发表于 2024-3-28 15:29:04 | 显示全部楼层
eric2013 发表于 2024-3-27 09:24
必须配置,他前一级。

硬汉哥,那请问为什么这个例子中使用了DMA,但是没有配置DMAMUX呢?

DMA.png
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-4-27 23:06 , Processed in 0.288829 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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