DMA详解

什么是DMA?

DMA,全称为Direct Memory Access, 直接存储器访问. 用于在外设与存储器之间以及存储器与存储器之间提供高速数据传
输。可以在无需任何 CPU 操作的情况下通过 DMA 快速移动数据。这样节省的 CPU 资源可供其他操作使用。

我们知道CPU有很多功能,单片机的核心就是CPU.
CPU无时无刻不在处理着大量的事务,但有些事情却没有那么重要,比方说数据的复制和存储数据,如果我们把这部分的CPU资源拿出来,让CPU去处理其他的复杂计算事务,是不是能够更好的利用CPU的资源呢?

DMA就是基于以上设想设计的,它的作用就是解决大量数据转移过度消耗CPU资源的问题。有了DMA使CPU更专注于更加实用的操作----计算、控制等。

DMA传输参数(结构体成员):

  • 外设地址
    • 一般设置为外设的数据寄存器地址. 要是是内存到内存模式则设置为其中一个内存的寄存器地址
  • 存储器地址
    • 一般设置为我们自定义存储区的首地址,即我们存放DMA传输数据的内存地址。

比如我们定义一个u32类型数组,直接写数组首地址(直接使用数组名)即可,在DMA传输的时候就可以发送数组数据,或者把数组用来接收其他数据。

  • 传输方向
    • 外设到内存
    • 内存到外设
    • 内存到内存
      -buffer_size
    • 用来设置一次传输数据的大小
  • 外设地址增量
    • 用来设置外设地址是递增还是不变,如果设置为递增,那么下一次传输的时候地址加1。通常外设只有一个数据寄存器,所以一般不会使能该位,即配置为disable.
  • 存储器地址增量
    • 用来设置内存地址是否递增. 我们自定义的存储区一般都是存放多个数据的,所以需要使能存储器地址自动递增功能,即配置为enable。
  • 外设数据宽度
    • 外设数据宽度选择,可以为字节(8位)、半字(16位)、字(32位)
  • 传输模式
    • DMA传输模式选择,可选择一次传输或者循环传输.

比如我们要从内存(存储器)中传输64个字节到串口,如果设置为循环传输,那么它会在64个字节传输完成之后继续从内存的第一个地址传输,如此循环。

  • 通道优先级
    • 用来设置DMA通道的优先级,有低,中,高,超高四种级别。DMA优先级只有在多个DMA数据流同时使用时才有意义。
  • 内存数据宽度
    • 内存数据宽度选择,可以为字节(8位)、半字(16位)、字(32位)

常见问题:

两个数据宽度不一致时:

源数据宽度为8bit,目标地址宽度为16bit

如果源端地址宽度<目标地址宽度,如源端地址宽度=8,目标地址宽度=16,那么源端地址每次偏移为0x1,目标地址每次偏移为0x2。数据没有丢失,但会出现8位数据占16位数据的情况,而此时,配置的左对齐和右对齐就有了作用。

比方说源数据为0xB1,当目标地址宽度为16的时候,传输后结果为0x00B1

源数据宽度为16bit,目标地址宽度为8bit

如果源端地址宽度>目标地址宽度,如源端地址宽度=16,目标地址宽度=8,那么源端地址每次偏移为0x2,目标地址每次偏移为0x1。且数据会丢失!

比方说源数据为0xB1B2,当目标地址宽度为8的时候,传输后结果为0xB2,只取低位.

如果源端地址宽度=目标地址宽度,如源端地址宽度=目标地址宽度=16,那么源端地址每次偏移为0x2,目标地址每次偏移为0x2。数据没有丢失,即源数据是什么,目标数据就是什么。

仲裁器

仲裁器的作用是确定各个DMA传输的优先级

仲裁器根据通道请求的优先级来启动外设/存储器的访问。

优先权管理分2个阶段:

  • 软件:每个通道的优先权可以在寄存器中设置,有4个等级:
    • 最高优先级
    • 高优先级
    • 中等优先级
    • 低优先级;
  • 硬件:如果2个请求有相同的软件优先级,则较低编号的通道比较高编号的通道有较高的优先权。

比如:如果软件优先级相同,通道2优先于通道4。

注意: 在大容量产品和互联型产品中,DMA1控制器拥有高于DMA2控制器的优先级。

循环模式

当通道配置设定为循环模式时,在最后一次传输后DMA 通道 x 数据传输量寄存器的内容会恢复成初始值。DMA会继续进行传输

外设到存储器模式

DMA详解_第1张图片

FIFO模式

在FIFO模式下,每次产生外设请求时候,数据流都会启动数据源到FIFO的传输
当FIFO达到阈值时候,FIFO的内容移除并且存储到目标中

直接模式

不再使用FIFO的阈值级别控制: 每完成一次从外设到FIFO的数据传输后,相应额数据立即就会移出并且存储到目标中

存储器到外设模式

DMA详解_第2张图片

FIFO模式

使能这种模式时,数据流会立即启动传输,从源完全填充 FIFO。每次发生外设请求,FIFO 的内容都会移出并存储到目标中。当 FIFO 的级别小于或等于预定义的阈值级别时,将使用存储器中的数据完全重载 FIFO。

直接模式

不使用 FIFO 的阈值级别。一旦使能了数据流,DMA 便会预装载第一个数据,将其传输到内部 FIFO。一旦外设请求数据传输,DMA 便会将预装载的值传输到配置的目标。然后,它会使用要传输的下一个数据再次重载内部空 FIFO。

存储器到存储器模式

DMA详解_第3张图片
DMA 通道在没有外设请求触发的情况下同样可以工作。通过将 DMA_SxCR 寄存器中的使能位 (EN) 置 1 来使能数据流时,数据流会立即开始填充 FIFO,直至达到阈值级别。达到阈值级别后,FIFO 的内容便会移出,并存储到目标中。如果 DMA_SxNDTR 寄存器达到零或 DMA_SxCR 寄存器中的 EN 位由软件清零,传输即会停止。

使用存储器到存储器模式时,不允许循环模式和直接模式。

你可能感兴趣的:(单片机)