ARM微控制器DMA控制器使用示例(1)

简介

本文阐述了如何ARM微控制器中利用直接存储器访问(DMA)控制器。该DMA控制器拥有的特性、系统架构设计、多级总线矩阵以及内存系统,共同为实现高数据传输带宽和开发极低延迟的响应时间软件提供了有力支持。

此外,本文档还提供了一系列技巧和建议,旨在帮助开发者充分挖掘这些功能,并确保各种外设和子系统能够达到预期的响应时间。

1 DMA控制器概述

直接存储器访问(DMA)是一个AMBA高级高性能总线(AHB)模块,配备了三个AHB接口:一个用于DMA编程的从接口以及两个主接口(外设和内存接口),这使得DMA能够在外设和内存模块之间启动数据传输。

DMA支持在后台进行数据传输,无需Cortex-M系列处理器的介入。在数据传输过程中,主处理器可以同时执行其他任务,仅在完成整个数据块的传输后才会被中断,从而提高了系统效率。

DMA可以高效地处理大量数据传输,对系统性能的影响微乎其微。它主要用于在系统静态随机存取存储器(SRAM)中为不同的外设模块实现中心数据缓冲区存储,这种集中式解决方案相较于每个外设独立实现本地数据存储的分布式方案,在硅片成本和功耗上更为经济。微控制器的DMA控制器充分利用了多层总线架构,确保了DMA传输和CPU执行以及中断事件的检测与服务都具有极低的延迟。

1.1 DMA传输特性

DMA传输具有以下特性:

  • DMA流/通道
  • 流的优先级
  • 数据源和目标地址
  • 传输方式
  • 传输的数据量(仅当DMA作为流量控制单元时)
  • 数据源/目标地址的递增或固定
  • 数据源和目标的数据宽度
  • 传输的种类
  • FIFO(先进先出队列)模式
  • 数据源/目标的突发传输大小
  • 双缓冲模式
  • 流量控制机制

微控制器内嵌的多个DMA控制器,每个控制器都具备一个外设端口和一个内存端口,这两个端口能够协同工作。 图1展示了DMA的模块化结构图。

图1 DMA控制器框图

1.1.1 DMA流与通道

微控制器内置一个或多个DMA(直接存储器访问)控制器,以两个DMA控制器为例,共计可提供最多16个DMA流(每个控制器分配有8个流),每个流专门负责处理一个或多个外设发起的内存访问请求。

每个DMA流最多可配置8个独立的通道(请求信号),这些通道的选择是可以通过软件进行配置的,从而使得多个外设都能够利用DMA流来发出数据传输的请求。

图2展示了为特定DMA流进行通道选择的配置方法。通过灵活的通道选择,开发者可以根据系统需求,为不同的外设分配DMA请求,以优化数据传输流程和提高系统性能。

图2 DMA通道选择

注:在同一个DMA流中,同一时间只能有一个通道或请求被激活。

多个已启动的DMA流不应同时响应同一个外设的请求。 表1和表2展示了示例MCU的DMA1和DMA2的请求映射情况。 这些表格详细列出了DMA流/通道与外设请求之间的对应关系,为开发者提供了DMA配置的参考依据。

在设计和配置DMA系统时,需要特别注意以下几点:

  • 单一激活限制:确保在任一给定的DMA流中,只有一个通道或请求被设置为激活状态,以避免数据传输冲突。

  • 避免请求冲突:不同的DMA流应该被配置为服务于不同的外设请求,以防止多个DMA流争用同一条传输通道。

  • 映射表参考:使用表1和表2来确定特定外设请求与DMA流/通道之间的映射关系,以确保正确的数据传输路径。

表1 示例微控制器的DMA1请求映射表

外设请求通道 0通道 1通道 2通道 3通道 4通道 5通道 6通道 7
SPI3_RX流 0-流 2-流 3-流 7-
I2C1_RX流 1-定时器7更新定时器7更新流 1流 1--
TIM4_CH1流 2-I2S3扩展接收定时器4通道2I2S2扩展发送I2S3扩展发送定时器4更新定时器4通道3
I2S3_EXT_RX流 3定时器2更新定时器2通道3I2C3接收I2S2扩展接收I2C3发送定时器2通道1定时器2通道2
UART5_RX流 4USART3接收USART4接收USART3发送USART4发送USART2接收USART2发送流 4
UART8_TX流 5USART7发送定时器3通道4定时器3更新USART7接收定时器3通道1定时器3触发定时器3通道2
TIM5_CH3流 6定时器5更新定时器5通道4定时器5触发定时器5通道1流 6定时器5通道2-
TIM6_UP-定时器6更新I2C2接收I2C2接收USART3发送DAC1DAC2I2C2发送

 表1 示例微控制器的DMA2请求映射表

外设请求流 0流 1流 2流 3流 4流 5流 6流 7
Channel 0ADC1SAI1_ATIM8_CH1TIM8_CH2TIM8_CH3SAI1_AADC1SAI1_B
Channel 1-DCMIADC2ADC2SAI1_BSPI6_TXSPI6_RXDCMI
Channel 2ADC3ADC3-SPI5_RXSPI5_TXCRYP_OUTCRYP_INHASH_IN
Channel 3SPI1_RX-SPI1_RXSPI1_TX-SPI1_TX--
Channel 4SPI4_RXSPI4_TXUSART1_RXSDIO-USART1_RXSDIOUSART1_TX
Channel 5-USART6_RXUSART6_RXSPI4_RXSPI4_TX-USART6_TXUSART6_TX
Channel 6TIM1_TRIGTIM1_CH1TIM1_CH2TIM1_CH1TIM1_CH4TIM1_TRIGTIM1_COMTIM1_UP
Channel 7-TIM8_UPTIM8_CH1TIM8_CH2TIM8_CH3SPI5_RXSPI5_TXTIM8_CH4

 示例微控制器的DMA请求映射设计赋予了软件应用程序更大的灵活性,允许用户将每个DMA请求映射到相应的外设请求。此外,大多数使用场景都可以通过将相关的DMA流和通道进行多路复用来得到满足。为了进行具体的DMA配置,请参阅你设计所使用微控制器的参考手册中的DMA1/DMA2请求映射表。

1.1.2 流的优先级设置

每个DMA端口都配备了一个仲裁器,用以处理与其他DMA流之间的优先级关系。流的优先级可以通过软件进行配置(提供了四个软件优先级级别)。如果两个或两个以上的DMA流被设置为具有相同的软件优先级级别,那么将采用硬件优先级规则(例如,流0的优先级高于流1,依此类推)。

1.1.3 源地址与目标地址的定义

DMA传输通过定义一个源地址和一个目标地址来实现。源地址和目标地址都应当位于AHB或APB存储器范围内,并且需要根据传输数据的大小进行适当对齐。

1.1.4 传输方式

DMA支持执行三种不同的数据传输方式:

  • 从外设到内存的传输
  • 从内存到外设的传输
  • 内存到内存的传输(仅有DMA2支持此类传输,且在此模式下不支持循环和直接模式)

1.1.5 传输数据量

仅当DMA担任流量控制角色时,才需设定传输数据量的值。此值实际上定义了从源地址向目标地址传输的数据总量。 传输数据量通过DMA_SxNDTR寄存器的值以及外设端的数据宽度来确定。根据接收到的传输请求类型(突发传输或单次传输),传输数据量的值会相应减少,减少的量等同于已传输的数据量。

1.1.6 源地址和目标地址的递增

用户可以设置DMA在每次数据传输完成后,自动对源地址和/或目标地址进行递增。

图3 DMA源地址和目标地址的递增示意图

1.1.7 源和目标的数据宽度

可以为源和目标定义以下数据宽度:

  • 8位(字节)
  • 16位(半字)
  • 32位(字)

1.1.8 传输模式

  • 循环模式:此模式适用于管理循环缓冲区和持续的数据流。在循环模式下,一旦DMA_SxNDTR寄存器的值递减到零,它会自动重新加载之前设定的数值,从而实现无缝的数据传输循环。
  • 普通模式:在此模式下,DMA_SxNDTR寄存器的值递减至零后,DMA流将被禁用,此时DMA_SxCR寄存器中的EN位会被设置为0,表示传输流已停止。

1.1.9 DMA的FIFO工作模式

每个DMA流都配备了一个独立的4字节深(4 × 32位)的FIFO(先进先出队列),并且其阈值可以通过软件配置为四分之一满、半满、四分之三满或完全满。FIFO的作用是在将数据发送至目标地址之前,暂存来自源地址的数据。 DMA的FIFO模式可以通过软件来启用或禁用。当FIFO禁用时,DMA将采用直接传输模式。一旦启用了DMA的FIFO,便可以使用数据打包/解包功能或突发传输模式。所配置的DMA FIFO阈值决定了DMA内存端口的请求时机。微控制器中实现的DMA FIFO具有以下优势:

  • 减少对SRAM的访问次数,从而给予其他主设备更多的时间来访问总线矩阵,避免了额外的并发冲突,
  • 使软件能够执行突发传输,优化了数据传输的带宽效率,
  • 允许进行数据的打包和解包操作,以便在不增加额外DMA访问次数的情况下,适应源和目标地址的数据宽度差异。 
图4 DMA FIFO的结构示意图

1.1.10 源和目标的突发传输大小

DMA的FIFO实现确保了突发传输的能力。

图5 DMA突发传输示意图

 突发传送需要关注以下要点:

响应外设的突发请求 当外设通过DMA发起突发数据传输请求时,根据设定的突发大小(4倍、8倍或16倍数据单元),DMA将执行相应数量的数据单元(可以是字、半字或字节)的读写操作。

DMA外设端口的突发大小配置 必须根据外设的需求和性能能力,对外设端口上的DMA突发大小进行相应的设置。

DMA内存端口的突发大小与FIFO阈值配置的匹配 内存端口上的DMA突发大小配置和FIFO阈值必须相互匹配,以保证在内存端口的突发传输开始时,DMA流能够在FIFO中预先储备充足的数据。表3列出了内存突发大小、FIFO阈值配置和数据大小之间的可能组合。

保障数据的一致性 为了维护数据的一致性,组成一次突发传输的所有数据传输组是不可中断的。在进行突发传输时,AHB传输会被锁定,AHB总线矩阵中的仲裁器不会在该突发传输序列过程中剥夺DMA主控的访问权限。

表3 突发传输配置示例

数据单元大小FIFO阈值水平突发大小设置为INCR4突发大小设置为INCR8突发大小设置为INCR16
字节1/4允许1个4字节突发不允许不允许
1/2允许2个4字节突发允许1个8字节突发不允许
3/4允许3个4字节突发不允许不允许
允许4个4字节突发允许2个8字节突发允许1个16字节突发
半字1/4不允许不允许不允许
1/2允许1个4半字突发不允许不允许
允许2个4半字突发允许1个8半字突发不允许
允许1个4字突发不允许不允许

1.1.11 双缓冲工作模式

双缓冲流在操作方式上与普通的单缓冲流相似,其独特之处在于它配备了两个内存指针。启用双缓冲模式后,循环模式也会自动被激活。每当DMA传输完成一个事务(即DMA_SxNDTR寄存器的值递减到0)时,这两个内存指针的角色就会互换。

这种工作模式使得软件能够同时进行两项操作:一方面处理一个内存区域中的数据,而另一方面,DMA传输则在另一个内存区域内进行数据的填充或读取。

图6 双缓冲模式示意图

在双缓冲模式中,当DMA流处于启用状态时,可以动态更新AHB内存端口的基本地址(DMA_SxM0AR 或 DMA_SxM1AR):

  • 当DMA_SxCR寄存器中的CT(当前目标)位为0时,当前的DMA内存目标是内存位置0,此时可以更新内存位置1的基本地址(DMA_SxM1AR)。
  • 当DMA_SxCR寄存器中的CT位为1时,当前的DMA内存目标是内存位置1,此时可以更新内存位置0的基本地址(DMA_SxM0AR)。

1.1.12 流量控制

流量控制器是负责控制数据传输长度并停止DMA传输的单元。流量控制器可以是DMA控制器本身或者是一个外设。

  • DMA作为流量控制器: 在这种情况下,需要在启用相关的DMA流之前,在DMA_SxNDTR寄存器中预先定义传输大小的值。当处理DMA请求时,根据传输的数据量(突发或单个),传输大小的值将相应减少。当传输大小的值降至0时,DMA传输随之结束,DMA流也被禁用。
  • 外设作为流量控制器: 当要传输的数据项数量不明确时,适用此情况。外设通过硬件信号告知DMA控制器何时传输最后的数据项。目前,只有SD/MMC和JPEG外设支持这种模式。

1.2 配置DMA传输

要配置编号为x的DMA流,应遵循以下步骤:

  1. 如果流已启用,通过将DMA_SxCR寄存器中的EN位清零来禁用它,然后读取该位以确认没有流操作正在进行。将EN位写为0不会立即生效,实际上只有当所有当前传输完成后,该位才会被清零。当EN位读为0时,表示流已准备好接受配置。因此,在开始任何流配置之前,必须等待EN位被清零。在重新启用流之前,应清除状态寄存器(DMA_LISR和DMA_HISR)中由先前数据块DMA传输所设置的所有流专用位。
  2. 在DMA_SxPAR寄存器中设置外设端口寄存器地址。数据将在每次外设事件后从该地址传输至外设端口或反之。
  3. 在DMA_SxMA0R寄存器中设置内存地址(如果是双缓冲模式,则还需在DMA_SxMA1R寄存器中设置)。数据将在每次外设事件后从该内存地址读取或写入。
  4. 在DMA_SxNDTR寄存器中配置要传输的总数据项数。在每次外设事件或每次突发传输的节拍后,该数值将递减。
  5. 使用DMA_SxCR寄存器中的CHSEL[2:0]位选择DMA通道(请求)。
  6. 如果计划让外设作为流量控制器,并且该外设支持此功能,则在DMA_SxCR寄存器中设置PFCTRL位。
  7. 使用DMA_SxCR寄存器中的PL[1:0]位配置流的优先级。
  8. 配置FIFO的使用(启用或禁用,以及传输和接收时的阈值设置)。
  9. 在DMA_SxCR寄存器中配置数据传输的方向、外设和内存的递增/固定模式、单个或突发传输类型、外设和内存的数据宽度、循环模式、双缓冲模式,以及在传输完成一半和/或全部完成或发生错误后触发中断的设置。
  10. 通过设置DMA_SxCR寄存器中的EN位来激活流。 一旦流被启用,它就可以响应连接到该流的外设发出的任何DMA请求。

2 DMA控制器的系统性能

ARM微控制器通常内嵌了一种多主多从的DMA系统架构:

  • 多主架构

    • Cortex®-Mx 核心的AHB总线
    • DMA1的内存总线
    • DMA2的内存总线
    • DMA2的外设总线
    • 以太网的DMA总线
    • USB高速的DMA总线
    • Chrom-ART加速器总线
    • LCD-TFT总线
  • 多从架构

    • 连接到多层总线矩阵的内部闪存接口
    • 主要的内部SRAM1以及辅助的内部SRAM(如设备上可用的SRAM2、SRAM3)
    • 包括AHB到APB桥接和APB外设在内的AHB1外设
    • AHB2外设
    • AHB3外设(例如,当产品线中可用时的FMC、Quad-SPI外设)

主设备和从设备通过多层总线矩阵相连,确保了即使在多个高速外设同时运行时,也能实现并发访问和高效运行。下图展示了DMA的主从系统架构。

图7  DMA系统架构示意图

2.1 多层总线矩阵架构

多层总线矩阵架构使得只要主设备访问的是从设备的不同模块,它们就能够并行地执行数据传输任务。这种结构在Cortex-Mx架构和双AHB端口DMA的基础上,增强了数据传输的并行性,有助于减少执行时间,同时优化了DMA的效率和功耗。

2.1.1 术语定义

  • AHB主设备:能够启动读写操作的总线主设备。在特定的时间周期内,只有单一的主设备能够获得总线的控制权。
  • AHB从设备:对主设备的读写操作做出响应的总线从设备。从设备向主设备返回成功、失败或等待的状态信号。
  • AHB仲裁器:确保在同一时间内只有一个主设备可以启动读写操作的总线仲裁器。
  • AHB总线矩阵:一个多层的AHB总线矩阵,通过每一层专用的AHB仲裁器将AHB主设备与AHB从设备相连接。该仲裁采用循环法(round-robin)算法。

2.1.2 循环法优先级机制

在总线矩阵层面,实施了循环法优先级机制,以确保每个主设备都能以极低的延迟访问任何从设备:

  • 循环法仲裁策略:允许公平地分配总线带宽。
  • 最大延迟被限定
  • 循环法量子:单次传输。

当多个AHB主设备尝试同时访问同一个AHB从设备时,总线矩阵中的仲裁器会介入以解决访问冲突。

在以下示例(见图8)中,CPU和DMA1都尝试访问SRAM1以读取数据。

图8 CPU和DMA1对SRAM1的访问请求

在类似上述例子中的总线访问冲突情况下,需要通过总线矩阵仲裁来解决。此时,采用循环法(round-robin)策略来处理:如果最后一个获得总线控制权的主设备是CPU,那么在下一次访问时,DMA1将获得总线的控制权,并优先访问SRAM1。随后,CPU也将获得访问SRAM1的权利。

这一点证实了,与单个主设备相关的传输延迟,实际上取决于其他等待访问同一AHB从设备的主设备的数量。在接下来的示例(见图9)中,有五个主设备正尝试同时访问SRAM1。

图9 五个主设备访问SRAM的情况

DMA1重新赢得总线矩阵并再次访问SRAM1(例如)所关联的延迟,等同于所有来自其他主设备的待处理请求的执行总时间。

2.1.3 总线矩阵仲裁与DMA传输延迟的最坏情况分析

DMA主端口在单一事务中所经历的延迟,取决于其他主设备进行的传输类型和传输长度。

以图8中的DMA1和CPU并发访问SRAM的案例为例,DMA传输的延迟会根据CPU事务的长度而有所变化。

如果首先批准CPU进行总线访问,并且CPU没有执行单个数据加载或存储操作,那么DMA等待获得SRAM访问权的时间可能从一个AHB周期(对应于单个数据加载或存储操作)延长到N个AHB周期,这里的N等于CPU事务中数据字的数量。

CPU锁定AHB总线以维持总线所有权,并在执行多个加载或存储操作以及中断进入时减少延迟。这种做法虽然提升了固件的响应速度,但也可能导致DMA传输的延迟。

当DMA1与CPU发生并发访问SRAM时,DMA1对SRAM的访问延迟将根据CPU传输的类型而有所不同:

  • 如果CPU通过中断发出传输(例如上下文保存):延迟为8个AHB周期
  • 如果CPU通过缓存控制器发出传输(例如256位缓存行的填充或清空):延迟为8个AHB周期(
  • 如果CPU通过LDM/STM指令发出传输:延迟为14个AHB周期,这涉及到从/向内存传输多达14个寄存器的数据

通过配置编译器,将加载/存储多条指令拆分成单独的加载/存储指令,可以减少由LDM/STM指令引起的传输延迟。

图10 DMA传输因CPU中断引起的传输而延迟

 上述图示详细说明了当CPU因中断而执行多周期传输时,如何导致DMA传输发生延迟。在DMA内存端口被触发去执行一次内存访问后,经过总线仲裁,AHB总线并未立即授予DMA1内存端口使用权,而是授予了CPU。因此,在满足DMA请求时会经历一个额外的延迟期,即对于由中断引发的CPU传输,延迟周期为8个AHB周期。

当其他主设备(例如DMA2、USB_HS、Ethernet等)也尝试以不同于单个数据单元的事务长度同时访问同一从设备时,同样可以观察到这种行为。

为了提升在总线矩阵上DMA访问的性能,建议尽量避免总线争用现象。

2.2 DMA传输路径

2.2.1 双DMA端口结构

S微控制器配备的两个或者多个DMA控制器。每个DMA控制器都具备两个端口:一个内存端口和一个外设端口,这两个端口不仅可以在DMA层面上同时运行,还可以与系统的其他主设备协同工作,利用外部总线矩阵和专用的DMA传输路径。

这种同时运行的能力使得DMA的效率得到优化,并减少了响应时间,即从请求发出到数据传输开始之间的等待时间得到了缩短。

图11 DMA双接口示意图

DMA2的访问路径:

  • 内存端口(MEM):能够通过总线矩阵访问AHB1、AHB2、AHB3(包括外部存储器控制器、FSMC)、静态随机存取存储器(SRAM)以及闪存存储器。
  • 外设端口(Periph):具备以下访问能力:
    • 通过总线矩阵,访问AHB1、AHB2、AHB3(包括外部存储器控制器、FSMC)、SRAM以及闪存存储器,
    • 通过一条直接路径(绕过总线矩阵),直接访问AHB至APB2的桥接。

DMA1的访问路径:

  • 内存端口(MEM):能够通过总线矩阵访问AHB3(包括外部存储器控制器、FSMC)、SRAM以及闪存存储器。
  • 外设端口(Periph):仅能通过一条直接路径(不通过总线矩阵)访问AHB至APB1的桥接。

2.2.2 DMA传输的状态

本节阐述了在DMA的外设端口和内存端口层面进行数据传输的步骤:

从外设到内存的传输: 在这种传输模式下,DMA需要通过两次总线访问来完成数据传输:

  • 第一次访问通过外设端口进行,由外设发起的请求触发,
  • 第二次访问通过内存端口进行,触发方式可以是FIFO阈值达到时(当启用FIFO模式时),或者是在外设完成读操作后立即进行(当使用直接传输模式时)。
图12 外设到内存传输的状态图

从内存到外设的传输:

在此传输模式中,DMA需要两次总线访问来完成数据的传输:

  • DMA预先读取内存中的数据,将其存储在FIFO中,以便在外设发起DMA请求时能够立即进行数据传输。
  • 当外设的DMA请求被触发,DMA外设端口便会产生一次数据传输。
图13 存储器到外设传输的状态图

2.2.3 DMA请求的仲裁机制

如在第1.1.2节“流优先级”中所述,STM32F2/F4/F7系列微控制器的DMA系统内嵌了一个仲裁器,它根据优先级管理每个AHB主端口(内存端口和外设端口)的八个DMA流请求,并触发外设或内存的访问序列。

当存在多个活跃的DMA请求时,DMA必须在其内部对这些活跃请求进行仲裁,并决定哪个请求应该首先被处理。

下图展示了由DMA流“请求1”和“请求2”(这两个请求可以是任意的DMA外设请求)同时触发的两个循环DMA请求的情况。在随后的AHB时钟周期中,DMA仲裁器会检查所有活跃的待处理请求,并授予最高优先级的“请求1”流访问权限。当处理到“请求1”流的最后一个数据传输周期时,会进入下一个仲裁周期。在这个时刻,“请求1”被搁置,仲裁器仅识别到“请求2”为活跃请求,因此这次访问权限便分配给了“请求2”,如此循环往复。

图14 DMA请求仲裁示意图

通用建议:

  • 应为高速/高带宽外设分配最高的DMA优先级,以确保这些外设的数据最大延迟得到满足,并防止出现数据溢出或欠载的情况。
  • 如果外设的带宽需求相同,建议对于以从模式(无法控制数据传输速率)工作的外设,相比以主模式(能够控制数据流)工作的外设,分配更高的优先级。
  • 由于两个DMA控制器可以根据总线矩阵的多层结构并行工作,因此在外设请求之间平衡高速外设的请求是可行的。

2.3 AHB至APB桥接

STM32F2/F4/F7系列微控制器内嵌了两个AHB至APB桥接:APB1和APB2,外设连接到这些桥接。

2.3.1 双端口AHB至APB架构

AHB至APB桥接采用了双端口架构,允许通过两种不同的通路进行访问:

  • 一条直接通路(不穿越总线矩阵),可以从DMA1直接到APB1,或者从DMA2直接到APB2生成;在这种情况下,访问不会受到总线矩阵仲裁器的影响。
  • 一条通用通路(通过总线矩阵),可以由CPU或DMA2生成,这需要通过总线矩阵仲裁来获得总线访问权。

2.3.2 AHB至APB桥接的仲裁

由于这些微控制器产品上实现了DMA的直接路径,因此在AHB至APB桥接级别上设置了一个仲裁器,用以解决并发的访问请求。

下图展示了在AHB至APB1桥接上由CPU(通过总线矩阵访问)和DMA1(通过直接路径访问)生成的并发访问请求的情况。


图15. AHB到APB1桥接上的CPU和DMA1并发访问请求

AHB至APB桥接在授予总线访问权时采用循环法(round-robin)策略:

  • 循环法的量子单位是1次APB传输。
  • 在DMA外设端口上,最大的延迟被限定为1次APB传输。

仅有CPU和DMA控制器能够对外设总线APB1和APB2发起并发访问请求:

  • 对于APB1,如果CPU、DMA1和/或DMA2同时发出访问请求,则可能产生并发访问情况。
  • 对于APB2,如果CPU和DMA2同时发出访问请求,则可能产生并发访问情况。

未完待续.........

  • 21
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
ARM平台的DMA初始化分为以下步骤: 1. 配置DMA控制器 首先需要配置DMA控制器的寄存器,如设置DMA通道数目、配置DMA时钟源、设置DMA传输模式等。 2. 分配DMA缓冲区 为了进行DMA数据传输,需要分配DMA缓冲区。一般情况下,DMA缓冲区需要使用可以被DMA访问的内存区域。 3. 配置DMA传输参数 根据具体的应用场景,配置DMA传输参数,如源地址、目的地址、传输长度、传输方向、传输周期等。 4. 使能DMA传输 经过以上步骤的配置后,就可以使能DMA传输,并等待DMA传输完成中断或者轮询DMA传输状态。 下面是一个简单的ARM DMA初始化的示例代码: ```c #include "stm32f10x_dma.h" #include "stm32f10x_gpio.h" #include "stm32f10x_rcc.h" // 定义DMA缓冲区 uint8_t dma_buffer[64]; void dma_init(void) { DMA_InitTypeDef dma_init_struct; // 使能DMA时钟 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); // 配置DMA通道 DMA_StructInit(&dma_init_struct); dma_init_struct.DMA_PeripheralBaseAddr = (uint32_t)&(USART1->DR); dma_init_struct.DMA_MemoryBaseAddr = (uint32_t)dma_buffer; dma_init_struct.DMA_DIR = DMA_DIR_PeripheralDST; dma_init_struct.DMA_BufferSize = 64; dma_init_struct.DMA_PeripheralInc = DMA_PeripheralInc_Disable; dma_init_struct.DMA_MemoryInc = DMA_MemoryInc_Enable; dma_init_struct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; dma_init_struct.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; dma_init_struct.DMA_Mode = DMA_Mode_Normal; dma_init_struct.DMA_Priority = DMA_Priority_High; dma_init_struct.DMA_M2M = DMA_M2M_Disable; DMA_Init(DMA1_Channel4, &dma_init_struct); // 使能DMA通道 DMA_Cmd(DMA1_Channel4, ENABLE); } ``` 以上代码中,我们使用了STM32F10x系列单片机DMA模块,通过配置DMA通道和缓冲区,实现了从USART1外设向DMA缓冲区的数据传输。具体的代码实现可以根据实际需求进行修改。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MUKAMO

你的鼓励是我们创作最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值