目录
一、认识 DMA
DMA (Direct Memory Access,直接存储器访问)控制器独立于内核,属于一个单独的外设,它的主要功能是传输数据,但是不需要占用CPU,即在它传输数据的时候,CPU可以干其他的事情,就像多线程一样。
数据传输支持从外设到存储器或者从存储器到存储器,这里的存储器可以是SRAM或者Flash存储器。DMA控制器包含了DMA1和DMA2,其中DMA1有7个通道,DMA2有5个通道,这里的通道可以理解为传输数据的一种管道。
补:DMA2只存在于大容量的单片机中。
二、DMA结构
1. DMA请求
外设要想通过DMA来传输数据,必须先向DMA控制器发送DMA请求,DMA收到请求信号之后,控制器会给外设一个应答信号,当外设应答且DMA控制器收到应答信号之后,就会启动DMA的传输,直到传输完毕。
DMA有DMA1和DMA2两个控制器,DMA1有7个通道,DMA2有5个通道,不同DMA控制器的通道对应不同的外设请求。
2. 通道DMA
有12个独立可编程的通道,DMA1有7个通道,DMA2有5个通道,每个通道对应不同外设的DMA请求。虽然每个通道可以接收多个外设的请求,但是同一时间只能接收一个,不能同时接收多个。
补:通道配置过程。
① 在 DMA_CPARx寄存器 中设置外设寄存器的地址。发生外设数据传输请求时,这个地址将是数据传输的源或目标。
② 在 DMA_CMARx奇存器 中设置数据存储器的地址。发生外设数据传输请求时,传输的数据将从这个地址读出或写入。
③ 在 DMA_CNDTRx寄存器 中设置要传输的数据量。在每个数据传输后,这个数值递减。
④ 在 DMA_CCRx寄存器的 PL[1:0]位 中设置通道的优先级。
⑤ 在 DMA_CCRx寄存器 中设置数据传输的方向、循环模式、外设和存储器的增量模式、外设和存储器的数据宽度、传输一半产生中断或传输完成产生中断。
⑥ 设置 DMA_CCRx寄存器的ENABLE位,启动该通道。
3. 仲裁器
解决请求先后响应顺序的问题,由仲裁器管理。管理DMA请求分为两个阶段:第1阶段属于软件阶段,可以在DMA_CCRx寄存器中设置,有4个等级:非常高、高、中和低;第2阶段属于硬件阶段,如果两个或以上的DMA请求设置的优先级一样,则它们的优先级取决于通道编号,编号越低越优先级越。
补:在大容量产品和互联型产品中,DMA1控制器拥有高于DMA2控制器的优先级。
三、DMA数据配置
1. 从哪里来,到哪里去
DMA传输数据的方向有3个: 从外设到存储器,从存储器到外设,从存储器到存储器。具体的方向由DMA_CCR中第4位的DIR配置:0表示从外设到存储器,1表示从存储器到外设。里面涉及的外设地址由DMA_CPAR配置,存储器地址由DMA_CMAR配置。
(1)从外设到存储器
以ADC采集为例。DMA外部寄存器的地址对应的就是ADC数据寄存器的地址,DMA存储器的地址就是我们自定义的变量 ( 用来接收、存储ADC采集的数据 )的地址。方向设置外设为源地址。
(2)从存储器到外设
以串口向电脑端发送数据为例。DMA外部寄存器的地址对应的就是串口数据寄存器的地址,DMA存储器的地址就是我们自定义的变量( 相当于一个缓冲区,用来存储通过串口发送到电脑的数据 )的地址。方向设置外设为目标地址。
(3)从存储器到存储器
以内部Flash存储器向内部SRAM复制数据为例。DMA外部寄存器的地址对应的就是内部Flash存储器(把内部Flash当作一个外设来看)的地址,DMA存储器的地址就是我们自定义的变量( 相当于一个缓冲区,用来存储来自内部Flash存储器的数据 )的地址。方向设置外设(内部Flash存储器)为源地址。与上面两个不同的是,还要把DMA_CCR中的第14位(MEM2MEM)存储器到存储器模式配置为1,启动存储器到存储器模式。
2. 要传多少,单位是什么
以串口向电脑发送数据为例,可以一次性给电脑发送很多数据,具体多少由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。而串口数据寄存器只有一个,那么外设的地址指针就固定不变。
补:指针增量。
通过设置 DMA_CCRx寄存器中的PINC和MINC 标志位,外设和存储器的指针在每次传输后可以有选择地完成自动增量。
① 通道配置为增量模式:下一个要传输的地址将是前一个地址加上增量值( 增量值取决与所选的数据宽度:1、2、4)。第一个传输的地址是存放在 DMA_CPARx / DMA_CMARx寄存器 中。在传输过程中,这些寄存器保持它们初始的数值,软件不能改变和读出当前正在传输的地址(在内部的当前外设/存储器地址寄存器中)。
② 通道配置为非循环模式:传输结束后(即传输计数变为0)将不再产生DMA操作,要开始新的DMA传输,需要在关闭DMA通道的情况下,在 DMA_CNDTRx奇存器 中重新写入传输数目。
③ 循环模式:最后一次传输结束时,DMA_CNDTRx寄存器 的内容会自动地被重新加载为其初始数值,内部的当前外设 / 存储器地址寄存器也被重新加载为 DMA_CPARx / DMA_CMARx寄存器 设定的初始基地址。
3. 什么时候传输完成
可以通过查询标志位或者通过中断的方式来鉴别。每个DMA通道在DMA传输过半、传输完成和传输错误时都会有相应的标志位(DMA中断状态寄存器DMA_ISR),如果使能了该类型的中断后,则会产生中断。
传输的完成还分两种模式:一次传输和循环传输。一次传输,即传输一次之后就停止,要想再传输的话,必须关闭DMA使能后再重新配置,才能继续传输。循环传输则是一次传输完成之后又恢复第一次传输时的配置,循环传输不断重复。具体的模式由DMA_CCRx寄存器的CIRC循环模式位控制。
可以结合这篇文章:
嵌入式一直接存储器存取(DMA)