STM32篇八:DMA

1、DMA概念

“Direct Memory Access(存储器直接访问)。这是指一种高速的数据传输操作,允许在外部设备和存储器之间直接读写数据。整个数据传输操作在一个称为"DMA控制器"的控制下进行的。CPU除了在数据传输开始和结束时做一点处理外(开始和结束时候要做中断处理),在传输过程中CPU可以进行其他的工作(前提是未设置停止CPU访问)。这样,在大部分时间里,CPU和输入输出都处于并行操作。因此,使整个计算机系统的效率大大提高”。

DMA传送方式是让存储器与外设、或外设与外设之间直接交换数据,不需要经过CPU的累加器中转,减少了这个中间环节,并且内存地址的修改、传送完毕的结束报告都是由硬件电路实现的,因此大大地提高了数据的传输速度。一个DMA传送只需要执行一个DMA周期,相当于一个总线读写周期。

DMA是在专门的硬件( DMA)控制下,实现高速外设和主存储器之间自动成批交换数据尽量减少CPU干预的输入/输出操作方式。

2、DMA适用场景

DMA方式主要适用于一些高速的I/O设备。这些设备传输字节或字的速度非常快。对于这类高速I/O设备,如果用输入输出指令或采用中断的方法来传输字节信息,会大量占用CPU的时间,同时也容易造成数据的丢失。而DMA方式能使I/O设备直接和存储器进行成批数据的快速传送。

DMA传送主要用于需要高速大批量数据传送的系统中,以提高数据的吞吐量。如磁盘存取、图像处理、高速数据采集系统、同步通信中的收/发信号等方面应用甚广。通常只有数据流量较大(kBps或者更高)的外设才需要支持DMA能力,这些应用方面典型的例子包括视频、音频和网络接口。

3、STM32f10x的DMA功能框图

在这里插入图片描述

  • 12个独立的可配置的通道(请求):DMA1有7个通道,DMA2有5个通道

  • 每个通道都直接连接专用的硬件DMA请求,每个通道都同样支持软件触发。这些功能通过 软件来配置。

  • 在同一个DMA模块上,多个请求间的优先权可以通过软件编程设置(共有四级:很高、高、 中等和低),优先权设置相等时由硬件决定(请求0优先于请求1,依此类推) 。

  • 独立数据源和目标数据区的传输宽度(字节、半字、全字),模拟打包和拆包的过程。源和目 标地址必须按数据传输宽度对齐。

  • 支持循环的缓冲器管理

  • 每个通道都有3个事件标志(DMA半传输、DMA传输完成和DMA传输出错),这3个事件标志 逻辑或成为一个单独的中断请求。

  • 存储器和存储器间的传输

  • 外设和存储器、存储器和外设之间的传输

  • 闪存、SRAM、外设的SRAM、APB1、APB2和AHB外设均可作为访问的源和目标。

  • 可编程的数据传输数目:最大为65535 。

4、DMA通道配置

1、在DMA_CPARx寄存器中设置外设寄存器的地址。发生外设数据传输请求时,这个地址将 是数据传输的源或目标

2、在DMA_CMARx寄存器中设置数据存储器的地址。发生外设数据传输请求时,传输的数 据将从这个地址读出或写入这个地址

3、在DMA_CNDTRx寄存器中设置要传输的数据量。在每个数据传输后,这个数值递减。

4、在DMA_CCRx寄存器的PL[1:0]位中设置通道的优先级。

5、在DMA_CCRx寄存器中设置数据传输的方向、循环模式、外设和存储器的增量模式、外 设和存储器的数据宽度、传输一半产生中断或传输完成产生中断

6、设置DMA_CCRx寄存器的ENABLE位,启动该通道。

5、DAM中断

在这里插入图片描述

6、DMA通道

在这里插入图片描述
在这里插入图片描述

7、DMA寄存器

  • DMA中断状态寄存器(DMA_ISR)
  • DMA中断标志清除寄存器(DMA_IFCR)
  • DMA通道x配置寄存器(DMA_CCRx)(x = 1…7)
  • DMA通道x传输数量寄存器(DMA_CNDTRx)(x = 1…7)
  • DMA通道x外设地址寄存器(DMA_CPARx)(x = 1…7)
  • DMA通道x存储器地址寄存器(DMA_CMARx)(x = 1…7)

8、DMA标准库

typedef struct
{
  uint32_t DMA_PeripheralBaseAddr;		// 指定DMAy Channelx的外设基地址
  uint32_t DMA_MemoryBaseAddr;     		// 指定DMAy Channelx的内存基址
  uint32_t DMA_DIR;            			// 指定外围设备是源还是目标(值见DMA_data_transfer_direction)
  uint32_t DMA_BufferSize;        		// 指定指定通道的缓冲区大小(以数据为单位)
  				// 数据单位等于DMA_PeripheralDataSize或DMA_MemoryDataSize成员中设置的配置,具体取决于传输方向
  uint32_t DMA_PeripheralInc;      		// 指定外设地址寄存器是否递增(值见DMA_peripheral_incremented_mode)
  uint32_t DMA_MemoryInc;        		// 指定内存地址寄存器是否递增(值见DMA_memory_incremented_mode)
  uint32_t DMA_PeripheralDataSize; 		// 指定外设数据宽度(值见DMA_peripheral_data_size)
  uint32_t DMA_MemoryDataSize;     		// 指定内存数据宽度(值见DMA_memory_data_size)
  uint32_t DMA_Mode;              		// 指定DMAy Channelx的操作模式(值见DMA_circular_normal_mode)
    									// 如果在所选通道上配置了内存到内存的数据传输,则无法使用循环缓冲区模式
  uint32_t DMA_Priority;          		// 指定DMAy Channelx的软件优先级(值见DMA_priority_level)
  uint32_t DMA_M2M;                	// 指定是否在内存到内存传输中使用DMAy Channelx(值见DMA_memory_to_memory)
}DMA_InitTypeDef;
DMA_data_transfer_direction:
    
#define DMA_DIR_PeripheralDST              ((uint32_t)0x00000010)		// 传输方向为内存到外设
#define DMA_DIR_PeripheralSRC              ((uint32_t)0x00000000)		// 传输方向外设到内存
DMA_peripheral_incremented_mode:

#define DMA_PeripheralInc_Enable           ((uint32_t)0x00000040)		// 外设地址递增
#define DMA_PeripheralInc_Disable          ((uint32_t)0x00000000)		// 外设地址非递增
DMA_memory_incremented_mode:

#define DMA_MemoryInc_Enable               ((uint32_t)0x00000080)		// 存储地址递增
#define DMA_MemoryInc_Disable              ((uint32_t)0x00000000)		// 存储地址非递增
DMA_peripheral_data_size:

#define DMA_PeripheralDataSize_Byte        ((uint32_t)0x00000000)		// 外设数据宽度-字节
#define DMA_PeripheralDataSize_HalfWord    ((uint32_t)0x00000100)		// 外设数据宽度-半字
#define DMA_PeripheralDataSize_Word        ((uint32_t)0x00000200)		// 外设数据宽度-字
DMA_memory_data_size:

#define DMA_MemoryDataSize_Byte            ((uint32_t)0x00000000)		// 外设数据宽度-字节
#define DMA_MemoryDataSize_HalfWord        ((uint32_t)0x00000400)		// 外设数据宽度-半字
#define DMA_MemoryDataSize_Word            ((uint32_t)0x00000800)		// 外设数据宽度-字
DMA_circular_normal_mode:

#define DMA_Mode_Circular                  ((uint32_t)0x00000020)		// 循环模式
#define DMA_Mode_Normal                    ((uint32_t)0x00000000)		// 非循环模式
DMA_priority_level:

#define DMA_Priority_VeryHigh              ((uint32_t)0x00003000)		// 非常高
#define DMA_Priority_High                  ((uint32_t)0x00002000)		// 高
#define DMA_Priority_Medium                ((uint32_t)0x00001000)		// 中
#define DMA_Priority_Low                   ((uint32_t)0x00000000)		// 低
DMA_memory_to_memory:

#define DMA_M2M_Enable                     ((uint32_t)0x00004000)		// 开启内存到内存
#define DMA_M2M_Disable                    ((uint32_t)0x00000000)		// 关闭内存到内存
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值