随笔 - 20  文章 - 0  评论 - 3  阅读 - 28128

STM32H743 中的DMA1 DMA2 DMAMUX1

STM32H743 中的DMA1 DMA2 DMAMUX1

 来自一位小菜鸡的小总结!

现在理一遍STM32H743中的DMA控制器和DMAMUX( DMA请求复用器)之间的恩怨情仇,闲话少说,上来就是一P

 

上图中从左到右分别是 107个DMA请求源,  DMAMUX(DMA请求复用器), [DMA1, DMA2控制器,外设端口,存储器端口], [DMA控制器外端, 外设和存储设备]

str0...str7 对应DMA控制器中的DMA数据流0-7

ch0-15 对应DMAMUX1的16个通道

注:外设的DMA请求可以任意请求对应任意DMA控制器的任意数据流, 比如USART1 的DMA发送请求(DMA请求号42) 可以请求DMA1的 数据流1/2/3..../7,也可以请求DMA2的 数据流1/2/3..../7

 

STM32H743的外设DMA请求号如下图所示

 

 

如何使用DMA?

例在USART1中使用DMA来发送和接收

USART1_TX 请求DMA1的数据流5

USART1_RX 请求DMA1的数据流1

 

 

第一步,初始化USART1

第二步,打开DMA1的外设时钟

__HAL_RCC_DMA1_CLK_ENABLE();

第三步,初始化DMA数据流,使能中断

/* USART1 DMA Init */
/* USART1_RX Init */
hdma_usart1_rx.Instance = DMA1_Stream5;   //USART接收DMA选择DMA1的数据流5
hdma_usart1_rx.Init.Request = DMA_REQUEST_USART1_RX;   //USART1 RX的DMA请求号41
hdma_usart1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;  //DMA方向 外设到存储器
hdma_usart1_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_usart1_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_usart1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_usart1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_usart1_rx.Init.Mode = DMA_NORMAL;
hdma_usart1_rx.Init.Priority = DMA_PRIORITY_LOW;
hdma_usart1_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
if (HAL_DMA_Init(&hdma_usart1_rx) != HAL_OK)
{
Error_Handler();
}

__HAL_LINKDMA(huart,hdmarx,hdma_usart1_rx);

/* USART1_TX Init */
hdma_usart1_tx.Instance = DMA1_Stream1; //USART接收DMA选择DMA1的数据流1
hdma_usart1_tx.Init.Request = DMA_REQUEST_USART1_TX; //USART1 RX的DMA请求号42
hdma_usart1_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;  //DMA方向 存储器到外设
hdma_usart1_tx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_usart1_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_usart1_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_usart1_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_usart1_tx.Init.Mode = DMA_NORMAL;
hdma_usart1_tx.Init.Priority = DMA_PRIORITY_LOW;
hdma_usart1_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
if (HAL_DMA_Init(&hdma_usart1_tx) != HAL_OK)
{
Error_Handler();
}

__HAL_LINKDMA(huart,hdmatx,hdma_usart1_tx);

 

//使能中断

/* DMA interrupt init */
/* DMA1_Stream0_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Stream5_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Stream5_IRQn);
/* DMA1_Stream1_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Stream1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Stream1_IRQn);

 

 

第五步, 使用DMA发送和接收

接收函数: HAL_UART_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);

发送函数:HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size)

 

posted on   一个大菜B  阅读(2020)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

点击右上角即可分享
微信分享提示