STM32F4-DMA(直接存储器访问)

        DMA,此外设有权限直接访问STM32内部的存储器:运行内存SRAM,程序存储器Flash和寄存器等。因此,DMA才能完成数据转运的工作。DMA可以实现外设和存储器之间(外设即外设的寄存器),或者存储器和存储器之间的高速数据传输。(本质上都是存储器到存储器)并且在此数据传输的过程中无须CPU干预,CPU可以去处理其他事情,节省CPU资源。( 外设的寄存器:一般是数据寄存器(DR),比如ADC,串口等的数据寄存器。 存储器:指的就是运行内存SRAM和程序存储器Flash。)

        STM32F4的两个 DMA 控制器(DMA1,DMA2)每一个 DMA 控制器都用于管理一个或多个外设的存储器访问请求。两个控制器总共有 16 个通道(每个控制器 8 个),DMA_SxCR 寄存器中的 CHSEL[2:0] 位用于选择DMA通道。每个通道总共可以有多达 8 个数据流(或称请求),每个DMA数据流可配置为不同的传输模式、数据方向、数据大小、地址增量等(由DMA_SxCR 寄存器配置)DMA通道是用作连接DMA请求和DMA数据流的通道,每个通道都与一个 DMA 请求相关联,此 DMA 请求可以从 8 个可能的数据流请求中选出。

STM32F4-DMA(直接存储器访问)_第1张图片

STM32F4-DMA(直接存储器访问)_第2张图片

STM32F4-DMA(直接存储器访问)_第3张图片

● DMA仲裁器:

DMA仲裁器是用于协调多个DMA请求的硬件模块。当有多个外设同时请求使用DMA控制器时,DMA仲裁器可以判断请求的优先级,按照优先级分配DMA通道,使不同外设的DMA请求可以有效地协调。这样,可避免DMA冲突、提高DMA的使用效率和系统性能。在STM32系列中,包括STM32 F1,F4等微控制器,都内置了DMA仲裁器。可以通过设置DMA通道的优先级级别,来实现对不同外设所发出的DMA请求进行有序的处理。每个DMA通道可以独立进行配置和控制。

        数据流是DMA通道的一个子功能,它可以将一个DMA通道拆分成多个独立的数据传输流,每个数据流都可以进行单独的配置和控制,这样可以提高DMA控制器的灵活性和效率。(DMA仲裁器是针对每个DMA通道进行配置的,而不是针对每个DMA数据流进行配置的。)                         为什么引入数据流?在进行数据传输时,一个DMA传输若占用比较长的时间的话。当一个DMA传输正在进行时,如果需要对同一DMA通道的其他数据进行传输,则需要等待当前的DMA传输结束。这样就会造成DMA效率比较低,影响系统的性能。为了解决这个问题,STM32系列单片机引入了DMA数据流的概念,使得在一个DMA通道中可以同时进行多个DMA数据流传输,每个数据流都可以独立地控制传输的开始、结束和中断等功能。这样,几个DMA数据流可以并行地进行传输,大大提高了DMA效率

       16个DMA通道,每个通道都和一个或者多个DMA请求连接。在进行DMA传输时,DMA通道会周期性地从外设或者存储器中接收DMA请求,并根据请求的类型进行相应的数据传输。每个数据流都支持软键触发和特定的硬件触发。[若DMA进行的是存储器到存储器的数据转运(比如将Flash里的一批数据转运到SRAM)一般采用软件触发,DMA会以最快速度将一批数据直接转运完成;若DMA进行外设到存储器的数据转运,不能一股脑的直接转运(因为外设的数据传输有一定的时机)一般需要采用硬件触发。在硬件达到时机时,传一个信号触发DMA进行转运。比如转运ADC的数据,需要等待ADC每个通道AD转换完成后,硬件触发一次,DMA再进行转运,这样数据才是正确的。]硬件触发的注意事项:若想使用某外设作为硬件触发源,必须选择对应的通道。每个通道对应的硬件触发源不同。同时需要把此外设的DMA输出开启。XXX_DMACmd()。

        寄存器是连接软件和硬件的桥梁,CPU可以对寄存器进行读写(和读写运行内存一样),寄存器的每一位背后都连接一根导线,,这些导线可以控制外设电路的状态(比如引脚置高低电平,开关导通断开,切换数据选择器等,或者多位结合起来可以当作:计数器,数据寄存器等),软件读写寄存器就是在控制硬件的执行。因此,既然外设就是寄存器,寄存器就是存储器,使用DMA进行数据转运就可归结为一类问题:从某个地址取内容再放到另一个地址去。

● 存储器映射(从起始地址开始,每个字节都分配专属的地址,帮助程序精准访问各个不同寄存器)

STM32F4-DMA(直接存储器访问)_第4张图片

BootLoader和选项字节(存储的Flash的读写保护以及看门狗等内容)存储于ROM区的最后面。内核外设(NVIC和SysTick)存储于RAM0XE000 0000。

● Flash模块构成(STM32F4):

Flash主要特性:STM32F40x 和 STM32F41x,容量1MB;128 位宽数据读取;字节、半字、字和双字数据写入; 扇区擦除与全部擦除。

Flash 结构如下:主存储器块,分为 4 个 16 KB 扇区、 1 个 64 KB 扇区和 7 个 128 KB 扇区。系统存储器,器件在系统存储器自举模式下从该存储器启动512 字节 OTP(一次性可编程),用于存储用户数据;OTP 区域还有 16 个额外字节,用于锁定对应的 OTP 数据块。选项字节,用于配置读写保护、 BOR 级别、软件/硬件看门狗以及器件处于待机或停止模式下的复位。

STM32F4-DMA(直接存储器访问)_第5张图片

● DMA内部结构图:

STM32F4-DMA(直接存储器访问)_第6张图片

STM32F4-DMA(直接存储器访问)_第7张图片

DMA要转运数据必须要有访问的主动权,DMA控制器1和2各有一条DMA总线连接总线矩阵。每个DMA控制器有8个传输通道,每个通道都可以设置他们转运数据的源地址和目标地址。虽然多个通道可以独立转运数据,但是DMA总线只有一条,多个通道需要分时复用这一条DMA总线,若产生了冲突则需要仲裁器来判定优先级。

DMA作为一个外设,同样有自己的配置寄存器(用于配置DMA自身的参数),连接在AHB1总线上。所以DMA既是总线矩阵的主动单元(可以读写各种寄存器),也是AHB总线上的被动单元。CPU通过此AHB线路可以对DMA进行配置。

DMA请求:是DMA的硬件触发源(比如AD转换完成,串口收到数据),需要触发DMA转运数据时候,就要通过外设到DMA请求这条线路,向DMA发出硬件触发信号。

注:DMA控制Flash(ROM只读存储器的一种)时候,只能取数据而不能作为目的地址写入数据。想要写入的话需要配置Flsah接口控制器,对Flash进行按页擦除,再写入(emm...只听过没试过!)。

● DMA具体工作流程(配置DMA参考此图)

STM32F4-DMA(直接存储器访问)_第8张图片

常规类型事务:DMA去左站点找数据传输到右站点。左右站点均可以是外设寄存器和存储器。源传输和目标传输在整个 4 GB 区域(地址在 0x0000 0000 和 0xFFFF FFFF 之间)都可以寻址外设和存储器。传输方向使用 DMA_SxCR 寄存器中的 DIR[1:0] 位进行配置,有三种可能的传输方向 存储器到外设、外设到存储器或存储器到存储器。
STM32F4-DMA(直接存储器访问)_第9张图片        双缓冲区类型事务(STM32F4系列新加的功能):使用存储器的两个存储器指针的双缓冲区传输(当 DMA 正在进行自缓冲区的读或至缓冲区的写操作时,应用程序可以进行至其它缓冲区的写或自其它缓冲区的读操作)。STM32F1系列单片机,其DMA控制器并没有官方DMA双缓冲区支持。

        通过将 DMA_SxCR 寄存器中的 DBM 位置 1,即可使能双缓冲区模式。使能双缓冲区模式时,将自动使能循环模式,并在每次事务结束时交换存储器指针。除了有两个存储器指针之外,双缓冲区数据流的工作方式与常规(单缓冲区)数据流的一样。此模式下,每次事务结束时, DMA 控制器都从一个存储器目标交换为另一个存储器目标。这样,软件在处理一个存储器区域的同时,DMA 传输还可以填充/使用第二个存储器区域。

        外设和存储器两个站点,都有三个参数:起始地址(外设端和存储器端),数据宽度(可以选择字节word,半字Halfword和字word),地址是否自增(指针递增)。起始地址决定数据的源头和目的地;数据宽度决定指定一次转运要以多大宽度进行;地址是否自增决定再一次转运完成后,下次转运外设和存储器的地址是否后移一位指向地址的指针++。

● 数据对齐问题:数据源端宽度>目标端宽度:高位舍弃;数据源端宽度<目标端宽度:高位补0。

STM32F4-DMA(直接存储器访问)_第10张图片

        字节就是8位,也就是一次转运uint8_t大小的数据,半字是16位,也就是一次转运一个uint16_t大小的数据,字是32位,一次转运uint32_t大小的数据。

        要传输的数据项的数目可以由DMA控制器或者外设管理:DMA流控制器:传输的数据项数目是1到65535,可用软件编程;外设流控制器:要传输的数据项数目未知并且由源或者目标外设控制,这些外设通过硬件发出传输结束的信号。

● 单次传输和突发传输
DMA 控制器可以产生单次传输或 4 个、 8 个和 16 个节拍的增量突发传输。突发大小指示突发中的节拍数,而不是传输的字节数。为确保数据一致性,形成突发的每一组传输都不可分割。        根据单次或突发配置的情况,每个 DMA 请求在 AHB 外设端口上相应地启动不同数量的传输。
当 AHB 外设端口被配置为单次传输时,根据 DMA_SxCR 寄存器 PSIZE[1:0] 位的值,
每个 DMA 请求产生一次字节、半字或字的数据传输。
当 AHB 外设端口被配置为突发传输时,根据 DMA_SxCR 寄存器 PBURST[1:0] 和PSIZE[1:0] 位的值,每个 DMA 请求相应地生成 4 个、 8 个或 16 个节拍的字节、半字或字的传输。

源和目标数据宽度不相等时,DMA自动封装/解封必要的传输数据来优化带宽(FIFO模式下才可)

传输计数器:是个自减计数器,用来指定DMA总共需要转运几次。它减到0之后,DMA不会进行数据转运了(注:它减到0之后,之前自增的地址会恢复到起始地址的位置。)自动重装器:决定传输计数器减到0之后,是否重新恢复最初的值。(决定了DMA转运模式。不重装:单次模式;重装:循环模式。循环模式:指定一轮工作完成后是否开启下一轮工作。)。注:写传输计数器时,必须先关闭DMA,不能在DMA开启时写。

M2M(Memory to Memory):控制DMA是软件触发还是硬件触发,置1:软件触发;置0:硬件触发。软件触发(可以理解为连续触发):以最快速度连续不断触发DMA,快速将传输计数器值清0。

开关控制:DMA_Cmd()函数使能DMA。

DMA常用于:ADC扫描模式配合DMA循环模式使用。

● 先进先出存储器缓冲区FIFO:

        每个通道有单独的四级32位先进先出存储器缓冲区FIFO,可用于FIFO模式或者直接模式。FIFO模式:可通过软件将阈值级别选取为FIFO的 1/4、 1/2、 3/4 或满;直接模式:每个DMA请求会立刻启动对DMA数据的传输。当在直接模式(禁止 FIFO)下将 DMA 配置为以存储器到外设模式传输数据时, DMA 会将一个数据从存储器预加载到内部 FIFO,从而确保一旦外设触发 DMA 请求时则立即传输数据。

        在STM32系列单片机中,每个DMA通道都有自己的独立FIFO,用于存储传输数据和相关控制信息。 DMA的数据传输过程中,数据是从外设或内存中获取到DMA控制器,并暂存到对应DMA通道的FIFO中。FIFO 用于在源数据传输到目标之前临时存储这些传输的数据。然后,DMA控制器从FIFO中读取数据,并将其传输到目标外设或内存地址中。由于每个DMA通道都拥有自己的独立FIFO,因此在多个DMA通道进行数据传输时,数据传输互不干扰。

STM32F4-DMA(直接存储器访问)_第11张图片

        每个通道对应的独立4字FIFO,阈值级别可由软件配置为 1/4、 1/2、 3/4 或满。通过设置FIFO阈值可以控制DMA传输开始条件。当存储在FIFO中的数据量到达FIFO阈值时,DMA控制器将会开始进行数据传输。在STM32F4系列的单片机中,DMA通道的FIFO阈值是通过DMA_SxFCR寄存器进行配置的。该寄存器包含了多个控制位,用于配置FIFO阈值、FIFO模式、FIFO错误中断和直接模式等参数。

STM32F4-DMA(直接存储器访问)_第12张图片

● DMA中断:

对于每个 DMA 数据流,可在发生以下事件时产生中断:达到半传输;传输完成;传输错误;FIFO 错误(上溢、下溢或 FIFO 级别错误);直接模式错误。

如下图:可以使用单独的中断使能位以实现灵活性。
STM32F4-DMA(直接存储器访问)_第13张图片

● DMA寄存器:

DMA 中断状态寄存器(发生中断会在此置标志位,如果配置了NVIC,会像CPU申请中断)2个:DMA 低中断状态寄存器 (DMA_LISR);DMA 高中断状态寄存器 (DMA_HISR)。

DMA 中断标志位清除2个:寄存器DMA 低中断标志清零寄存器 (DMA_LIFCR);DMA 高中断标志清零寄存器 (DMA_HIFCR)。

DMA通道配置寄存器2个:DMA 数据流 x 配置寄存器 (DMA_SxCR) (x = 0..7);DMA 数据流 x 数据项数寄存器 (DMA_SxNDTR) (x = 0..7):在STM32F4系列的单片机,是由DMA_SxCR寄存器和DMA_SxNDTR寄存器组成。DMA_SxCR寄存器存储了DMA通道的配置信息,包括DMA传输模式、数据宽度、传输方向、中断使能、FIFO使能和FIFO阈值等。而DMA_SxNDTR寄存器则用于存储DMA传输的数据量,即传输的数据块大小。

用于指定两个传输站点的地址的寄存器3个:DMA 数据流 x 外设地址寄存器 (DMA_SxPAR) (x = 0..7);DMA 数据流 x 存储器 0 地址寄存器 (DMA_SxM0AR) (x = 0..7);DMA 数据流 x 存储器 1 地址寄存器 (DMA_SxM1AR) (x = 0..7)。

DMA 数据流 x FIFO 控制寄存器 (DMA_SxFCR) (x = 0..7)。

● DMA配置程序过程

①使能DMA时钟:RCC_AHB1PeriphClockCmd();②初始化通道参数:DMA_Init();

③使能串口DMA发,串口DMA使能函数:USART_DMACmd();

④查询DMA的EN位,确保数据流就绪,没有正在进行的数据传输:DMA_GetCmdStatus();

⑤设置通道当前剩余数据量:DMA_SetCurrDataCounter();

⑥使能DMA通道,启动传输:DMA_Cmd();⑦查询DMA传输状态:DMA_GetFlagStatus();

⑧获取/设置通道当前剩余数据量:DMA_GetCurrDataCounter();

● DMA配置参数

①通道;②优先级;③数据传输方向;④存储器/外设数据宽度;⑤存储器/外设地址是否自增;

⑥循环模式/单次模式;⑦数据传输量。

你可能感兴趣的:(stm32,单片机,嵌入式硬件)