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)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?