第21章 DMA—直接存储区访问—零死角玩转STM32-F429系列

2019-09-18来源: eefocus关键字:DMA  直接存储区访问  STM32-F429系列

本章参考资料:《STM32F4xx中文参考手册》DMA控制器章节。


学习本章时,配合《STM32F4xx中文参考手册》DMA控制器章节一起阅读,效果会更佳,特别是涉及到寄存器说明的部分。本章内容专业名称较多,内容丰富也较难理解,但非常有必要细读研究。


特别说明,本章内容是以STM32F42xxx系列资源讲解。


21.1 DMA简介

DMA(Direct Memory Access,直接存储区访问)为实现数据高速在外设寄存器与存储器之间或者存储器与存储器之间传输提供了高效的方法。之所以称之为高效,是因为DMA传输实现高速数据移动过程无需任何CPU操作控制。从硬件层次上来说,DMA控制器是独立于Cortex-M4内核的,有点类似GPIO、USART外设一般,只是DMA的功能是可以快速移动内存数据。


STM32F4xx系列的DMA功能齐全,工作模式众多,适合不同编程环境要求。STM32F4xx系列的DMA支持外设到存储器传输、存储器到外设传输和存储器到存储器传输三种传输模式。这里的外设一般指外设的数据寄存器,比如ADC、SPI、I2C、DCMI等等外设的数据寄存器,存储器一般是指片内SRAM、外部存储器、片内Flash等等。


外设到存储器传输就是把外设数据寄存器内容转移到指定的内存空间。比如进行ADC采集时我们可以利用DMA传输把AD转换数据转移到我们定义的存储区中,这样对于多通道采集、采样频率高、连续输出数据的AD采集是非常高效的处理方法。


存储区到外设传输就是把特定存储区内容转移至外设的数据寄存器中,这种多用于外设的发送通信。


存储器到存储器传输就是把一个指定的存储区内容拷贝到另一个存储区空间。功能类似于C语言内存拷贝函数memcpy,利用DMA传输可以达到更高的传输效率,特别是DMA传输是不占用CPU的,可以节省很多CPU资源。


21。2 DMA功能框图

STM32F4xx系列的DMA可以实现外设寄存器与存储器之间或者存储器与存储器之间传输三种模式,这要得益于DMA控制器是采样AHB主总线的,可以控制AHB总线矩阵来启动AHB事务。图 211为DMA控制器的框图。

图 211 DMA框图


1.    ①外设通道选择

STM32F4xx系列资源丰富,具有两个DMA控制器,同时外设繁多,为实现正常传输,DMA需要通道选择控制。每个DMA控制器具有8个数据流,每个数据流对应8个外设请求。在实现DMA传输之前,DMA控制器会通过DMA数据流x配置寄存器DMA_SxCR(x为0~7,对应8个DMA数据流)的CHSEL[2:0]位选择对应的通道作为该数据流的目标外设。


外设通道选择要解决的主要问题是决定哪一个外设作为该数据流的源地址或者目标地址。


DMA请求映射情况参考表 211和表 212。


表 211 DMA1请求映射

image.png


表 212 DMA2请求映射

image.png

每个外设请求都占用一个数据流通道,相同外设请求可以占用不同数据流通道。比如SPI3_RX请求,即SPI3数据发送请求,占用DMA1的数据流0的通道0,因此当我们使用该请求时,我们需要在把DMA_S0CR寄存器的CHSEL[2:0]设置为"000",此时相同数据流的其他通道不被选择,处于不可用状态,比如此时不能使用数据流0的通道1即I2C1_RX请求等等。


查阅表 211可以发现SPI3_RX请求不仅仅在数据流0的通道0,同时数据流2的通道0也是SPI3_RX请求,实际上其他外设基本上都有两个对应数据流通道,这两个数据流通道都是可选的,这样设计是尽可能提供多个数据流同时使用情况选择。


2。    ②仲裁器

一个DMA控制器对应8个数据流,数据流包含要传输数据的源地址、目标地址、数据等等信息。如果我们需要同时使用同一个DMA控制器(DMA1或DMA2)多个外设请求时,那必然需要同时使用多个数据流,那究竟哪一个数据流具有优先传输的权利呢?这就需要仲裁器来管理判断了。


仲裁器管理数据流方法分为两个阶段。第一阶段属于软件阶段,我们在配置数据流时可以通过寄存器设定它的优先级别,具体配置DMA_SxCR寄存器PL[1:0]位,可以设置为非常高、高、中和低四个级别。第二阶段属于硬件阶段,如果两个或以上数据流软件设置优先级一样,则他们优先级取决于数据流编号,编号越低越具有优先权,比如数据流2优先级高于数据流3。


3.    ③FIFO

每个数据流都独立拥有四级32位FIFO(先进先出存储器缓冲区)。DMA传输具有FIFO模式和直接模式。


直接模式在每个外设请求都立即启动对存储器传输。在直接模式下,如果DMA配置为存储器到外设传输那DMA会见一个数据存放在FIFO内,如果外设启动DMA传输请求就可以马上将数据传输过去。


FIFO用于在源数据传输到目标地址之前临时存放这些数据。可以通过DMA数据流xFIFO控制寄存器DMA_SxFCR的FTH[1:0]位来控制FIFO的阈值,分别为1/4、1/2、3/4和满。如果数据存储量达到阈值级别时,FIFO内容将传输到目标中。


FIFO对于要求源地址和目标地址数据宽度不同时非常有用,比如源数据是源源不断的字节数据,而目标地址要求输出字宽度的数据,即在实现数据传输时同时把原来4个8位字节的数据拼凑成一个32位字数据。此时使用FIFO功能先把数据缓存起来,分别根据需要输出数据。


FIFO另外一个作用使用于突发(burst)传输。


4.    ④存储器端口、⑤外设端口

DMA控制器实现双AHB主接口,更好利用总线矩阵和并行传输。DMA控制器通过存储器端口和外设端口与存储器和外设进行数据传输,关系见图 212。DMA控制器的功能是快速转移内存数据,需要一个连接至源数据地址的端口和一个连接至目标地址的端口。


DMA2(DMA控制器2)的存储器端口和外设端口都是连接到AHB总线矩阵,可以使用AHB总线矩阵功能。DMA2存储器和外设端口可以访问相关的内存地址,包括有内部Flash、内部SRAM、AHB1外设、AHB2外设、APB2外设和外部存储器空间。


DMA1的存储区端口相比DMA2的要减少AHB2外设的访问权,同时DMA1外设端口是没有连接至总线矩阵的,只有连接到APB1外设,所以DMA1不能实现存储器到存储器传输。

图 212 两个DMA控制器系统实现


5.    ⑥编程端口

AHB从器件编程端口是连接至AHB2外设的。AHB2外设在使用DMA传输时需要相关控制信号。


21.3 DMA数据配置

DMA工作模式多样,具有多种可能工作模式,具体可能配置见表 213。


表 213 DMA配置可能情况

image.png

1.    DMA传输模式

DMA2支持全部三种传输模式,而DMA1只有外设到存储器和存储器到外设两种模式。模式选择可以通过DMA_SxCR寄存器的DIR[1:0]位控制,进而将DMA_SxCR寄存器的EN位置1就可以使能DMA传输。


在DMA_SxCR寄存器的PSIZE[1:0]和MSIZE[1:0]位分别指定外设和存储器数据宽度大小,可以指定为字节(8位)、半字(16位)和字(32位),我们可以根据实际情况设置。直接模式要求外设和存储器数据宽度大小一样,实际上在这种模式下DMA数据流直接使用PSIZE,MSIZE不被使用。


2。    源地址和目标地址

DMA数据流x外设地址DMA_SxPAR(x为0~7)寄存器用来指定外设地址,它是一个32位数据有效寄存器。DMA数据流x存储器0地址DMA_SxM0AR(x为0~7) 寄存器和DMA数据流x存储器1地址DMA_SxM1AR(x为0~7) 寄存器用来存放存储器地址,其中DMA_SxM1AR只用于双缓冲模式,DMA_SxM0AR和DMA_SxM1AR都是32位数据有效的。


当选择外设到存储器模式时,即设置DMA_SxCR寄存器的DIR[1:0] 位为"00",DMA_SxPAR寄存器为外设地址,也是传输的源地址,DMA_SxM0AR寄存器为存储器地址,也是传输的目标地址。对于存储器到存储器传输模式,即设置DIR[1:0] 位为"10"时,采用与外设到存储器模式相同配置。而对于存储器到外设,即设置DIR[1:0]位为"01"时,DMA_SxM0AR寄存器作为为源地址,DMA_SxPAR寄存器作为目标地址。


3.    流控制器

流控制器主要涉及到一个控制DMA传输停止问题。DMA传输在DMA_SxCR寄存器的EN位被置1后就进入准备传输状态,如果有外设请求DMA传输就可以进行数据传输。很多情况下,我们明确知道传输数据的数目,比如要传1000个或者2000个数据,这样我们就可以在传输之前设置DMA_SxNDTR寄存器为要传输数目值,DMA控制器在传输完这么多数目数据后就可以控制DMA停止传输。


DMA数据流x数据项数DMA_SxNDTR(x为0~7)寄存器用来记录当前仍需要传输数目,它是一个16位数据有效寄存器,即最大值为65535,这个值在程序设计是非常有用也是需要注意的地方。我们在编程时一般都会明确指定一个传输数量,在完成一次数目传输后DMA_SxNDTR计数值就会自减,当达到零时就说明传输完成。


如果某些情况下在传输之前我们无法确定数据的数目,那DMA就无法自动控制传输停止了,此时需要外设通过硬件通信向DMA控制器发送停止传输信号。这里有一个大前提就是外设必须是可以发出这个停止传输信号,只有SDIO才有这个功能,其他外设不具备此功能。


4。    循环模式

循环模式相对应于一次模式。一次模式就是传输一次就停止传输,下一次传输需要手动控制,而循环模式在传输一次后会自动按照相同配置重新传输,周而复始直至被控制停止或传输发生错误。


通过DMA_SxCR寄存器的CIRC位可以使能循环模式。


5.    传输类型

DMA传输类型有单次(Single)传输和突发(Burst)传输。突发传输就是用非常

[1] [2] [3] [4]
关键字:DMA  直接存储区访问  STM32-F429系列 编辑:什么鱼 引用地址:http://news.2689mr.com/mcu/ic474886.html 本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。

上一篇:第11章 GPIO输出-使用固件库点亮LED—零死角玩转STM32-F429系列
下一篇:第20章 USART—串口通讯—零死角玩转STM32-F429系列

关注eeworld公众号 快捷获取更多信息
关注eeworld公众号
快捷获取更多信息
关注eeworld服务号 享受更多官方福利
关注eeworld服务号
享受更多官方福利

推荐阅读

STM32L4新版HAL库SDIO(DMA)、FatFs使用教程(四)
添加FreeRtos支持。FreeRtos中使用FATFS是强制要求使用DMA模式的SDIO驱动。步骤如下:1、打开工程配置文件,添加FreeRtos支持2、配置参数发现configuration选项卡SDMMC1报错,信息如下,意思是中断优先级问题。打开NVIC配置界面,修改中断优先级,注意,DMA优先级要比SD中断优先级低。打开FREERTOS选项,如图所示适当配置任务堆栈大小,这里为了测试方便,放到Start Task中测试,正式使用时,不要放在这里,要新建任务。文件操作所在的任务需要适当加大堆栈。3、生成代码,打开工程,将main函数中的Fatfs_RW_test();语句剪切,粘贴到StartDefaultTask函数
发表于 2020-04-22
STM32L4新版HAL库SDIO(DMA)、FatFs使用教程(四)
STM32 CUBEMX UART+DMA
不同,寄存器名称可能需要修改) */        temp = huart1.Instance->SR;        /* 读取串口数据寄存器(芯片型号不同,寄存器名称可能需要修改) */        temp = huart1.Instance->DR;        HAL_UART_DMAStop(&huart1);        /* 读取DMA剩余传输数量(芯片型号不同,寄存器名称可能需要修改
发表于 2020-04-17
stm32F4 配置串口+DMA 接收不定长数据 串口空闲中断
串口是一种很常见的通讯接口,通过串口回传数据是很多智能型的传感器都拥有的特点。 很多智能型传感器内置单片机 通过单片机将原始的数据处理,然后以串口的形式发送给用户单片机,用户单片机在利用串口得来的信息进行决策。 那么有没有一种简化通讯的方式呢 ?那就是串口 +DMA了!主要思想: 配置一个串口DMA接收 任务,任务搬运的数据量要大于一次通讯的总数据量(也就是DMA 的搬运工作还没结束 我们的数据就已经搬完了) 然后这时候因为串口的总线 没有数据传输了(数据传输频率不是特别高 完全占用总线的情况下,总线肯定会有一段时间空闲!) 这时候 因为串口的总线空闲会触发一个 串口总线控线中断,在这个中断里面  我们进行数据处理(获取
发表于 2020-04-15
stm32F4 配置串口+DMA 接收不定长数据 串口空闲中断
CubeMX Stm32F407 生成一定周期的占空比不同的方波 DMA + 定时器
先上图如图 是我生成的一个波形  这个波形的占空比在连续的四个周期内分别是10%,20%,30%,40%, 并且按照这个顺序循环这里大致介绍一下实现的方式。使用的软件是Cubemx(库函肯定也可以实现)第一步是器件选型  这一部分不做介绍  用的是Stm32F407第二是时钟配置接下来是定时器配置 第三步就是生成代码了这里 需要在生成的代码里面加上一行开始的代码。
发表于 2020-04-14
CubeMX Stm32F407 生成一定周期的占空比不同的方波 DMA + 定时器
基于Stm32F407的任意波形发生器
今天跟大家分享一个DAC转换的例子:先来效果图示波器使用的是Loto示波器OSC802三角波20KHz示例三角波20KHz示例正弦波20KHz示例测试使用的是Loto虚拟示波器   以上两张图的波形每一个周期都是300个DAC点组成,DAC转换速度是3MHz具体的实现代码如下:主要是最下面的三个函数  一个是DAC的初始化函数,另一个是定时器4的初始化函数 最后一个是波形发生函数。这是DAC+DMA的初始化函数  这要是设置DAC和DMA的基本参数 DAC触发选择的是定时器4的触发引脚, 也可以换成以上的其他定时器接下来是定时器的初始化定时器初始化部分很简单,不需要配置
发表于 2020-04-14
基于Stm32F407的任意波形发生器
Stm32F407 SPI1 全双工DMA 收发数据
这里我使用的是软件NSS所以就单独配置一下输出手册中的引脚复用在这里这一部分是SPI的参数设置,都是一些基本的参数就不去介绍了这是实际测试的速度这个是DMA 的配置部分也是整个程序的精华所在主要就是设置了一些 DMA 的基本参数,后面的注释是我跟据意思加的这是DMA双工发送的代码同时进行收和发这是原本的代码 相比我的多了一个设置 存储器地址的自增这部分应该是不需要的 写这篇博客主要是给自己以后一个参考,  ESP8266 的 通讯还是不好解决的 。如果用SPI 协议的话 还是需要一个主机 一个从机 而 ESP8266 做 从机比较难做
发表于 2020-04-11
Stm32F407 SPI1 全双工DMA 收发数据
小广播
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号 电信业务审批[2006]字第258号函 京公海网安备110108001534 Copyright © 2005-2020 2689mr.com, Inc. All rights reserved
免存送彩金 下载app赠送彩金平台 2019年无需申请送彩金 网上百家乐送彩金 2019年无需申请送彩金 网上百家乐送彩金 彩票大赢家 棋牌送彩金38 银行卡送彩金 娱乐平台加微信送彩金