STM32-DMAダイレクト・メモリ・アクセス

簡単な紹介

DMA(ダイレクトメモリアクセス、ダイレクト・メモリ・アクセス)周辺レジスタとの間で高速データを実現し、メモリは、送信またはメモリとメモリとの間の効率的な方法を提供します。高効率、高速のDMA転送は、制御CPUの動作なしにデータを移動するためのプロセスであると呼ばれます。ハードウェアレベルから、独立してDMAコントローラ・コアのCortex-M4の、ある一般に幾分類似GPIO、USART周辺機器、DMA機能は、高速メモリデータを移動させることができます。

異なるプログラミング環境のためのフル機能を備えたDMA、多くの動作モードのSTM32F4xxシリーズ。STM32F4xxシリーズは、メモリ転送と3つの伝送モードに周辺転送メモリへのメモリ転送、メモリへのDMAは、周辺機器をサポートしています。周辺本明細書中で一般的に、一般的に、そのようなADC、SPI、I2C、DCMI周辺データレジスタ等の周辺データレジスタを指すメモリチップSRAMのような、外部メモリ、オンチップ・フラッシュを指します。

メモリ転送の周辺には、指定されたメモリ空間に周辺データレジスタの内容に転送されます。例えば、我々は、処理マルチチャネル獲得、高いサンプリング周波数は、捕捉のための連続出力データADは非常に効率的であるように、メモリ領域AD変換に私達の定義データを転送するためにADC取得DMA転送を使用することができるとき。

記憶領域は、特定のコンテンツが通信ペリフェラルを送信するために使用される周辺記憶データレジスタに転送され、周辺領域に伝達されます。

メモリ転送へのメモリは、コンテンツスペースをコピーし、別の記憶領域に指定された記憶領域です。memcpyのメモリコピー機能に似たC言語関数、DMA転送は、より高い伝送効率を使用することによって達成することができ、特にDMA転送はCPUによって占有されていない、あなたは、CPUリソースを大幅に節約することができます。

DMA機能ブロック図

STM32F4xxシリーズDMA転送の3つのモードの間に達成することができ、DMAコントローラの恩恵を受けるべきメモリとメモリやペリフェラルレジスタメモリは、バス・マスタサンプリングAHBであるAHBバスマトリックスAHBトランザクションを開始するように制御することができます。

5d306813bec2063255

図1に示すように、周辺チャネル選択

STM32F4xxシリーズ豊富な資源は、通常の送信、必要なチャネル選択制御DMAを達成するために、周辺範囲ながら、2つのDMAコントローラを持っています。各DMAコントローラは、各データストリームは、8つの周辺要求に対応する、8つのデータストリームを有しています。データ・ストリームの対象として選択されたチャンネルに対応する[2:0]ビットDMA転送を実施する前に、DMAコントローラの構成はDMA_SxCRがx CHSELを介してDMAデータストリーム(xは0~7であり、8つのデータに対応するDMAストリーム)登録します周辺機器。主な問題を解決するために、周辺のチャネル選択は、データストリームの送信元または宛先アドレスとして決定末梢あります。

DMA要求のマッピングリファレンス表21-1と表21-2。

DMA1要求のマッピング

5d3068558ecef70336
DMA2マッピング要求

5d30685a4871c42871

各周辺装置は、要求データ・ストリーム・チャネルを占有し、同じ要求は、異なる周辺データ・ストリーム・チャネルを占有してもよいです。例えばSPI3_RX要求、すなわち、データ受信要求SPI3、DMA1フローチャネル占有データ00、我々はこの要求を使用するときに、我々はCHSEL DMA_S0CR [2:0]に登録する必要が「000」に設定されている、同じケース他のチャネルのデータストリームが選択されていない、そのようなデータストリームとして利用不可能状態は、この時間すなわちI2C1_RX要求チャネル0、等で使用することができません。

2、アービタ

8つのデータストリームに対応するDMAコントローラ、等元アドレスに送信するデータ、送信先アドレス、データ、を含むデータストリーム。私たちは同じDMAコントローラ(DMA1またはDMA2)複数のペリフェラル要求を使用する必要がある場合は、複数のデータをどちらのデータ・ストリームは、それを輸送する優先権を持っていることをストリームに使用するまでに時間がかかるのだろうか?これは、裁判官を管理するための調停が必要です。

アービタは、データフロー方式を2つの段階に分けて管理します。第一段階の具体的な構成はDMA_SxCR PL登録、それは優先度レジスタを通って流れるときに、我々は、構成データを設定することができ、ソフトウェアのステージに属する[1:0]ビットは非常に高く、高、中、低レベル4に設定することができます。2つ以上のデータストリームソフトウェアは、データストリーム2のデータストリーム3よりも高い優先順位として、それらのデータストリーム数に応じて優先度として低い番号を有する優先順位が同じ優先度を設けた場合に第二段階は、ハードウェアの段階です。

3、FIFO

各データ・ストリームは、(先入れ先出しメモリバッファに)4つの別個の32ビットFIFOを有しています。FIFO DMA転送モードとダイレクトモードを持ちます。

直接模式在每个外设请求都立即启动对存储器传输。在直接模式下,如果 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 控制器通过存储器端口和外设端口与存储器和外设进行数据传输,关系见图 21-2。 DMA 控制器的功能是快速转移内存数据,需要一个连接至源数据地址的端口和一个连接至目标地址的端口。

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

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

5d306885ab4db84543

5、编程端口

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

DMA数据配置

5d306897df22b54696

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 寄存器作为为源地址, MA_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)传输。突发传输就是用非常短时间结合非常高数据信号率传输数据,相对正常传输速度,突发传输就是在传输阶段把速度瞬间提高,实现高速传输,在数据传输完成后恢复正常速度,有点类似达到数据块“秒传”效果。为达到这个效果突发传输过程要占用 AHB 总线,保证要求每个数据项在传输过程不被分割,这样一次性把数据全部传输完才释放 AHB 总线;而单次传输时必须通过 AHB 的总线仲裁多次控制才传输完成。

单次和突发传输数据使用具体情况参考表 21-4。其中 PBURST[1:0]和 MBURST[1:0]位是位于 DMA_SxCR 寄存器中的,用于分别设置外设和存储器不同节拍数的突发传输,对应为单次传输、 4 个节拍增量传输、 8 个节拍增量传输和 16 个节拍增量传输。 PINC 位和MINC 位是寄存器 DMA_SxCR 寄存器的第 9 和第 10 位,如果位被置 1 则在每次数据传输后数据地址指针自动递增,其增量由 PSIZE 和 MSIZE 值决定,比如,设置 PSIZE 为半字大小,那么下一次传输地址将是前一次地址递增 2。

5d3068d680db026629

突发传输与 FIFO 密切相关,突发传输需要结合 FIFO 使用,具体要求 FIFO 阈值一定要是内存突发传输数据量的整数倍。 FIFO 阈值选择和存储器突发大小必须配合使用,具体参考表 21-5。

5d3068e74d29f20294

6、直接模式

默认情况下, DMA 工作在直接模式,不使能 FIFO 阈值级别。

直接模式在每个外设请求都立即启动对存储器传输的单次传输。直接模式要求源地址和目标地址的数据宽度必须一致,所以只有 PSIZE 控制,而 MSIZE 值被忽略。突发传输是基于 FIFO 的所以直接模式不被支持。另外直接模式不能用于存储器到存储器传输。

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

7、双缓冲模式

设置 DMA_SxCR 寄存器的 DBM 位为 1 可启动双缓冲传输模式,并自动激活循环模式。双缓冲不应用与存储器到存储器的传输。双缓冲模式下,两个存储器地址指针都有效,即DMA_SxM1AR 寄存器将被激活使用。开始传输使用 DMA_SxM0AR 寄存器的地址指针所对应的存储区,当这个存储区数据传输完 DMA 控制器会自动切换至 DMA_SxM1AR 寄存器的地址指针所对应的另一块存储区,如果这一块也传输完成就再切换至 DMA_SxM0AR寄存器的地址指针所对应的存储区,这样循环调用。

当其中一个存储区传输完成时都会把传输完成中断标志 TCIF 位置 1,如果我们使能了DMA_SxCR 寄存器的传输完成中断,则可以产生中断信号,这个对我们编程非常有用。另外一个非常有用的信息是 DMA_SxCR 寄存器的 CT 位,当 DMA 控制器是在访问使用DMA_SxM0AR 时 CT=0,此时 CPU 不能访问 DMA_SxM0AR,但可以向 DMA_SxM1AR填充或者读取数据;当 DMA 控制器是在访问使用 DMA_SxM1AR 时 CT=1,此时 CPU 不能访问 DMA_SxM1AR,但可以向 DMA_SxM0AR 填充或者读取数据。另外在未使能DMA 数据流传输时,可以直接写 CT 位,改变开始传输的目标存储区。

双缓冲模式应用在需要解码程序的地方是非常有效的。比如 MP3 格式音频解码播放,MP3 是被压缩的文件格式,我们需要特定的解码库程序来解码文件才能得到可以播放的PCM 信号,解码需要一定的实际,按照常规方法是读取一段原始数据到缓冲区,然后对缓冲区内容进行解码,解码后才输出到音频播放电路,这种流程对 CPU 运算速度要求高,很容易出现播放不流畅现象。如果我们使用 DMA 双缓冲模式传输数据就可以非常好的解决这个问题,达到解码和输出音频数据到音频电路同步进行的效果。

8、DMA中断

每个 DMA 数据流可以在发送以下事件时产生中断:

  1. 达到半传输: DMA 数据传输达到一半时 HTIF 标志位被置 1,如果使能 HTIE 中断控制位将产生达到半传输中断;

  2. 传输完成: DMA 数据传输完成时 TCIF 标志位被置 1,如果使能 TCIE 中断控制位将产生传输完成中断;

  3. 传输错误: DMA 访问总线发生错误或者在双缓冲模式下试图访问“受限”存储器地址寄存器时 TEIF 标志位被置 1,如果使能 TEIE 中断控制位将产生传输错误中断;

  4. FIFO 错误:发生 FIFO 下溢或者上溢时 FEIF 标志位被置 1,如果使能 FEIE 中断控制位将产生 FIFO 错误中断;

  5. 直接模式错误:在外设到存储器的直接模式下,因为存储器总线没得到授权,使得先前数据没有完成被传输到存储器空间上, 此时 DMEIF 标志位被置 1,如果使能 DMEIE 中断控制位将产生直接模式错误中断。

DMA初始化结构体详解

DMA_ InitTypeDef 初始化结构体

typedef struct {
    uint32_t DMA_Channel; //通道选择
    uint32_t DMA_PeripheralBaseAddr; //外设地址
    uint32_t DMA_Memory0BaseAddr; //存储器 0 地址
    uint32_t DMA_DIR; //传输方向
    uint32_t DMA_BufferSize; //数据数目
    uint32_t DMA_PeripheralInc; //外设递增
    uint32_t DMA_MemoryInc; //存储器递增
    uint32_t DMA_PeripheralDataSize; //外设数据宽度
    uint32_t DMA_MemoryDataSize; //存储器数据宽度
    uint32_t DMA_Mode; //模式选择
    uint32_t DMA_Priority; //优先级
    uint32_t DMA_FIFOMode; //FIFO 模式
    uint32_t DMA_FIFOThreshold; //FIFO 阈值
    uint32_t DMA_MemoryBurst; //存储器突发传输
    uint32_t DMA_PeripheralBurst; //外设突发传输
} DMA_InitTypeDef;
  1. DMA_Channel: DMA 请求通道选择,可选通道 0 至通道 7,每个外设对应固定的通道,具体设置值需要查表 21-1 和表 21-2;它设 定 DMA_SxCR 寄存器 的CHSEL[2:0]位的值。例如,我们使用模拟数字转换器 ADC3 规则采集 4 个输入通道的电压数据,查表 21-2 可知使用通道 2。

  2. DMA_PeripheralBaseAddr:外设地址,设定 DMA_SxPAR 寄存器的值;一般设置为外设的数据寄存器地址,如果是存储器到存储器模式则设置为其中一个存储区地址。 ADC3 的数据寄存器ADC_DR 地址为((uint32_t)ADC3+0x4C)。

  3. DMA_Memory0BaseAddr:存储器 0 地址,设定 DMA_SxM0AR 寄存器值;一般设置为我们自定义存储区的首地址。我们程序先自定义一个 16 位无符号整形数组ADC_ConvertedValue[4]用来存放每个通道的 ADC 值,所以把数组首地址(直接使用数组名即可)赋值给 DMA_Memory0BaseAddr。

  4. DMA_DIR:传输方向选择,可选外设到存储器、存储器到外设以及存储器到存储器。它设定 DMA_SxCR 寄存器的 DIR[1:0]位的值。 ADC 采集显然使用外设到存储器模式。

  5. DMA_BufferSize:设定待传输数据数目,初始化设定 DMA_SxNDTR 寄存器的值。这里 ADC 是采集 4 个通道数据,所以待传输数目也就是 4。

  6. DMA_PeripheralInc:如果配置为 DMA_PeripheralInc_Enable,使能外设地址自动递增功能,它设定 DMA_SxCR 寄存器的 PINC 位的值;一般外设都是只有一个数据寄存器,所以一般不会使能该位。 ADC3 的数据寄存器地址是固定并且只有一个所以不使能外设地址递增。

  7. DMA_MemoryInc:如果配置为 DMA_MemoryInc_Enable,使能存储器地址自动递增功能,它设定 DMA_SxCR 寄存器的 MINC 位的值;我们自定义的存储区一般都是存放多个数据的,所以使能存储器地址自动递增功能。我们之前已经定义了一个包含 4 个元素的数字用来存放数据,使能存储区地址递增功能,自动把每个通道数据存放到对应数组元素内。

  8. DMA_PeripheralDataSize:外设数据宽度,可选字节(8 位)、半字(16 位)和字(32位),它设定 DMA_SxCR 寄存器的 PSIZE[1:0]位的值。 ADC 数据寄存器只有低 16位数据有效,使用半字数据宽度。

  9. DMA_MemoryDataSize:存储器数据宽度,可选字节(8 位)、半字(16 位)和字(32位),它设定 DMA_SxCR 寄存器的 MSIZE[1:0]位的值。保存 ADC 转换数据也要使用半字数据宽度,这跟我们定义的数组是相对应的。

  10. DMA_Mode : DMA 传 输 模 式 选 择 , 可 选 一 次 传 输 或 者 循 环 传 输 , 它 设 定DMA_SxCR 寄存器的 CIRC 位的值。我们希望 ADC 采集是持续循环进行的,所以使用循环传输模式。

  11. DMA_Priority:软件设置数据流的优先级,有 4 个可选优先级分别为非常高、高、中和低,它设定 DMA_SxCR 寄存器的 PL[1:0]位的值。 DMA 优先级只有在多个DMA 数据流同时使用时才有意义,这里我们设置为非常高优先级就可以了。

  12. DMA_FIFOMode:FIFOを示すセットモードDMA_FIFOMode_Enable機能が有効になっている場合、FIFOモードが有効になっている。DMDISはそれがDMA_SxFCRレジスタを設定するビットです。FIFOモードを使用することなく直接透過モードにADCの取得および伝送、。

  13. DMA_FIFOThreshold:FIFOしきい値の選択は、4つの状態が1 / 4,1 / 2、3/4、フルの選択可能なFIFO容量であり、FTH DMA_SxFCR [1:0]レジスタに設定されている。DMA_FIFOModeはDMA_FIFOMode_Disableを設定する、ことビットDMA_FIFOThreshold値が無効です。ADCの取得および送信FIFOモードを使用しない場合、無効な値が変化するように設定されています。

  14. DMA_MemoryBurst:バーストモードメモリを選択すると、増分バーストモードはメニュー次モード、インクリメントバーストモード4ビート、ビートインクリメントバーストモードMBURST DMA_SxCR [1設定レジスタ8または16拍をすることができます。値0]。ADCは、直接取得送信モードであるシングルモードの使用を必要とします。

  15. DMA_PeripheralBurst:周辺バーストモード選択、メニュー次モードは、バーストモード4,8又は16拍がバーストモードをインクリメントビートのインクリメント・バーストモードをインクリメントビート、それは、[1 PBURSTレジスタDMA_SxCR設定します:0]ビット。ADCは、直接取得送信モードであるシングルモードの使用を必要とします。

メモリテストモードへのDMAメモリ

メモリコピーモードへのメモリは、2つのメモリで高速なデータを得ることができます。まず静的データソースを定義し、ターゲットアドレス、送信が正確かどうかを確認するデータのデータ・ソースと宛先アドレスの最終的な比較にソースデータをコピーするために、DMA転送を使用します。

おすすめ

転載: www.cnblogs.com/luoxiao23/p/11209857.html