DMA介绍、原理、工作模式

本文介绍了DMA(直接存储器访问)技术,它能实现无需CPU干预的数据传输,包括传输方式、通道管理、仲裁机制、传输模式和中断配置,以及STM32中的应用实例和注意事项。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

写在前面:个人学习总结,小白,不喜勿喷,欢迎指正。

1、什么是DMA

DMA,全称Direct Memory Access,直接存储器访问。DMA将数据从一个内存地址复制到另一个内存地址的操作,当然不仅仅局限于内存到内存,也可以外设和内存之间相互访问。

那么DMA进行数据的搬移和普通通信方式(IIC、SPI)想比区别在哪,普通通信方式IIC或者SPI或多或少的到需要CPU的参与,CPU控制收发、读写,而DMA在进行数据传输的时候不需要CPU参与,因此大大降低了CPU的工作量

2、DMA的传输方式

分为四种情况,外设到内存、内存到外设、内存到内存、外设到外设。DMA传输有专门的传输通道,以STM32为例

        如图所示,DMA1和DMA2,其中DMA1有7条通道,DMA2有5条通道。每个通道对应不同的外设DMA请求,并且每个通道可能可以接收多个外设的请求,但是在同一时间只能接收一个DMA请求,不能接收多个请求。如果外设想通过DMA传输数据,必须先给DMA控制器发送请求,DMA收到请求信号之后,控制器会给外设一个应答信号,当外设接到应答信号后,才会启动DAM传输。

3、 仲裁器

        在某一时刻,DMA控制器可能会接收到多个DAM请求,那么控制器先响应谁后响应谁是怎么规定的?这就引入一个新的概念:仲裁器。

 

        仲裁器管理DMA请求分为两个阶段:软件阶段和硬件阶段。

软件阶段可以通过寄存器(DMA_CCRx)设置等级:非常高、高、中、低四个等级。

硬件阶段优先级不可更改:如果两个DMA通道等级在软件阶段设置的一样,比如都为高,那么在硬件阶段优先级取决于通道编号,编号越低优先级越高(通道1大于通道2 类推),如果有两个DAM(例如32ZET6),那么DMA1大于DMA2。

4、DMA传输方式

共有两种传输模式:正常模式(其实就是单次传输)、循环传输模式(重新装载数据多次)。

正常模式(Normal):当设置好DMA源地址、目标地址、传输方向,数据量时,DMA一次将需要发送的数据全部发送过去。

循环传输模式(Circular):当一次数据传输结束后,重新装载数据,再次开始传输,知道数据传输完成。

5、DMA中断

        每个DMA通道都可以在DMA传输过半、传输完成和传输错误时产生中断,中断可以通过寄存器配置打开。

 则在DMA传输过程中,可以通过对DMA中断位查询来获得DMA传输状态。

6、DMA配置

        DAM请求通过之后,DMA开始传输之前,还需要了解:数据从哪里来(源地址)、到哪里去(目标地址)?以ADC采集数据为例,那源地址就是ADC的数据寄存器地址,目标地址就是我们自己定义的变量,可以是flash,SRAM,也可以是我们自己定义的临时区间RAM。要传输多少数据?传输数据的单位是什么(数据宽度8位、16位?)?传输多少次?设置好传输数据位宽,数据量,传输模式。当这些设定好之后就可以开始传输,我们可以利用中断传输,当传输次数达到设定值或者剩余传输数据量为0就停止传输。

以STM32为例:

 

 

注意事项:

1、地址的自增,因为数据传输地址可能不是固定的,比如ADC数据到内存,那么从ADC中获取数据的地址是固定的,但是目标内存的地址要自增,不然下次DAM传输的数据就会覆盖掉之前的数据。

2、DMA进行数据的传输是需要总线的,因此总线在DMA工作时是分时复用的。比如1时刻ARM正在正常运行,此时CPU占用总线;2时刻,DAM控制器接收到DMA请求,开始DAM传输,此时CPU释放总线,DAM占用总线进行传输;3DMA传输完成,释放总线,此时CPU重新获取总线。

### DMA工作原理详解 DMA(Direct Memory Access)是一种数据传输机制,允许外设与内存之间或内存与内存之间直接进行高速数据传输,而无需CPU干预。该机制显著提高了系统的性能和效率,尤其适用于大数据量传输的场景。 #### DMA系统架构 DMA控制器作为系统中的一个独立硬件模块,通常包含多个通道,每个通道可以处理不同的数据传输请求。在STM32等嵌入式系统中,DMA控制器连接了多种外设(如SPI、I2C、ADC等),并通过总线接口与系统内存通信[^1]。 DMA控制器的核心功能包括: - **地址管理**:负责源地址和目标地址的递增或固定。 - **数据传输**:根据配置的传输模式(单次传输、循环传输等)将数据从源端搬运到目标端。 - **中断生成**:当传输完成或发生错误时,DMA控制器会触发相应的中断通知CPU。 #### 为什么使用多个DMA控制器? 在一些高性能MCU中,例如STM32系列,通常集成两个DMA控制器(DMA1和DMA2)。这种设计的主要原因如下: - 单个DMA控制器的通道数量有限,无法满足所有外设的需求。 - 使用两路DMA可以扩展支持更多的外设DMA请求源。 - 两路DMA在访问内存和外设时具有一定的空间区分,能够并行工作,从而提高整体系统的效率[^1]。 #### 链式DMA传输 链式DMA(Scatter-Gather DMA)是一种高级的数据传输方式,用于处理非连续物理内存块之间的数据传输。通过链式DMA,可以将多个离散的内存块用描述符进行描述,并形成一个描述符表。DMA控制器只需知道第一个描述符的地址,就可以依次完成所有内存块的传输,极大提升了传输效率[^2]。 链式DMA的关键组成部分是**描述符**(Descriptor),它通常包含以下信息: - 数据块的物理地址 - 数据块大小 - 下一个描述符的地址 DMA控制器通过遍历描述符表来逐个处理每个数据块,直到所有数据都传输完毕。这种方式避免了频繁的CPU干预,使得大规模数据传输更加高效可靠。 #### DMA传输流程 DMA传输的基本流程如下: 1. **初始化DMA控制器**:配置DMA通道的源地址、目标地址、数据长度、传输模式以及是否启用中断等参数。 2. **启动DMA传输**:由外设或软件触发DMA请求,DMA控制器开始执行数据搬运任务。 3. **自动传输数据**:DMA控制器接管总线控制权,在源和目标之间直接传输数据,无需CPU参与。 4. **传输结束处理**:当数据传输完成后,DMA控制器会发出中断信号,通知CPU传输已完成或出现错误。 #### 示例代码 以下是一个简单的DMA配置示例,展示如何在STM32上配置DMA1通道4以实现内存到外设的数据传输: ```c #include "stm32f10x.h" #define BUFFER_SIZE 16 uint8_t srcBuffer[BUFFER_SIZE] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10}; void DMA_Config(void) { // 使能DMA1时钟 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); DMA_InitTypeDef DMA_InitStructure; // 设置DMA通道4 DMA_DeInit(DMA1_Channel4); // 配置DMA参数 DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART1->DR; // 外设地址 DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)srcBuffer; // 内存地址 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; // 方向:内存到外设 DMA_InitStructure.DMA_BufferSize = BUFFER_SIZE; // 缓冲区大小 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; // 外设地址不增加 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; // 内存地址递增 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; // 每次传输1字节 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; // 正常模式 DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; // 禁用内存到内存传输 // 初始化DMA通道4 DMA_Init(DMA1_Channel4, &DMA_InitStructure); // 使能DMA通道4 DMA_Cmd(DMA1_Channel4, ENABLE); } ``` 上述代码展示了如何配置DMA1 Channel4将一个内存缓冲区的数据发送到USART1的数据寄存器中。实际应用中,还需结合NVIC中断服务程序来处理DMA传输完成后的回调操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值