DMA英文全称是Direct Memory Access,意思是直接存储器访问。
他的作用就是不需要经过CPU进行数据传输,也就是替CPU分担点事情做,什么事情?数据传输方面的事情。也就是说,你只要使能并配置好了DMA,DMA就可以将一批数据从源地址搬运到目的地址去而不经过CPU的干预,这样可以为CPU节省好多精力去干更重要的事情很人性化。就像我们人一样,我们平常习惯性的动作是不用经过大脑思考的,比如说眨眼睛,呼吸等。DMA就是负责这些工作的,但它没人这么智能,需要将它设置好了它才会正常工作。
要进行数据传输就必须有两个条件:数据从哪传(源地址),数据传到哪里去(目的地址)。是的DMA的确有这两项设置,通过软件设置,设置好源地址和目的地址。在一个重要的条件就是触发源是什么,就是说什么时候进行DMA数据传输呢?这叫触发信号。也可以通过软件编程设置具体时间,具体条件来触发DMA数据传输。
总之,要使用DMA就要将各种参数,条件配置好才可以用。就提的DMA寄存器说明见STM32的参考手册。下面举一简单的历程来说明DMA的用法,本历程将串口数据发送设置为DMA模式,串口1将持续从RAM中的一段连续的地址中取数据,然后发送出去。用串口调试助手可以监测DMA的工作和CPU互不冲突,串口发送就相当于后台运行的一段程序。具体配置如下:
DMA发送的配置步骤如下:
- 在DMA_CPARx寄存器中设置外设寄存器的地址。发生外设数据传输请求时,这个地址将是数据传输的源或目标。
- 在DMA_CMARx寄存器中设置数据存储器的地址。发生外设数据传输请求时,传输的数据将从这个地址读出或写入这个地址。
- 在DMA_CNDTRx 寄存器中设置要传输的数据量。在每个数据传输后,这个数值递减。
- 在DMA_CCRx寄存器的PL[1:0]位中设置通道的优先级。
- 在DMA_CCRx寄存器中设置数据传输的方向、循环模式、外设和存储器的增量模式、外设和存储器的数据宽度、传输一半产生中断或传输完成产生中断。
- 设置DMA_CCRx寄存器的ENABLE 位,启动该通道。 一旦启动了DMA通道,它既可响应联到该通道上的外设的DMA请求。 当传输一半的数据后,半传输标志(HTIF) 被置1 ,当设置了允许半传输中断位(HTIE) 时,将产生一个中断请求。在数据传输结束后,传输完成标志(TCIF) 被置1 ,当设置了允许传输完成中断位
(TCIE) 时,将产生一个中断请求。
对于stm32一些外设的地址,参看stm32参考手册的存储器映像就可以了。
还有STM32 DMA通道的选择表
在使能DMA的时候千万不要忘记了时钟的配置。
以下是DMA的一些基本概念:
一般芯片的dma有基本功能:
1、普通的内存、外设间互传数据,一次性的。
2、支持链表的,美其名曰“scatter”,内核有struct scatter可以参考。
说一下注意点:
dma有burst、burst size、transfer的概念:
burst:
dma实际上是一次一次的申请总线,把要传的数据总量分成一个一个小的数据块。比如要传64个字节,那么dma内部可能分为2次,一次传 64/2=32个字节,这个2(a)次呢,就叫做burst。这个burst是可以设置的。这32个字节又可以分为32位 * 8或者16位*16来传输。
transfer size:
就是数据宽度,比如8位、32位,一般跟外设的FIFO相同。
burst size:
就是一次传几个 transfer size.
现在我配置数据宽度为32位。一次传8个32位=32个字节。
那么如果总长度为128字节,那么实际dma设置的长度为 128/32 = 4.