一.介绍
DMA(直接存储器访问):
DMA是一种计算机系统中的重要技术,它允许数据在内存和外设之间直接传输,而无需CPU的直接干预。这种直接传输的方式可以显著提高数据传输的效率,因为它可以在数据传输过程中不占用CPU的时间,从而使CPU能够专注于执行其他任务。
一些额外的信息包括:
工作原理:
DMA工作原理是在CPU控制下配置好DMA的参数后,DMA控制器会独立地从一个地址空间(通常是内存)中获取数据,并将数据传输到另一个地址空间(可以是内存或者外设)。整个传输过程无需CPU的干预,只有在传输完成或者出错时,DMA才会通过中断或者其他方式通知CPU。
优点:
DMA的主要优点是能够显著减轻CPU的负担,提高系统的整体性能。它可以加速大量数据的传输,同时释放CPU用于执行其他任务,从而提高系统的并行处理能力和效率。
应用场景:
DMA广泛应用于需要大量数据传输的场景,比如网络通信、存储设备读写、音视频处理等。在这些场景中,DMA可以大幅提高系统的数据处理速度,同时降低CPU的负载。
注意事项:
虽然DMA可以提高系统的性能,但在使用时需要注意DMA传输过程中的数据一致性和安全性问题。由于DMA是直接访问内存的,因此需要合理管理数据的读写顺序和保证数据的正确性,以避免出现数据损坏或者不一致的情况。
总的来说,DMA是一种强大的数据传输技术,能够有效提高系统的性能和效率,但在应用中需要合理使用,并注意处理好相关的数据一致性和安全性问题。
二.结构框图
1.STM32F1 DMA框图
STM32F1系列的DMA(Direct Memory Access)结构包括以下关键部分:
DMA请求:
DMA传输数据之前,外设需要向DMA控制器发送请求,以启动数据传输过程。
DMA通道:
DMA通道是DMA控制器中用于处理不同外设请求的通道。STM32F1系列中,DMA1有7个通道,而DMA2有5个通道。每个通道可以与一个外设相连,接收其数据传输请求。
DMA优先级:
当多个DMA通道同时发出请求时,需要确定响应处理的优先级顺序。DMA控制器中的仲裁器负责管理DMA通道的优先级,以确保数据传输的顺序性和有效性。优先级管理可以在软件阶段进行设置,也可以在硬件阶段进行配置。
需要注意的是,STM32F1系列中的DMA2仅存在于某些大容量产品和互联型产品中,而不是所有的STM32F1芯片都具有DMA2。
(1)DMA处理过程
DMA(Direct Memory Access)处理过程大致如下:
1.外设发送请求:
外设希望通过DMA进行数据传输时,会向DMA控制器发送请求。
2.DMA控制器确认请求:
DMA控制器收到外设的请求后,会向外设发送确认信号(ACK),表示已经收到请求。
3.外设释放请求:
在收到DMA控制器的确认信号后,外设会释放请求,允许DMA控制器进行数据传输。
4.数据传输:
DMA控制器根据外设发送的请求,启动数据传输过程。数据传输包括从源地址(通常是外设的数据寄存器)读取数据,并将其写入目标地址(通常是内存或另一个外设的数据寄存器)。
传输的数据量由DMA控制器提前配置好,通常是指定要传输的字节数或数据块的数量。
5.传输完成:
一旦传输完成,DMA控制器会发送信号通知外设和CPU传输已经完成。
这个过程中,CPU不需要直接参与数据传输的过程,而是可以继续执行其他任务,从而提高了系统的效率。DMA对于大量数据的传输以及需要高速响应的应用场景非常有用。
(2)DMA通道
DMA通道在STM32中用于管理外设对存储器访问的请求,每个通道可以处理来自一个或多个外设的请求。DMA通道的数量取决于具体的STM32系列和型号,在STM32中通常有多个DMA通道可供选择。
每个DMA通道都有一个仲裁器(Arbiter),用于处理DMA请求之间的优先级。当多个DMA通道同时收到请求时,仲裁器会根据通道的优先级确定哪个通道优先处理请求。通常,可以通过软件配置DMA通道的优先级,也可以在硬件层面实现对DMA请求的优先级管理。这种方式可以确保DMA传输按照特定的优先级顺序进行,从而更好地满足系统的要求。
(3)DMA优先级
在STM32中,DMA优先级的管理分为两个阶段:软件阶段和硬件阶段。
软件阶段:在软件阶段,每个DMA通道的优先级可以在相应的DMA_CCRx寄存器中进行设置。通常情况下,有四个优先级等级可供选择:最高优先级、高优先级、中优先级和低优先级。通过设置这些优先级等级,可以确保DMA通道在处理请求时按照指定的优先级顺序进行。
硬件阶段:如果多个DMA通道的请求具有相同的软件优先级,则会进入硬件阶段。在硬件阶段,仲裁器会对DMA请求进行优先级排序。通常情况下,如果两个请求具有相同的软件优先级,则具有较低编号的DMA通道会被赋予较高的优先级。这意味着较低编号的DMA通道会优先获得DMA控制器的处理权。
需要注意的是,多个DMA请求通过逻辑或门输入到DMA控制器时,只能有一个请求能够被有效处理。因此,在设置DMA优先级时,需要确保合适的优先级设置以及适当的DMA请求触发条件,以便系统能够按照预期的方式处理DMA传输请求。
2.F4 / F7 / H7 DMA结构框图
(1)系统架构图
(2)F4/F7/H7 DMA功能
在STM32F4和F7系列中,DMA控制器主要是通过DMA1和DMA2来实现数据传输。它们支持以下功能:
DMA1:
内存到外设(Memory to Peripheral)传输
外设到内存(Peripheral to Memory)传输
DMA2:
内存到内存(Memory to Memory)传输
内存到外设(Memory to Peripheral)传输
外设到内存(Peripheral to Memory)传输
而在STM32H7系列中,DMA功能更加强大,具有更多的功能和灵活性:
D1域(MDMA):
内存到内存(Memory to Memory)传输
内存到外设(Memory to Peripheral)传输
外设到内存(Peripheral to Memory)传输
D2域(DMA1和DMA2):
内存到内存(Memory to Memory)传输
内存到外设(Memory to Peripheral)传输
外设到内存(Peripheral to Memory)传输
D3域(BDMA):
内存到内存(Memory to Memory)传输
内存到外设(Memory to Peripheral)传输
外设到内存(Peripheral to Memory)传输
外设到外设(Peripheral to Peripheral)传输
此外,H7系列的DMA控制器还具有双缓冲模式、突发传输等功能,以提高数据传输的效率和性能。通道请求的灵活性也得到了增强,使得DMA在处理各种数据传输任务时更加灵活和高效。
(3)F4/F7 DMA框图
在STM32F4/F7的DMA结构中,主要包括以下几个关键部分:
AHB从器件编程接口:
DMA相关的控制寄存器通过这个接口设置,用于配置DMA的工作模式、数据传输方向等。
存储器端口和外设端口:
DMA控制器有两个端口,一个用于存储器访问,另一个用于外设访问。这两个端口分别用于处理从存储器到外设或从外设到存储器的数据传输。
FIFO(First In, First Out):
DMA控制器内部有一个FIFO,通常包含4级32位存储器缓冲区。这个FIFO用作源数据传输到目标地址前的临时存储区。可以配置为FIFO模式或直接模式。在FIFO模式下,软件设置阈值,当FIFO达到阈值时触发数据传输;在直接模式下,立即启动对存储器的传输。
DMA优先级(数据流优先级):
DMA控制器中的每个数据流都有一个优先级。在软件阶段,可以通过寄存器配置优先级,通常分为非常高、高、中、低四个等级。在硬件阶段,较低编号的数据流具有较高的优先级。
DMA请求:
每个数据流与一个DMA请求相关联,可以从8个通道中选出DMA请求。这些请求来自于外设,表示外设需要进行数据传输操作。
通过以上结构,DMA控制器能够高效地管理数据传输,减轻CPU的负担,提高系统性能。
(4)F4/F7 DMA请求
在STM32F4/F7中,DMA请求管理主要涉及以下几个关键点:
DMA_SxCR控制数据流使用通道:
DMA控制寄存器(如DMA_SxCR)用于配置数据流的工作模式、数据传输方向、数据大小等参数。每个数据流都对应一个通道,通过配置这些寄存器,可以控制数据流的行为。
外设请求占用通道:
每个外设请求都会占用一个DMA通道,当外设需要进行数据传输时,它会发送一个请求,并占用一个特定的DMA通道。相同外设的不同请求可以占用不同的数据流通道。
请求占用通道的限制:
当某个外设请求使用了某个数据流的通道时,该数据流的其他通道就不能被选择,变为不可用状态。这意味着如果一个外设需要使用多个通道进行数据传输,就需要考虑通道的分配和冲突问题。
通过DMA请求的管理,可以有效地分配和利用DMA通道,确保各个外设之间的数据传输能够顺利进行,提高系统的整体性能。
(5)H7 的结构框图
在STM32H7中,DMA请求管理主要由DMAMUX(DMA Multiplexer)模块负责,具体结构如下:
1.DMA请求的分配:
数据流0~7的通道请求由DMAMUX1管理,每个数据流都有多达115个通道请求可供选择。
H7具有两个DMAMUX模块,其中DMAMUX1负责DMA1/2,而DMAMUX2负责BDMA(Basic DMA)。
2.DMAMUX的作用:
DMAMUX用于管理DMA通道的请求,它能够将外设的请求与DMA通道进行有效地映射,以满足不同外设对DMA传输的需求。通过DMAMUX的灵活配置,可以实现不同数据流通道与外设请求之间的映射关系,从而灵活地分配DMA资源,提高系统的数据传输效率。
3.多通道请求选择:
每个数据流通道可以选择多达115个通道请求,这意味着系统可以同时处理多个外设的数据传输请求,从而实现并行传输,提高系统整体性能。通过DMAMUX的灵活配置和管理,STM32H7能够高效地处理来自多个外设的DMA请求,并且能够满足复杂应用场景下的数据传输需求。
(6)DMAMUX(DMA Multiplexer)
DMAMUX(DMA Multiplexer)DMA请求复用器在STM32H7中起着关键的作用,其主要特点和功能如下:
1.外设请求:
DMAMUX接收来自外设的DMA请求信号,这些请求信号可能来自STM32H7芯片内部的不同外设模块,共有107个外设请求信号可供选择。
2.通道选择:
DMAMUX具有用于选择DMA请求通道的功能,通过配置DMAMUX,可以将外设的DMA请求信号映射到DMA控制器的具体通道上。
3.同步控制:
DMAMUX还提供了同步控制功能,用于同步DMA请求信号。这个功能可以在一定程度上优化DMA传输的效率,但在某些情况下可能不需要使用,可以关闭以节省系统资源。
4.请求信号输出:
DMAMUX最终将经过选择和同步的DMA请求信号输出给DMA控制器,由DMA控制器根据接收到的信号进行数据传输操作。
5.通道映射:
对于DMAMUX1而言,共有15个通道可供选择,分别对应DMA1的通道0-7和DMA2的通道0-7,共计15个通道。通道0-7用于DMA1,通道8-15用于DMA2。
对于DMAMUX2,通道数和通道映射情况可能有所不同,具体取决于其管理的DMA模块(比如BDMA)。
通过DMAMUX的灵活配置,可以有效管理和优化系统中的DMA请求信号,实现不同外设模块之间的数据传输需求,并且提高系统整体的性能和效率。
三.DMA相关寄存器介绍
1.DMA相关寄存器 F1
以下是STM32F1系列中与DMA相关的寄存器介绍:
1.DMA_CCRx:DMA通道x配置寄存器。用于配置DMA通道的工作模式、传输方向、数据大小、内存和外设增量模式、循环模式等参数。每个DMA通道都有一个对应的CCR寄存器。
2.DMA_ISR:DMA中断状态寄存器。用于查询当前DMA传输的状态,包括传输完成、半传输完成、传输错误等状态。
3.DMA_IFCR:DMA中断标志清除寄存器。用来清除DMA_ISR寄存器中的中断标志位,以便重新开始新的DMA传输。
4.DMA_CNDTRx:DMA通道x传输数量寄存器。用于设置DMA通道x每次传输的数据量,即传输的数据数量。
5.DMA_CPARx:DMA通道x外设地址寄存器。用于存储与DMA通道x相关联的外设的地址,指定数据的来源或目的地。
6.DMA_CMARx:DMA通道x存储器地址寄存器。用于存放与DMA通道x相关联的存储器的地址,指定数据的来源或目的地。
7.USART_CR3:USART控制寄存器3。用于配置USART串口的工作模式,其中包括使能串口DMA发送功能,允许USART通过DMA进行数据发送。
这些寄存器在DMA控制和配置过程中起着关键作用,通过合理设置这些寄存器的值,可以实现灵活高效的DMA数据传输操作。
2.F4 / F7 / H7 DMA相关寄存器
以下是F4/F7/H7系列的DMA相关寄存器介绍:
F4/F7/H7 DMA寄存器:
1.DMA_SxCR(DMA数据流x配置寄存器):
用于配置DMA数据流的控制参数,包括传输方向、数据大小、传输模式、循环模式等。
2.DMA_(H/L)ISR(DMA(低/高)中断状态寄存器):
用于查询当前DMA传输状态和中断标志,包括传输完成、传输错误等。
3.DMA_(H/L)IFCR(DMA(低/高)中断标志清除寄存器):
用来清除DMA_(H/L)ISR中对应的中断标志位。
4.DMA_SxNDTR(DMA数据流x传输数量寄存器):
用于设置DMA数据流x每次传输的数据量,即传输的数据大小。
5.DMA_SxPAR(DMA数据流x外设地址寄存器):
用于存储外设的地址,DMA将从这个地址读取数据进行传输。
6.DMA_SxM0AR(DMA数据流x存储器地址寄存器):
用于存放存储器的地址,DMA将把数据传输到这个地址。
H7 DMAMUX寄存器:
对于H7系列的DMAMUX,只需要了解DMAMUX请求发生器通道x配置寄存器的使用即可,具体寄存器名称和作用可能与DMA控制器的寄存器有所不同,但作用是用于配置DMAMUX通道和DMA控制器之间的连接关系,从而实现DMA请求的管理和分配。
四.DMA相关HAL库驱动介绍
4.1、DMA相关HAL库驱动 F1
以下是STM32F1系列中与DMA相关的HAL库驱动介绍:
__HAL_RCC_DMAx_CLK_ENABLE(...): 该函数用于使能DMAx时钟,其中x表示DMA控制器的编号。通过该函数可以启用对应DMA控制器的时钟。
HAL_DMA_Init(...): 该函数用于初始化DMA传输通道。通过配置DMA_InitTypeDef结构体中的参数,可以初始化DMA通道的工作模式、传输方向、数据大小、内存和外设增量模式等。
HAL_DMA_Start_IT(...): 该函数用于启动DMA传输,并通过中断方式进行传输。它需要配置DMA传输通道的相关寄存器,包括CCR寄存器、CPAR寄存器、CMAR寄存器和CNDTR寄存器。
__HAL_LINKDMA(...): 该函数用于将DMA传输通道与外设句柄连接起来,以便外设能够通过DMA进行数据传输。
HAL_UART_Transmit_DMA(...): 该函数用于启用USART串口的DMA发送功能,并启动数据传输。它需要配置DMA传输通道的相关寄存器以及USART的CR3寄存器,以使能DMA发送。
__HAL_DMA_GET_FLAG(...): 该函数用于查询DMA传输通道的状态,可以检查DMA_ISR寄存器中的中断标志位,以确定DMA传输是否完成或出现错误。
__HAL_DMA_ENABLE(...) 和 __HAL_DMA_DISABLE(...): 这两个函数分别用于使能和失能DMA外设。它们通过设置DMA通道的CCR寄存器中的EN位来控制DMA外设的使能状态。
此外,还有两个与DMA相关的结构体:DMA_HandleTypeDef 和 DMA_InitTypeDef。DMA_HandleTypeDef结构体用于存储DMA传输通道的相关信息,而DMA_InitTypeDef结构体用于配置DMA传输通道的初始化参数。
4.2、F4 / F7 / H7 DMA相关HAL库驱动
以下是F4/F7/H7系列的DMA相关HAL库驱动函数介绍:
F4/F7/H7 DMA HAL库驱动:
__HAL_RCC_DMAx_CLK_ENABLE(...):
关联寄存器:RCC_AHBENR
功能描述:使能指定的DMA时钟。
HAL_DMA_Init(...):
关联寄存器:DMA_SxCR
功能描述:初始化DMA数据流配置,包括传输方向、数据大小、传输模式等参数的设置。
HAL_DMA_Start_IT(...):
关联寄存器:DMA_SxCR、DMA_SxPAR、DMA_SxM0AR、DMA_SxNDTR
功能描述:开始DMA传输,并启用中断进行传输完成等事件的处理。
__HAL_LINKDMA(...):
功能描述:用来连接DMA和外设句柄,建立DMA传输的关联关系。
HAL_UART_Transmit_DMA(...):
关联寄存器:DMA_SxCR、DMA_SxPAR、DMA_SxM0AR、DMA_SxNDTR、USART_CR3
功能描述:使能DMA发送,并启动传输,通常用于串口数据传输。
__HAL_DMA_GET_FLAG(...):
关联寄存器:DMA_ISR
功能描述:查询DMA传输通道的状态,例如传输完成标志等。
__HAL_DMA_ENABLE(...):
关联寄存器:DMA_CCR(EN)
功能描述:使能指定的DMA外设。
__HAL_DMA_DISABLE(...):
关联寄存器:DMA_CCR(EN)
功能描述:失能指定的DMA外设。
HAL_UART_DMAStop(...):
关联寄存器:USART_CR3
功能描述:停止DMA传输,通常用于串口DMA传输的停止。
五、DMA配置步骤
5.1、以DMA方式传输串口数据配置步骤 F1
以下是使用DMA方式传输串口数据的配置步骤:
使能DMA时钟:
使用 __HAL_RCC_DMA1_CLK_ENABLE() 函数使能DMA1的时钟,确保DMA功能正常运行。
初始化DMA:
使用 HAL_DMA_Init() 函数初始化DMA传输通道,配置DMA_InitTypeDef结构体中的参数,包括DMA模式、数据方向、数据大小、传输地址等。
连接DMA和外设:
使用 __HAL_LINKDMA() 函数将DMA传输通道与串口外设连接起来,以确保外设能够通过DMA进行数据传输。
使能串口的DMA发送并启动传输:
使用 HAL_UART_Transmit_DMA() 函数使能串口的DMA发送功能,并启动数据传输。该函数需要配置DMA传输通道的相关寄存器以及串口的CR3寄存器,以启用DMA发送。
查询DMA传输状态:
使用 __HAL_DMA_GET_FLAG() 函数查询DMA传输通道的状态,以确定传输是否完成或出现错误。
使用 __HAL_DMA_GET_COUNTER() 函数获取当前传输剩余数据量,以便监测传输进度。
DMA中断使用:
使用 HAL_NVIC_EnableIRQ() 函数使能DMA传输通道的中断,并设置优先级。
编写中断服务函数,例如 xxx_IRQHandler(),用于处理DMA传输完成或错误的中断事件。
通过以上步骤,可以实现串口数据的DMA传输,并通过中断方式进行传输状态的监测和处理。
5.2、F4 / F7/ H7 DMA配置步骤
以下是F4/F7/H7系列的DMA配置步骤:
使能DMA时钟:
__HAL_RCC_DMAx_CLK_ENABLE();
1
使用该宏使能所需的DMA时钟。
初始化DMA:
HAL_DMA_Init(&hdma); // hdma为DMA_HandleTypeDef类型的结构体变量,其中包含DMA的配置参数
1
使用HAL_DMA_Init函数初始化DMA相关参数,包括传输方向、数据大小、传输模式等。
连接DMA和外设:
__HAL_LINKDMA(huart, hdmatx, hdma_tx); // huart为UART_HandleTypeDef类型的结构体变量,hdmatx为外设的DMA传输句柄,hdma_tx为DMA的句柄
1
使用__HAL_LINKDMA函数连接DMA和外设,建立DMA传输的关联关系。
使能串口的DMA发送,启动传输:
HAL_UART_Transmit_DMA(&huart, pData, Size); // huart为UART_HandleTypeDef类型的结构体变量,pData为发送数据的指针,Size为发送数据的大小
1
使用HAL_UART_Transmit_DMA函数使能串口的DMA发送,并启动数据传输。
查询DMA传输状态:
__HAL_DMA_GET_FLAG(hdma, DMA_FLAG_TC); // hdma为DMA_HandleTypeDef类型的结构体变量,DMA_FLAG_TC为传输完成标志
1
使用__HAL_DMA_GET_FLAG函数查询DMA传输通道的状态,例如传输完成标志等。
__HAL_DMA_GET_COUNTER(hdma); // hdma为DMA_HandleTypeDef类型的结构体变量
1
使用__HAL_DMA_GET_COUNTER函数获取当前传输剩余数据量。
DMA中断使用:
HAL_NVIC_EnableIRQ(DMAx_Streamx_IRQn); // DMAx_Streamx_IRQn为DMA中断的中断号
HAL_NVIC_SetPriority(DMAx_Streamx_IRQn, 0, 0); // DMAx_Streamx_IRQn为DMA中断的中断号,0为抢占优先级,0为子优先级
1
2
使用HAL_NVIC_EnableIRQ函数使能DMA中断。
使用HAL_NVIC_SetPriority函数配置DMA中断的优先级。
编写中断服务函数:
void DMAx_Streamx_IRQHandler(void)
{
HAL_DMA_IRQHandler(&hdma); // hdma为DMA_HandleTypeDef类型的结构体变量
}
1
2
3
4
编写DMA中断服务函数,处理DMA中断事件。
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/m0_62140641/article/details/136411996