1.DMA简介
 
    DMA(Direct Memory Access) 
 —直接存储器存取,是单片机的一个外设,它的主要功能是用来搬数 据,但是不需要占用 CPU 
 ,即在传输数据的时候, 
 CPU  
 可以干其他的事情,好像是多线程一样。 数据传输支持从外设到存储器或者存储器到存储器,这里的存储器可以是 SRAM  
 或者是  
 FLASH 
 。 DMA 控制器包含了  
 DMA1  
 和  
 DMA2 
 ,其中  
 DMA1  
 有  
 7  
 个通道, 
 DMA2  
 有  
 5  
 个通道,这里的通道 可以理解为传输数据的一种管道。要注意的是 DMA2  
 只存在于大容量的单片机中。  
 
 
2.DMA 功能框图
 
 DMA  
 控制器独立于内核,属于一个单独的外设,结构比较简单,从编程的角度来看,我们只需  
 
 
 掌握功能框图中的三部分内容即可,具体见图  
 DMA  
 框图  
 : 
 DMA  
 控制器的框图。  
 
 
 
 
 
 2.1DMA 请求 
 
 
  如果外设要想通过  
  DMA  
  来传输数据,必须先给  
  DMA  
  控制器发送  
  DMA  
  请求, 
  DMA  
  收到请求信  
 
 
  
  号之后,控制器会给外设一个应答信号,当外设应答后且  
  DMA  
  控制器收到应答信号之后,就会  
 
 
  
  启动  
  DMA  
  的传输,直到传输完毕。  
 
 
  
  DMA  
  有  
  DMA1  
  和  
  DMA2  
  两个控制器, 
  DMA1  
  有  
  7  
  个通道, 
  DMA2  
  有  
  5  
  个通道,不同的  
  DMA  
  控  
 
 
  
  制器的通道对应着不同的外设请求,这决定了我们在软件编程上该怎么设置,具体见  
  DMA  
  请求 
 
 
  
  
 
  
  2.3通道 
    
 
 
  
   DMA  
   具有  
   12  
   个独立可编程的通道,其中  
   DMA1  
   有  
   7  
   个通道, 
   DMA2  
   有  
   5  
   个通道,每个通道对  
  
 
   
   应不同的外设的  
   DMA  
   请求。虽然每个通道可以接收多个外设的请求,但是同一时间只能接收一  
  
 
   
   个,不能同时接收多个。 
  
 
  
  2.4仲裁器 
 
 
  
  
   当发生多个  
   DMA  
   通道请求时,就意味着有先后响应处理的顺序问题,这个就由仲裁器也管理。  
  
 
   
   仲裁器管理  
   DMA  
   通道请求分为两个阶段。第一阶段属于软件阶段,可以在  
   DMA_CCRx  
   寄存器  
  
 
   
   中设置,有  
   4  
   个等级:非常高、高、中和低四个优先级。第二阶段属于硬件阶段,如果两个或以  
  
 
   
   上的  
   DMA  
   通道请求设置的优先级一样,则他们优先级取决于通道编号,编号越低优先权越高,  
  
 
   
   比如通道  
   0  
   高于通道  
   1 
   。在大容量产品和互联型产品中, 
   DMA1  
   控制器拥有高于  
   DMA2  
   控制器的  
  
 
   
   优先级。 
  
 
   
   
   2.5DMA 数据配置 
  
 
   
   
    使用  
    DMA 
    ,最核心就是配置要传输的数据,包括数据从哪里来,要到哪里去,传输的数据的单  
   
 
    
    位是什么,要传多少数据,是一次传输还是循环传输等等。 
   
 
  
  3.1 
 
 
  我们知道  
  DMA  
  传输数据的方向有三个:从外设到存储器,从存储器到外设,从存储器到存储器。  
 
 
  
  具体的方向  
  DMA_CCR  
  位  
  4 DIR  
  配置: 
  0  
  表示从外设到存储器, 
  1  
  表示从存储器到外设。这里面  
 
 
  
  涉及到的外设地址由  
  DMA_CPAR  
  配置,存储器地址由  
  DMA_CMAR  
  配置。  
 
 
  
  外设到存储器  
 
 
  
  当我们使用从外设到存储器传输时,以  
  ADC  
  采集为例。 
  DMA  
  外设寄存器的地址对应的就是  
  ADC  
 
 
  
  数据寄存器的地址, 
  DMA  
  存储器的地址就是我们自定义的变量(用来接收存储  
  AD  
  采集的数据)  
 
 
  
  的地址。方向我们设置外设为源地址。  
 
 
  
  
   存储器到外设  
  
 
   
   当我们使用从存储器到外设传输时,以串口向电脑端发送数据为例。 
   DMA  
   外设寄存器的地址对  
  
 
   
   应的就是串口数据寄存器的地址, 
   DMA  
   存储器的地址就是我们自定义的变量(相当于一个缓冲  
  
 
   
   区,用来存储通过串口发送到电脑的数据)的地址。方向我们设置外设为目标地址。  
  
 
   
   存储器到存储器  
  
 
   
   当我们使用从存储器到存储器传输时,以内部  
   FLASH  
   向内部  
   SRAM  
   复制数据为例。 
   DMA  
   外设寄  
  
 
   
   存器的地址对应的就是内部  
   FLASH 
   (我们这里把内部  
   FALSH  
   当作一个外设来看)的地址, 
   DMA  
  
 
   
   存储器的地址就是我们自定义的变量(相当于一个缓冲区,用来存储来自内部  
   FLASH  
   的数据)  
  
 
   
   的地址。方向我们设置外设(即内部  
   FLASH 
   )为源地址。跟上面两个不一样的是,这里需要把  
  
 
   
   DMA_CCR  
   位  
   14 
   : 
   MEM2MEM 
   :存储器到存储器模式配置为  
   1 
   ,启动  
   M2M  
   模式。 
  
 
   
   
   2.6 
   要传多少,单位是什么 
  
 
   
   
    当我们配置好数据要从哪里来到哪里去之后,我们还需要知道我们要传输的数据是多少,数据的  
   
 
    
    单位是什么。  
   
 
    
    以串口向电脑发送数据为例,我们可以一次性给电脑发送很多数据,具体多少由  
    DMA_CNDTR  
   
 
    
    配置,这是一个  
    32  
    位的寄存器,一次最多只能传输  
    65535  
    个数据。  
   
 
    
    要想数据传输正确,源和目标地址存储的数据宽度还必须一致,串口数据寄存器是  
    8  
    位的,所以  
   
 
    
    我们定义的要发送的数据也必须是  
    8  
    位。外设的数据宽度由  
    DMA_CCRx  
    的  
    PSIZE[1:0]  
    配置,可  
   
 
    
    以是  
    8/16/32  
    位,存储器的数据宽度由  
    DMA_CCRx  
    的  
    MSIZE[1:0]  
    配置,可以是  
    8/16/32  
    位。  
   
 
    
    在  
    DMA  
    控制器的控制下,数据要想有条不紊的从一个地方搬到另外一个地方,还必须正确设置  
   
 
    
    两边数据指针的增量模式。外设的地址指针由  
    DMA_CCRx  
    的  
    PINC  
    配置,存储器的地址指针由  
   
 
    
    MINC  
    配置。以串口向电脑发送数据为例,要发送的数据很多,每发送完一个,那么存储器的地  
   
 
    
    址指针就应该加  
    1 
    ,而串口数据寄存器只有一个,那么外设的地址指针就固定不变。具体的数据  
   
 
    
    指针的增量模式由实际情况决定。  
   
 
  


















