STM32—DMA

1. DMA简介

  • DMA(Direct Memory Access)直接存储器存取
  • DMA可以提供外设和存储器或者存储器和存储器之间的高速数据传输,无须CPU干预,节省了CPU的资源
  • 12个独立可配置的通道:DMA1(7个通道)、DMA2(5个通道)每个通道都支持软件触发和特定的硬件触发
    • 如果DMA进行的是存储器到存储器的数据转运,比如我们想把Fash里的一批数据,转运到SRAM里去,那就需要软件触发,使用软件触发之后,DMA就会一股脑地,把这批教据,以最快的速度,全部转运完成
    • 那如果DMA进行的是外设到存储器的数据转运,那就不能一股脑地转运了,因为外设的数据是有一定时机的,所以这时我们就需要用硬件触发,比如转运ADC的数据,那就得ADC每个通道AD转换完成后,硬件触发一次DMA,之后DMA再转运,触发一次,转运一次,这样数据才是正确的
  • STM32F103C8T6 DMA资源:DMA1(7个通道)

2.存储器映像

3.DMA框图

左上角这里是Cortex-M3内核,里面包含了CPU和内核外设等等,剩下的这所有东西,你都可以把它看成是存储器

Flash是主闪存,SRAM是运行内存,各个外设,都可以看成是寄存器,也是一种SRAM存储器

 为了高效有条理地访问存储器,这里设计了一个总线矩阵,右边这些是被动单元,它们的存储器只能被左边的主动单元读写,主动单元这里,内核有DCode和系统总线,可以访问右边的存储器,其中DCode总线是专门访问Hash的,系统总线是访问其他东西的,

另外,由于DMA要转运数据,所以DMA也必须要有访问的主动权,那主动单元,除了内核CPU,剩下的就是DMA总线了,DMA1有一条DMA总线,DMA2也有一条DMA总线,下面这还有一条DMA总线,这是以太网外设自己私有的DMA,这个可以不用管的

在DMA1和DMA2里面,DMA1有7个通道,DMA2有5个通道,各个通道可以分别设置它们转运数据的源地址和目的地址,这样它们就可以各自独立地工作了

接着下面这里有个仲裁器,这个是因为,虽然多个通道可以独立转运数据,但是最终DMA总线只有一条,所以所有的通道都只能分时复用这一条DMA总线,如果产生了冲突,那就会由仲裁器,根据通道的优先级,来决定谁先用,谁后用,另外在总线矩阵这里,也会有个仲裁器,如果DMA和CPU都要访问同一个目标,那么DMA就会暂停CPU的访问,以防止冲突,不过总线仲裁器,仍然会保证CPU得到一半的总线带宽,使CPU也能正常的工作

下面这里是AHB从设备,也就是DMA自身的寄存器,因为DMA作为一个外设,它自己也会有相应的配置寄存器,这里连接在了总线右边的AHB总线上,所以DMA,即是总线短阵的主动单元,可以读写各种存储器,也是AHB总线上的被动单元,CPU通过这一条线路,就可以对DMA进行配置了

接着继续看这里,是DMA请求,请求就是触发的意思,这条线路右边的触发源,是各个外设,所以这个DMA请求就是DMA的硬件触发源,比如ADC转换完成、串口接收到数据,需要触发DMA转运数据的时候,就会通过这条线路,向DMA发出硬件触发信号,之后DMA就可以执行数据转运的工作了

这里的Flash,它是ROM只读存储器的一种,如果通过总线直接访问的话,无论是CPU,还是DMA,都是只读的,只能读取数据,而不能写入,如果你DMA的目的地址,填了Flash的区域,那转运时,就会出错,当然Flash也不是绝对的不可写入,我们可以配置这个Flash接口控制器,对Flash进行写入,这个流程就比较麻烦了,要先对Fash按页进行擦除,再写入数据

4.DMA基本结构

  • 第一个是起始地址,有外设端的起始地址,和存储器端的起始地址,这两个参数决定了数据是从哪里来,到哪里去的
  • 第三个参数是数据宽度,这个参数的作用是,指定一次转运要按多大的数据宽度来进行,它可以选择字节Bvte、半字HalfWord和字Word,字节就是8位,也就是一次转运一个uint8 t,这么大的数据,半字是16位,就是一次转运一个uint16 t,字是32位,就是一次转运uint32 t,这么大,32位系统中一个字为4
  • 第三个参数是地址是否自增,这个参数的作用是,指定一次转运完成后,下一次转运,是不是要把地址移动到下一个位置去,这就相当于是指针,p++,这个意思,

如果要进行存储器到存储器的数据转运,那我们就需要把其中一个存储器的地址,放在外设的这个站点,这样就能进行存储器到存储器的转运了,只要你在外设起始地址里写Flash或者SRAM的地址,那它就会去Flash或SRAM找数据,这个站点虽然叫外设奇存器,但是它就只是个名字而已,并不是说这个地址只能写寄存器的地址,你如果写Flash的地址,那就会去Flash里找,写SRAM,它就会去SRAM里找,这个没有限制

传输计数器:这个东西就是用来指定,我总共需要转运几次的,这个传输计数器是一个自減计数器,转运过程中,每转运一次,计数器的数就会减1,当传输计数器减到0之后,DMA就不会再进行数据转运了,另外,它减到0之后,之前自增的地址,也会恢复到起始地址的位置, 以方便之后DMA开始新一轮的转运

在传输计数器的右边,有一个自动重装器,这个自动重装器的作用就是,传输计数器减到0之后,是否要自动恢复到最初的值(传输计数器),它决定了转运的模式,如果不重装,就是正常的单次模式,如果重装,就是循环模式

下面这一块,就是DMA的触发控制了,触发,就是决定DMA需要在什么时机进行转运的,触发源,有硬件触发,和软件触发,具体选择哪个,由M2M这个参数决定

M2M就是Memory to Memory,当我们给M2M位1时,DMA就会选择软件触发,这个软件触发并不是调用某个函数一次,触发一次,它这个软件触发的执行逻辑是,以最快的速度,连续不断地触发DMA,争取早目把传输计数器清零,完成这一轮的转换,这里的软件触发,和我们之前外部中断和ADC的软件触发可能不太一样,你可以把他理解成连续触发,

这个软件触发和循环模式,不能同时用,因为软件触发就是想把传输计数器清零,循环模式是清零后自动重装,如果同时用的话,那DMA就停不下来了,软件触发一般适用于存储器到存储器的转运,因为存储器到存储器的转运,是软件启动、不需要时机,并且想尽快完成任务

当M2M位给0,那就是使用硬件触发了,硬件触发源可以选择ADC、串口、定时器等等,使用硬件触发的转运,一般都是与外设有关的转运,这些转运需要一定的时机,比如ADC转换完成、串口收到数据、定时时间到等等,所以需要使用硬件触发,在硬件达到这些时机时,传一个信号过来,来触发DMA进行转运

开关控制:也就是DMA_Cmd函数,当给DMA使能后,DMA就准备就绪,可以进行转运了,DMA进行转运,有几个条件

  • 第一,就是开关控制,DMA_Cmd必须使能
  • 第二,就是传输计数器必须大于0
  • 第三,就是触发源,必须有触发信号,

触发一次,转运一次,传输计数器自减一次,当传输计数器等手0,且没有自动重装时,这时无论是否触发,DMA都不会再进行转运了,此时就需要DMA_Cmd,给DISABLE,关闭DMA,再为传输计数器写入一个大于0的数,再DMA_Cmd,给ENABLE,开启DMA,DMA才能继续工作

注意一下,写传输计数器时,必须要先关闭DMA,再进行,不能在DMA开启时,写传输计数器,这是手册里的规定

5.DMA请求

也就是DMA的触发控制部分

这张图是DMA1的请求映像,下面是DMA的7个通道,每个通道都有一个数据选择器,可以选择硬件触发或软件触发,他把EN位画在了数据选择器的侧边,一般数据选择器的侧边是输入选择控制位,难道这里的意思是,EN!给1“选择硬件触发,EN给0,选择软件触发吗,这显然不对,而且它左边这里写的是软件触发(MEM2MEM位),难道M2M位是软件触发吗

M2M位是数据选择器的控制位,用于选择是硬件触发还是软件触发

EN位是开关控制,EN=0时不工作,EN=1时工作,EN并不是数据选择器的控制位,而且决定这个数据选择器要不要工作

然后软件触发后面跟个M2M位的意思应该是,当M2M位与1时,选择软件触发

然后继续看左边的硬件触发源,这里是外设请求信号,可以看到,每个通道的硬件触发源都是不同的,如果你需要用ADC1来触发的话,那就必须选择通道1,因为每个通道的硬件触发源都不同,所以如果你想使用某个硬件触发源的话,就必须使用窗所在的通道

而如果使用软件触发的话,那通道就可以任意选择了,因为每个通道的软件触发都是一样的

这里通道1的硬件触发是ADG1、定时器2的通道3和定时器4的通道1,那到底是选择哪个触发源呢?这个是对应的外设是否开启了DMA输出来决定的,比如你要使用ADC1,那会有个库函数叫ADC_DMACmd,必须使用这个库函数开启ADC1的这:路输出,它才有效,所以这三个触发源,具体使用哪个,取决于你把哪个外设的DMA输出开启了,如果3个都开启了,那这边是个或门,理论上3个硬件都可以进行触发,不过一般情况下,我们都是开启其中一个

之后,这7个触发源,进入到仲裁器,进行优先级判断,最终高生内部的DMA1请求,这个优先级的判断,类似于本断的优先级,默认优先级是通道号越小,优先级越高,当然也可以在程京束配置优先级

6.数据宽度与对齐

如果你把小的数据转到关的里面去”高位就会补0,如果把大的数据转到小的里面去高位就会舍弃掉

7.数据转运+DMA

将SRAM里的数组DataA,转运到另一个数组DataB中,我们看一下这种情况下,这个基本结构里的各个参数该如何配置,首先是外设站点和存储器站点的起始地址、数据宽度、地址是否自增这三个参数,那在这个任务里,外设地址显然应该填DataA数组的首地址,存储器地址,给DataB数组的首地址,然后数据宽度,两个数组的类型都是uint8_t,所以数据宽度都是按8位的字节传输,之后地址是否自增,在中间可以看到,我们想要的效果是DataA[0]转到DataB[0],DataA[1]转到DataB[1],等等,两个数组位置一一对应,所以转运完DataA[0]和DataB[0]之后,两个站点的地址都应该自增,都移动到下一个数据的位置,继续转运DataA[1]和DataB(1],这样来进行

  • 如果你左边不自增,右边自增,效果就是这样的,转运完成后,DataB的所有数据都会等于DataA[0]
  • 如果左边自增,右边不自增,那效果就是这样的,转运完成后,DataB[0]等于DataA的最后一个数,DataB其他的数不变,
  • 如果左右都不自增,那就一直是DataA[0]转到DataB[0],其他的数据不变

之后,这里的方向参数,那显然就是外设站点转运到存储器站点了,当然如果你想把DataB的数据转运到DataA,那可以把方向参数换过来,这样就是反向转运了

然后是传输计数器和是否要自动重装,在这里,显然要转运7次,所以传输计数器给7,自动重装暂时不需要

之后触发选择部分,因为这是存储器到存储器的数据转运,是不需要等待硬件时机的,尽快转运完成就行了,那最后,调用DMACmd,给DMA使能,转运7次之后,传输计数器自减到0,DMA停止,转运完成,这里的数据转运是一种复制转运,转运完成后DataA的数据并不会消失, 这个过程相当于是把DataA的数据复制到了DataB的位置 

8.ADC扫描模式+DMA

左边是ADC扫描模式的执行流程,这里有7个通道,触发一次后,7个通道依次进行AD转换,然后转换结果都放到ADC_DR数据寄存器里面,那我们要做的就是,在每个单独的通道转换完成后,进行一个DMA数据转运,并且目的地址进行自增,这样数据就不会被覆盖了

所以在这里DMA的配置就是,外设地址,写入ADC_DR这个寄存器的地址,存储器的地址,可以在SRAM中定义一个数组ADValue,然后把ADalue的地址当做存储器的地址,之后数据宽度,因为ADC DR和SRAM数组,我们要的都是uint16 t的数据,所以数据宽度都是16位的半字传输,那从这个图里,显然是外设地址不自增,存储器地址自增,传输方向,是外设站点到存储器站点,传输计数器,这里通道有7个,所以计数7次,计数器是否自动重装,这里可以看ADC的配置,ADC如果是单次扫描,那DMA的传输计数器可以不自动重装,转换一轮就停止,如果ADC是连续扫描,那DMA就可以使用自动重装,在ADC启动下一轮转换的时候,DMA也启动下一轮的转运,ADC和DMA同步工作

最后是触发选择,这里ADC DR的值是在ADC单个通道转换完成后才会有效,所以DMA转运的时机,需要和ADC单个通道转换完成同步,所以DMA的触发要选择ADC的硬件触发

最后硬件触发这里要说明一下,ADC扫描模式,在每个单独的通道转换完成后,没有任何标志位,也不会触发中断,所以我们程序不太好判断,某一个通道转换完成的时机是什么时候,但是根据我的研究,虽然单个通道转换完成后,不产生任何标志位和中断,但是它应该会产生DMA请求,去触发DMA转运

  • 14
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: STM32中的DMA(直接内存访问)是一种高效的数据传输机制,它可以以较少的CPU干预完成大量的数据传输。 DMA FIFO是DMA传输中的一个缓冲区,它可以储存数据以便DMA直接从中读取和写入数据。DMA FIFO可以大大提升DMA传输的效率,因为它可以避免DMA频繁访问内存,从而减少CPU的干预,提升数据传输的速率。 在STM32中,不同的DMA通道都有自己独立的DMA FIFO。DMA FIFO可以通过编程控制其大小和数据传输的方向。此外,DMA FIFO还支持半总线传输和内存突发传输等高级功能,以进一步提高数据传输的效率。 需要注意的是,DMA FIFO的大小不能太小,否则会影响传输速度。同时,在使用DMA FIFO时,需要注意内存的地址对齐,否则会影响DMA传输的效率。 总之,STM32 DMA FIFO是一种高效的DMA缓冲区,它能够大大提高数据传输的效率,减少CPU的干预,是STM32高效数据传输的重要手段之一。 ### 回答2: STM32 DMA FIFO是一种在STM32微控制器内部使用的先进的数据传输机制,旨在提高数据传输的效率和可靠性。DMA(FIFO)是指直接内存存储器访问(FIFO)的简称,这种传输方式可以通过DMA控制器自动处理,而无需CPU的干预。 STM32 DMA FIFO可以通过提供缓存缓冲区来处理和管理数据传输,这些缓存区是可以在存储器或外设之间共享数据的独立存储器区域。缓存区的大小和数量可以根据应用程序的数据传输速率和带宽要求进行配置。通过使用FIFO机制,可以缓解传输速率不匹配的问题,并且可以在数据传输时提供额外的保密性。 STM32 DMA FIFO的优点包括高效的数据传输速率,使得数据传输更加快速和可靠;同时,它还可以减少CPU的负担,提高程序执行效率。STM32 DMA FIFO对于大数据传输、高速传输以及多模块数据传输等应用非常有用。 因此,STM32 DMA FIFO已经成为了STM32微控制器的一个标准组件,许多工业自动化、智能制造和物联网应用程序中,都广泛采用了这种数据传输机制。 ### 回答3: STM32 DMA FIFO是STM32微控制器中的一种DMA传输方式,它使用了FIFO缓冲区来提高DMA传输效率。FIFO(First-In-First-Out)的缓冲区可以在一端输入数据,在另一端输出数据,所有数据按照入队的顺序依次出队。在DMA传输中,FIFO缓冲区可以减少DMA传输对CPU的干扰,并且可以缓存大量的数据,以增强数据传输的连续性与稳定性。通过使用DMA FIFO,可以在DMA传输期间减少数据丢失和重复读取以及提高数据传输的吞吐量。 STM32 DMA FIFO的主要特点包括: 1. 多通道支持:STM32 DMA FIFO可以支持多个通道同时进行DMA传输,并且可以进行通道间的数据拷贝。 2. 高效传输:使用DMA FIFO可以减少CPU的干扰,并且可以增强数据传输的连续性,从而提高数据传输的效率。 3. 灵活配置:STM32 DMA FIFO可以通过编程的方式配置传输方式、传输数据长度、传输地址等参数,以适应不同的应用场景。 总之,STM32 DMA FIFO是一种高效的DMA传输方式,适用于需要高效、稳定、连续的数据传输场景,例如音频、视频、存储器等大量数据传输场景。它可以提高数据传输效率,减少CPU的负担,提高系统的稳定性和可靠性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值