1.什么是DMA,有什么作用?
DMA用于在外设与存储器之间以及存储器与存储器之间提供高速数据传输。可以在无需任何 CPU 操作的情况下通过 DMA 快速移动数据。这样节省的 CPU 资源可供其它操作使用。
我们用一个现实例子来做个类比。有一家冶炼公司,每天要不断的从矿场拉矿石进入厂区冶炼,以前通过公路运送的,但是这个公路除了他家的货运车以外,还有其他车,所以一般堵车严重,交通事故频发,影响工厂生产,货运成为该公司提高产能的一大瓶颈。公司思量再三,决定出资在矿场和公司间修建一条专用铁路来运矿石。虽然修建这条铁路价格昂贵,但是修好后,运送矿石的效率大大提高,公司迅速扩大产能,很快得到回报。同时原来运送矿石这条公路,也不堵车了。这条铁路的作用其实和DMA类似。
本文通过STM32F4对DMA相关原理做个介绍。
STM32F4共有2个 DMA 控制器,每个控制器均有8个数据流,每一个 DMA 控制器都用于管理一个或多个外设的存储器访问请求。每个数据流总共可以有多达8 个通道(或称请求)。每个通道都有一个仲裁器,用于处理 DMA 请求间的优先级。
2.DMA传输过程简述
DMA传输过程说起来很简单,每个DMA有2个端口:外设端口和存储器端口,通过这两个端口可以单向传输数据。
DMA1外设端口通过AHB总线连接到外设,存储器端口通过AHB总线连接到存储器,DMA1传输方向有二种:从外设向存储器传输数据,从存储器向外设传输数据。
DMA2外设端口通过AHB总线连接到外设以及存储器,存储器端口通过AHB总线连接到存储器。DMA2传输方向有三种:从外设向存储器传输数据,从存储器向外设传输数据,存储器向存储器传输数据。
ARM Cortex-M 处理器的存储系统使用32位寻址,共有4GB地址空间。ROM、RAM、外设以及处理器内的调试支持部件的地址均映射在这4GB存储空间内。所以不论哪种传输方向,DMA数据传输的本质是将数据从4GB空间内的一个地址传输到另一个地址上。
两个DMA各有1个4字(1字=4字节)大小的缓冲区(FIFO),用于数据在传输到目标之前,临时存储这些数据。缓冲区有一个可配置的阈值(可配置为1/4、1/2、3/4 或满),用来决定何时将缓冲区(FIFO)中数据发送到存储器(当从外设向存储器传输数据)或何时将存储器内的数据发送到缓冲区(FIFO)(从存储器向外设传输数据)。当从外设向存储器传输数据时,缓冲区(FIFO)内数据量达到阈值时,会将缓冲区(FIFO)数据发送到目标地址上。当从存储器向外设传输数据时,缓冲区内的数据量小于等于缓冲区(FIFO)阈值时,会使用存储器内的数据填充满FIFO。
通过DMA传输数据,需要以下信息:
- DMA外设端口和存储器端口的数据宽度。所谓数据宽度是指从端口发送或从端口接收的数据是多少位的。我们在编写程序时,有时候有这样的需求(特别是在外设与存储器间传输数据),从一个地址将A个N位的数据传输到另一个地址,重合组合成B个M位的数据。用DMA传输数据时,通过配置其外设端口和存储器端口的数据宽度可完美解决此问题。DMA中数据宽度可配置为字节、半字(2字节)和字(4字节)。通过DMA_SxCR寄存器的 PSIZE(配置外设端口数据宽度) 和 MSIZE(配置内存端口数据宽度) 位配置。
- 传输的数据量。所谓数据量是指具体要传输多少个数据。有两种控制传输数据量的方法:(1)连接外设并且要传输的数据数据量未知时,可通过外设发送数据传输的结束信号停止传输,但此种方法需要外设具有SDIO接口。(2) 在已知需要传输的数据量时,通过设置需要传输的数据量。要传输的数据量在使能DMA数据流之前写入DMA_SxNDTR 寄存器。在两边数据宽度不一致情况下,DMA_SxNDTR中的数据量等于外设端的数据量。每传输一次后,DMA_SxNDTR中值递减1,递减为0时,DMA停止传输。通常情况下,使用第2中方法来控制数据量。
- 数据传输地址。所谓数据传输地址是指从什么地址发送数据,从什么地址接收数据。外设端口和存储器端口各自有自己的数据传输地址,分别通过寄存器DMA_SxPAR 和DMA_SxM0AR/ DMA_SxM1A(DMA_SxM1AR仅在双缓冲区模式下有效)来设置数据传输地址。
2.1.DMA普通传输过程
DMA有一个使能信号,通过使能信号来控制DMA工作,在使用DMA时,首先需要使能DMA。
针对于不同的传输方向,其传输过程略有不同。
- 从外设向存储器传输数据
DMA使能后,等待外设发出DMA请求信号,DMA收到请求,数据从外设端口数据传输地址(DMA_SxPAR)存储到DMA缓冲区(FIFO)内,当缓冲区(FIFO)内数据量达到缓冲区(FIFO)阈值后,缓冲区(FIFO)内数据移出到内存端口数据传输地址(DMA_SxM0AR)指定的存储器地址中,同时每传输一个数据,DMA_SxNDTR内的值会减1,DMA_SxNDTR值递减为0,DMA传输停止。 - 从存储器向外设传输数据
DMA使能后,立即会将内存端口数据传输地址(DMA_SxM0AR)指定的数据移动到DMA缓冲区(FIFO)内,完全填满DMA缓冲区(FIFO),等待外设端口DMA请求信号&#x