STM32 DMA控制器结构框图概述

发布者:清新生活最新更新时间:2024-03-29 来源: elecfans关键字:STM32  DMA控制器  结构框图 手机看文章 扫描二维码
随时随地手机看文章

DMA叫做直接存储器访问,用于在外设与存储器之间与存储器之间提供高速数据传输。可以在无需任何CPU操作的情况下通过DMA快速移动数据。这样节省的CPU资源可供其他操作使用。从硬件层次上来说,DMA 控制器是独立于 Cortex-M4内核的,有点类似 GPIO、USART 外设一般,只是 DMA的功能是可以快速移动内存数据。


要实现把外设数据写入内存,或把内存数据送至外设,一般由CPU控制完成,可采用标记查询或中断的方式。利用中断传送数据,可大大提高CPU的利用率。但当批量传输数据时,由于进出中断需保护现场和断点,无形之中增加了CPU的中断负载。另外,CPU的核心工作是算法处理,借用CPU进行大量数据传输,会降低CPU处理算法的效率。引入DMA技术,在一定程度上解放了CPU,提高了CPU的处理能力。


STM32F4xx的两个 DMA 控制器总共有 16 个数据流(每个控制器 8 个),每一个 DMA控制器都用于管理一个或多个外设的存储器访问请求。每个数据流总共可以有多达 8 个通道(或称请求)。每个通道都有一个仲裁器,用于处理 DMA 请求间的优先级。

DMA控制器结构框图

图片

DMA 控制器执行直接存储器传输:因为采用 AHB 主总线,它可以控制 AHB 总线矩阵来启动 AHB 事务。

它可以执行下列事务:

● 外设到存储器的传输

● 存储器到外设的传输

● 存储器到存储器的传输(仅DMA2数据流能实现存储器到存储器的传输)

通道选择

每个数据流可连接8个通道,某一时刻具体使用数据流的哪个通道,需通过DMA_SxCR寄存器中的CHSEL[2:0]位控制。通道选择如下图所示:

图片

两个DMA控制器的通道(请求)与数据流的映射关系如下所示:

a.DMA1通道选择(请求映射)

图片

b.DMA2通道选择(请求映射)

图片

由表可知,STM32F4XX的每个DMA控制器有8个数据流,每个数据流有多达8个通道。

仲裁器

当有多个数据流同时请求数据传输时,由仲裁器裁决数据流的传输顺序。

仲裁器为两个 AHB 主端口(存储器和外设端口)提供基于请求优先级的 8 个 DMA 数据流请求管理,并启动外设/存储器访问序列。

优先级管理分为两个阶段:

● ** 软件** :每个数据流优先级都可以在 DMA_SxCR 寄存器中配置。分为四个级别:

— 非常高优先级

— 高优先级

— 中优先级

— 低优先级

● 硬件 :如果两个请求具有相同的软件优先级,则编号低的数据流优先于编号高的数据流。例如,数据流 2 的优先级高于数据流 4。

配置好优先级,还需要指定数据传输的方向、指针递增方式和循环模式。

DMA的核心设置集中在配置寄存器、指定内存地址、外设地址及数据项目。下面描述DMA的相关寄存器。

DMA 低中断状态寄存器 (DMA_LISR)

图片

DMA 高中断状态寄存器 (DMA_HISR)

图片

DMA控制器使用状态寄存器LISR和HISR,来描述8个数据流的状态标记。LISR描述低4个数据流,而HISR描述高4个数据流。每个流对应5个状态,下面以数据流x来进行说明。

FCIFx :数据流x传输完成中断标记;

HTIFx :数据流x半传输完成中断标记;

TEIFx :数据流x传输错误中断标记;

DMEIFx:数据流x直接传输错误中断标记;

FEIFx :数据流xFIFO错误中断标记。

DMA 低中断标志清零寄存器 (DMA_LIFCR)

图片

DMA 高中断标志清零寄存器 (DMA_HIFCR)

图片

由DMA_LIFR/DMA_HIFR寄存器可知,DMA的标记是只读的,不能直接擦除。DMA控制器含有中断标记清零寄存器,用户通过向中断标记清零寄存器对应位写1,可清除对应的中断标记。

DMA 数据流 x 配置寄存器 (DMA_SxCR) (x = 0..7)

图片位 27:25 CHSEL[2:0]:通道选择 (Channel selection)

这些位将由软件置 1 和清零。

000:选择通道 0

001:选择通道 1

010:选择通道 2

011:选择通道 3

100:选择通道 4

101:选择通道 5

110:选择通道 6

111:选择通道 7

这些位受到保护,只有 EN 为“0”时才可以写入

位 24:23 MBURST :存储器突发传输配置(Memory burst transfer configuration)

这些位将由软件置 1 和清零。

00:单次传输

01:INCR4(4 个节拍的增量突发传输)

10:INCR8(8 个节拍的增量突发传输)

11:INCR16(16 个节拍的增量突发传输)

这些位受到保护,只有 EN 为“0”时才可以写入

在直接模式中,当位 EN =“1”时,这些位由硬件强制置为 0x0。

位 22:21 PBURST[1:0]:外设突发传输配置 (Peripheral burst transfer configuration)

这些位将由软件置 1 和清零。

00:单次传输

01:INCR4(4 个节拍的增量突发传输)

10:INCR8(8 个节拍的增量突发传输)

11:INCR16(16 个节拍的增量突发传输)

这些位受到保护,只有 EN 为“0”时才可以写入

在直接模式下,这些位由硬件强制置为 0x0。

位 19 CT:当前目标(仅在双缓冲区模式下)(Current target (only in double buffer mode))

此位由硬件置 1 和清零,也可由软件写入。

0:当前目标存储器为存储器 0(使用 DMA_SxM0AR 指针寻址)

1:当前目标存储器为存储器 1(使用 DMA_SxM1AR 指针寻址)

只有 EN 为“0”时,此位才可以写入,以指示第一次传输的目标存储区。在使能数据流后,此位相当于一个状态标志,用于指示作为当前目标的存储区。

位 18 DBM:双缓冲区模式 (Double buffer mode)

此位由软件置 1 和清零。

0:传输结束时不切换缓冲区

1:DMA 传输结束时切换目标存储区

此位受到保护,只有 EN 为“0”时才可以写入。

位 17:16 PL[1:0]:优先级 (Priority level)

这些位将由软件置 1 和清零。

00:低

01:中

10:高

11:非常高

这些位受到保护,只有 EN 为“0”时才可以写入。

位 15 PINCOS:外设增量偏移量 (Peripheral increment offset size)

此位由软件置 1 和清零

0:用于计算外设地址的偏移量与 PSIZE 相关

1:用于计算外设地址的偏移量固定为 4(32 位对齐)。

如果位 PINC =“0”,则此位没有意义。

此位受到保护,只有 EN 为“0”时才可以写入。

如果选择直接模式或者 PBURST 不等于“00”,则当使能数据流(位 EN =“1”)时,此位由硬件强制置为低电平。

位 14:13 MSIZE[1:0]:存储器数据大小 (Memory data size)

这些位将由软件置 1 和清零。

00:字节(8 位)

01:半字(16 位)

10:字(32 位)

11:保留

这些位受到保护,只有 EN 为“0”时才可以写入。

在直接模式下,当位 EN =“1”时,MSIZE 位由硬件强制置为与 PSIZE 相同的值。

位 12:11 PSIZE[1:0]:外设数据大小 (Peripheral data size)

这些位将由软件置 1 和清零。

00:字节(8 位)

01:半字(16 位)

10:字(32 位)

11:保留

这些位受到保护,只有 EN 为“0”时才可以写入

位 10 MINC:存储器递增模式 (Memory increment mode)

此位由软件置 1 和清零。

0:存储器地址指针固定

1:每次数据传输后,存储器地址指针递增(增量为 MSIZE 值)

此位受到保护,只有 EN 为“0”时才可以写入。

位 9 PINC:外设递增模式 (Peripheral increment mode)

此位由软件置 1 和清零。

0:外设地址指针固定

1:每次数据传输后,外设地址指针递增(增量为 PSIZE 值)

此位受到保护,只有 EN 为“0”时才可以写入。

位 8 CIRC:循环模式 (Circular mode)

此位由软件置 1 和清零,并可由硬件清零。

0:禁止循环模式

1:使能循环模式

如果外设为流控制器(位 PFCTRL=1)且使能数据流(位 EN=1),此位由硬件自动强制清零。

如果 DBM 位置 1,当使能数据流(位 EN =“1”)时,此位由硬件自动强制置 1。

位 7:6 DIR[1:0]:数据传输方向 (Data transfer direction)

这些位将由软件置 1 和清零。

00:外设到存储器

01:存储器到外设

10:存储器到存储器

11:保留

这些位受到保护,只有 EN 为“0”时才可以写入。

位 5 PFCTRL:外设流控制器 (Peripheral flow controller)

此位由软件置 1 和清零。

0:DMA 是流控制器

1:外设是流控制器

此位受到保护,只有 EN 为“0”时才可以写入。

选择存储器到存储器模式(位 DIR[1:0]=10)后,此位由硬件自动强制清零。

位 4 TCIE:传输完成中断使能 (Transfer complete interrupt enable)

此位由软件置 1 和清零。

0:禁止 TC 中断

1:使能 TC 中断

位 3 HTIE:半传输中断使能 (Half transfer interrupt enable)

此位由软件置 1 和清零。

0:禁止 HT 中断

1:使能 HT 中断

位 2 TEIE:传输错误中断使能 (Transfer error interrupt enable)

此位由软件置 1 和清零。

0:禁止 TE 中断

1:使能 TE 中断

位 1 DMEIE:直接模式错误中断使能 (Direct mode error interrupt enable)

此位由软件置 1 和清零。

0:禁止 DME 中断

1:使能 DME 中断

位 0 EN:数据流使能/读作低电平时数据流就绪标志 (Stream enable / flag stream ready when read low)

此位由软件置 1 和清零。

0:禁止数据流

1:使能数据流

以下情况下,此位可由硬件清零:

— DMA 传输结束时(准备好配置数据流)

— AHB 主总线出现传输错误时

— 存储器 AHB 端口上的 FIFO 阈值与突发大小不兼容时

此位读作 0 时,软件可以对配置和 FIFO 位寄存器编程。EN 位读作 1 时,禁止向这些寄存器执行写操作。

另外,在EN位置1(启动流前),与数据流相对应的事件标记都要清0。
DMA 数据流 x 数据项数寄存器 (DMA_SxNDTR) (x = 0..7)

图片

位 15:0 NDT[15:0]:要传输的数据项数目 (Number of data items to transfer)

要传输的数据项数目(0 到 65535)。只有在禁止数据流时,才能向此寄存器执行写操作。

使能数据流后,此寄存器为只读,用于指示要传输的剩余数据项数。每次 DMA 传输后,此寄存器将递减。

传输完成后,此寄存器保持为零(数据流处于正常模式时),或者在以下情况下自动以先前编程的值重载:

— 以循环模式配置数据流时。

— 通过将 EN 位置“1”来重新使能数据流时

如果该寄存器的值为零,则即使使能数据流,也无法完成任何事务。

DMA 数据流 x 外设地址寄存器 (DMA_SxPAR) (x = 0..7)

图片

位 31:0 PAR[31:0]:外设地址 (Peripheral address)

读/写数据的外设数据寄存器的基址。

这些位受到写保护,只有 DMA_SxCR 寄存器中的 EN 为“0”时才可以写入。

DMA相当于CPU的助理,通过软件对DMA控制器的以上寄存器进行合理配置,就可以启动DMA来传输数据了。此时CPU就可以专注于运算或其它事务的处理了。


这里以串口DMA为例编写程序


void DMA2_Uart1_TX_Init()

{

  //1. 开外设时钟(DMA2)

  RCC- >AHB1ENR  |= 1< < 22;

  //2.配置DMA控制器

    //a. 先禁止DMA,然后再设置

      //清状态标记(写1清除)

    DMA2- >LIFCR  =  0X0F7D0F7D;

    DMA2- >HIFCR  =  0X0F7D0F7D;

      //禁止EN

    DMA2_Stream7- >CR  = 0;

    while((DMA2_Stream7- >CR & (1< < 0)) != 0);  //等待DMA停止

    //b. 配置DMA/采用单次模式

    DMA2_Stream7- >CR  |= 4< < 25;    //通道4

    DMA2_Stream7- >CR  |= 2< < 16;    //优先级:2

    //c. PINCOS不偏移(不固定4字节对齐)、内存/外设大小为一个字节

    //内存递增、外设不递增

    DMA2_Stream7- >CR  |= 1< < 10;

    //不采用循环模式、方向:内存到外设

    DMA2_Stream7- >CR  |= 1< < 6;

}



/*

  传输设置函数

  paddr:外设地址

  maddr:内存地址

  cnt:数据项数目

*/

void DMA2_TransConfig(u32 paddr,u32 maddr,u16 cnt)

{

    //清状态标记(写1清除)

    DMA2- >LIFCR  =  0X0F7D0F7D;

    DMA2- >HIFCR  =  0X0F7D0F7D;

    DMA2_Stream7- >CR  &=~(1< < 0);

    while((DMA2_Stream7- >CR & (1< < 0)) != 0);  //等待DMA停止

    DMA2_Stream7- >PAR  =  paddr;

    DMA2_Stream7- >M0AR  =  maddr;

    DMA2_Stream7- >NDTR  =  cnt;

    DMA2_Stream7- >CR  |= 1< < 0;    //启动传输

}



u8 DMA2_GetFlag()          //获取传输完成标记

{

  if(DMA2- >HISR &(1< < 27))  //判断是否传输完成

    return 1;

  else

    return 0;

}



u8 DMA2_ClearFlag()

{

  DMA2- >HIFCR  = 1< < 27;    //清传输完成标记

}

除了以上DMA控制器的配置外,还要开启串口的DMA功能。


void Usart1_dma_config()

{

  USART1- >CR3 |= 1< < 7;      //使能串口DMA发送功能

}

接着编写主函数进行测试:


#include 'stm32f4xx.h'

#include 'usart.h'

#include 'DMA.h'

#include 'delay.h'



u8 str[]='hello,world!rn';



int main()

{

  u32 i=0;

  Usart1_Init(460800);

  Usart1_dma_config();      //开启串口发送DMA功能

  DMA2_Uart1_TX_Init();      //DMA控制器初始化

  DMA2_TransConfig((u32)&USART1- >DR,(u32)str,sizeof(str));  //开始传输


  while(1)

  {

    while(DMA2_GetFlag() == 0);  //判断传输是否完成,完成时退出循环

    DMA2_ClearFlag();            //清传输完成标记

    DMA2_TransConfig((u32)&USART1- >DR,(u32)str,sizeof(str));  //再次开启传输

    Delay_ms(500);

  }

}


由于DMA的传输速度较快,所以把串口的波特率调到最高460800,但是速度还是太快,串口接收的速度跟不上,如下图所示:

图片

因此在大循环的最后加上500ms的延时,就可以看到传输的数据被完整地打印出来了。可见DMA传输速度之快。

图片

串口DMA发送数据测试成功。串口DMA发送数据是属于内存到外设的,对于外设到内存和内存到内存的应用同样只要根据以上寄存器的描述进行配置,就可以实现DMA的数据传输了。


关键字:STM32  DMA控制器  结构框图 引用地址:STM32 DMA控制器结构框图概述

上一篇:基于STM32+Jlink的边界扫描实际应用演示
下一篇:STM32 IIC读写AT24C02(二)

推荐阅读最新更新时间:2024-11-21 13:58

基于STM32的USB枚举过程学习笔记(一)
之前使用ST官方的库以及网络的资料,完成了使用USB HID类进行STM32和PC机的通讯。由于其他原因并没有深入的分析,虽然实现了功能,但是关于USB设备的枚举,以及具体的通讯方式都没有清晰的概念,所以现在回头重新学习USB相关知识。主要参考资料是《圈圈教你玩USB》、USB枚举过程图解,ST官方的USB HID例程。 一,USB数据包 1. USB数据包分类 USB总线上的数据传输以包为基本的单位。USB协议规定了四种包:令牌包、数据包、握手包、特殊包。不同的包通过包中的8位PID域区分。 令牌包 令牌包用于启动 一次USB传输,USB的数据传输必须由主机发起。令牌包有四种: 输出令牌包
[单片机]
STM32学习之:IAR中确认某段代码的执行时间
1.接出来一个I/O口,然后设置反转,用示波器查看反转周期。 2.软件仿真时计算两断点CYCLECOUNTER(在CPU registers中)的差值,乘以指令周期(MCLK)便是执行时间。
[单片机]
单片机开发中的内存溢出的状况
在进行单片机开发的过程中,出现单片机内存溢出的小状况及总结: 循环遍历溢出 在初学C语言时可能会犯的错误,for循环遍历一个数组时,循环的次数超出了数组的长度。c语言编程时都要特别注意,细心。 各种string.h中的函数 string.h提供了许多方便的处理字符串的函数,像是strcpy,strcmp。但是这些函数都是用于处理字符串的,它们的参数都只给了一块内存的首地址,函数通过’’字符来判断是否到了字符串结尾。如果用这些函数处理一块不含’’的内存(或者自己代码有误没把’’写进去),就会发生内存溢出的问题。 推荐使用带n的函数,例如strncmp,memcpy,snprintf等,这样就可以配合sizeof来限制要处理的内
[单片机]
stm32驱动lora模块sx1278
开发环境 keil5 子设备读取Ds18b20数据,通过iic显示到OLED 屏幕上,同时用spi协议发送给lora,再传给网关。 网关接收到数据在OLED 屏幕上显示。 单片机源码: #include stdio.h #include DELAY/Delay.h #include UART/uart.h #include ADC/ADC.h #include LED/LED.h #include IIC/IIC.h #include OLED/OLED.h #include SPIx/SPIx.h #include SX1278/SX1278.h #define ALARM 22 int ma
[单片机]
STM32 串口DMA发送
一般情况下串口发送数据的完全不需要用到DMA,只有在处理器非常繁忙的时候,使用的DMA帮忙发送的就可以减轻处理器的负担。 下面就讲讲怎么使用DMA发送串口数据。还是基于我自己的标准工程。 1、工程的修改 1)这里要用到DMA,必须使用到库文件stm32f10x_dma.c,所以将是stm32f10x_dma.c文件添加到STM32F10x_StdPeriod_Driver工程组中。 2)打开stm32f10x_conf.h文件,将原先屏蔽的: #include stm32f10x_dma.h 语句的屏蔽去掉。 3)新建DMATx.c与DMATx.h两个文件分别保存到BSP文件夹下的src与inc两个文件中。并将DMATx.
[单片机]
STM32开源代码——UART串口程序
#include led.h #include delay.h #include key.h #include sys.h #include usart.h /************************************************ ALIENTEK精英STM32开发板 作者:唯恋殊雨 CSDN博客:https://blog.csdn.net/tichimi3375 TX-PA10 RX-PA9 ************************************************/ int main(void) { u16 t; u16 le
[单片机]
STM32学习笔记一一红外遥控
1. 简述 红外遥控是一种无线、非接触控制技术,具有抗干扰能力强,信息传输可靠,低功耗,低成本。 红外遥控的编码方式目前广泛使用的是: PWM (脉冲宽度调制)的 NEC 协议和 Philips PPM(脉冲位置调制) 的 RC-5 协议的。 1.1 NEC 协议定义 NEC 码的位定义: 一个脉冲对应 560us 的连续载波,一个逻辑 1 传输需要2.25ms(560us 脉冲+1680us 低电平),一个逻辑 0 的传输需要1.125ms(560us 脉冲+560us 低电平)。而遥控接收头在收到脉冲的时候为低电平,在没有脉冲的时候为高电平,这样,我们在接收头端收到的信号为:逻辑 1 应该是 560us 低+1680u
[单片机]
<font color='red'>STM32</font>学习笔记一一红外遥控
ST 最新STM32 Primer开发工具可玩Maze和Breakout
完整、独立、预编程的评估工具套件,既有充满趣味性的功能介绍,又有严肃的开发工具,可以链接到在线开发社区 中国,2007年10月15日 — 意法半导体(纽约证券交易所代码:STM)今天推出了一套价格低廉的开发工具,这款代号为STM32 Primer开发工具是一套完整的学习与娱乐相结合的趣味性应用开发工具,用于ST的STM32系列基于具有突破性的ARM Cortex-M3内核的闪存微控制器。这套工具包含一个创新的用户界面、多个游戏和向新用户介绍该系列产品的产品入门功能,以及用于高级开发和编程的Raisonance软件工具。 STM32 Primer是一个手持评估开发工具,力图通过简单和有趣的介绍,让用户了解STM32的强大功能。紧
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

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

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved