区分STM32H7的DMAMUX中同步触发源和外部触发源以及配套的几个实战案例
问题:大家初次看手册的话,会看到同步触发源和外部触发源支持的触发基本都是一样的,难免有所疑惑
1、基础知识普及:
http://www.armbbs.cn/forum.php?mod=viewthread&tid=86980
2、同步触发源和外部触发源在DMAMUX中所处的位置。
3、外部触发源作用:
外部触发源就是在原有的外设请求(如SPI,串口,定时器等)的基础上,再增加一批额外的请求,而且用户可以通过外部触发源来控制如何触发
4、同步触发源作用:
同步触发是处理外设触发请求和新增的触发(通过外部触发)的后级阶段。可以设置外设触发和新增触发何时执行。
对应的例子:
http://www.armbbs.cn/forum.php?mod=viewthread&tid=86980
static/image/hrline/4.gif
外部触发案例两个:
同步触发案例两个:
{:8:}这么细的研究,赞硬汉大哥 看似简单的问题,其实很多人都不理解 那么问题来了:如何利用一个GPIO或EXTI触发一次DMA搬运?十年前的TI的片子很好弄,H7我实在搞不定…… 那么问题来了:如何实现一个GPIO或EXTI的边沿触发一个DMA搬运呢?十年前的TI的片子很好弄,但是H7实在没搞定…… ragen 发表于 2020-9-26 15:29
那么问题来了:如何利用一个GPIO或EXTI触发一次DMA搬运?十年前的TI的片子很好弄,H7我实在搞不定……
这个很简单,回头我做个案例分享给大家。 eric2013 发表于 2020-9-26 15:33
这个很简单,回头我做个案例分享给大家。
硬汉哥,啥时候弄个出例子来啊,我已经迫不及待了啊{:3:} ragen 发表于 2020-9-27 11:10
硬汉哥,啥时候弄个出例子来啊,我已经迫不及待了啊
争取早点安排上。 eric2013 发表于 2020-9-27 11:16
争取早点安排上。
或者汉哥你先说一下流程,我先试一下看能不能折腾出来,先趟趟水:lol ragen 发表于 2020-9-28 09:11
或者汉哥你先说一下流程,我先试一下看能不能折腾出来,先趟趟水
DMAMMUX有个外部EXTI触发的,使用这个即可。 eric2013 发表于 2020-9-29 05:19
DMAMMUX有个外部EXTI触发的,使用这个即可。
这个EXTI看着只有EXTI0,另外俩是syscfg_exti0/2,不知道是个啥东西。
如果只有EXTI0的话,那这个IO触发DMA的功能受限太大了啊 eric2013 发表于 2020-9-29 05:19
DMAMMUX有个外部EXTI触发的,使用这个即可。
dmamux_trgx可不可以跟GPIO关联起来的呢? ragen 发表于 2020-9-30 08:59
这个EXTI看着只有EXTI0,另外俩是syscfg_exti0/2,不知道是个啥东西。
如果只有EXTI0的话,那这个IO触发 ...
GPIOA PIN0,GPIOA PIN1,GPIOB,,,依次。
设计的时候一定要注意。 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哪一章节有介绍呢?我研究下 ragen 发表于 2020-10-9 15:02
汉哥你的意思是syscfg_exti0/1可以配置成GPA_0/GPA_1或GPB_0/GPB_1?
STM32H7 Reference Manual哪一章节 ...
DMAMUX 是syscfg_exti0/1 ?好象是syscfg_exti0/2 Edmund1964 发表于 2020-12-15 16:04
是syscfg_exti0/1 ?好象是syscfg_exti0/2
对
HAL_DMAMUX1_SYNC_EXTI0
HAL_DMAMUX2_SYNC_EXTI0
HAL_DMAMUX2_SYNC_EXTI2 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();
}
不知道错在哪了 lindahnu 发表于 2021-3-30 10:35
用外部中断触发DMA搬运数据,使一个IO口翻转,DMA发生错误中断,用的是STM32G0
hdma_memtomem_dma1_cha ...
发个稍完整点的程序,我看下。 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={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 */
}
/**
* @briefThis function handles DMA1_Channel1 interrupt request.
* @paramNone
* @retval None
*/
void DMA1_Channel1_IRQHandler(void)
{
HAL_DMA_IRQHandler(&hdma_memtomem_dma1_channel1);
}
/* USER CODE BEGIN 1 */
/**
* @briefThis function handles external line 4_15 interrupt request.
* @paramNone
* @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;
}
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、别的问题暂未看出来 eric2013 发表于 2020-9-26 15:33
这个很简单,回头我做个案例分享给大家。
这个现在有例子吗? lindahnu 发表于 2021-5-19 14:44
这个现在有例子吗?
没有。 /*##-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只有高电平 EastWind 发表于 2022-1-14 16:08
/*##-4- 启动DMA双缓冲传输 ################################################*/
/*
1、此 ...
这个是早期的定义方式,是新版库的,手动修改下即可。
现在所有系列都改成下面这种玩法了。
F4系列HAL库GPIO的BSRR寄存器怎么不按照BSRRH和BSRRL定义了,使用很不方便
https://www.armbbs.cn/forum.php?mod=viewthread&tid=93422&fromuid=58
(出处: 硬汉嵌入式论坛)
最近使用这个,差点绕进去,要搞一个ADC SPI DMA方式。 eric2013 发表于 2020-9-26 15:33
这个很简单,回头我做个案例分享给大家。
硬汉哥赶紧做这个案例吧,太需要了{:33:} 触发一次,DMA只能搬运一次数据,如果要发送16个数据,是不是要触发16次? 29877318 发表于 2022-9-15 21:12
触发一次,DMA只能搬运一次数据,如果要发送16个数据,是不是要触发16次?
可以使用突发模式,DMA可以设置突发次数,DMAMUX也可以设置突发次数。 eric2013 发表于 2020-9-26 15:33
这个很简单,回头我做个案例分享给大家。
硬汉哥 这个案例有做吗 好像没找到 zzy 发表于 2023-2-27 17:45
硬汉哥 这个案例有做吗 好像没找到
还没做。 硬汉哥,请问如果不配置DMAMUX的同步触发的话,当来了一个DMA请求后,DMA会传输吗? 永恒丶 发表于 2024-3-25 17:02
硬汉哥,请问如果不配置DMAMUX的同步触发的话,当来了一个DMA请求后,DMA会传输吗?
必须配置,他前一级。 eric2013 发表于 2024-3-27 09:24
必须配置,他前一级。
硬汉哥,那请问为什么这个例子中使用了DMA,但是没有配置DMAMUX呢?
页:
[1]