跳到主要内容

STM32 DMA 存储器到存储器

介绍

DMA(Direct Memory Access,直接存储器访问)是 STM32 微控制器中一种强大的功能,它允许外设与存储器之间或存储器与存储器之间直接传输数据,而无需 CPU 的干预。这种机制可以显著提高数据传输效率,减少 CPU 的负担。

在 STM32 中,DMA 的存储器到存储器模式是一种特殊的传输模式,它允许数据在两个存储器区域之间直接传输,而不需要通过外设。这种模式非常适合需要快速复制或移动大量数据的场景。

DMA 存储器到存储器的工作原理

在存储器到存储器模式下,DMA 控制器会从源地址读取数据,并将其写入目标地址。整个过程由 DMA 控制器自动完成,CPU 只需初始化 DMA 并启动传输。

关键概念

  • 源地址(Source Address):数据读取的起始地址。
  • 目标地址(Destination Address):数据写入的起始地址。
  • 数据长度(Data Length):需要传输的数据量,通常以字节、半字或字为单位。
  • 传输模式(Transfer Mode):可以是单次传输或循环传输。

配置 STM32 DMA 存储器到存储器模式

以下是一个简单的代码示例,展示如何配置 STM32 的 DMA 控制器以实现存储器到存储器的数据传输。

代码示例

c
#include "stm32f4xx.h"

#define BUFFER_SIZE 32

uint32_t srcBuffer[BUFFER_SIZE] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A};
uint32_t dstBuffer[BUFFER_SIZE];

void DMA_Config(void) {
// 启用 DMA2 时钟
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);

// 配置 DMA2 Stream0
DMA_InitTypeDef DMA_InitStruct;
DMA_InitStruct.DMA_Channel = DMA_Channel_0;
DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)srcBuffer;
DMA_InitStruct.DMA_Memory0BaseAddr = (uint32_t)dstBuffer;
DMA_InitStruct.DMA_DIR = DMA_DIR_MemoryToMemory;
DMA_InitStruct.DMA_BufferSize = BUFFER_SIZE;
DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Enable;
DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;
DMA_InitStruct.DMA_Mode = DMA_Mode_Normal;
DMA_InitStruct.DMA_Priority = DMA_Priority_High;
DMA_InitStruct.DMA_FIFOMode = DMA_FIFOMode_Disable;
DMA_InitStruct.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
DMA_InitStruct.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStruct.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_Init(DMA2_Stream0, &DMA_InitStruct);

// 启用 DMA2 Stream0
DMA_Cmd(DMA2_Stream0, ENABLE);

// 等待传输完成
while (DMA_GetFlagStatus(DMA2_Stream0, DMA_FLAG_TCIF0) == RESET);
}

int main(void) {
DMA_Config();

// 验证数据传输
for (int i = 0; i < BUFFER_SIZE; i++) {
if (srcBuffer[i] != dstBuffer[i]) {
// 数据传输错误
while (1);
}
}

// 数据传输成功
while (1);
}

代码解释

  1. 启用 DMA2 时钟:首先需要启用 DMA2 的时钟,因为 DMA 控制器是挂载在 AHB 总线上的。
  2. 配置 DMA 流:通过 DMA_InitTypeDef 结构体配置 DMA 流的各项参数,包括源地址、目标地址、数据长度、传输方向等。
  3. 启动 DMA 传输:调用 DMA_Cmd 函数启动 DMA 传输。
  4. 等待传输完成:通过检查 DMA 标志位来等待传输完成。
  5. 验证数据传输:在传输完成后,可以通过比较源缓冲区和目标缓冲区的内容来验证数据传输是否正确。

实际应用场景

数据复制

在某些应用中,可能需要将数据从一个存储器区域复制到另一个存储器区域。例如,在图像处理中,可能需要将图像数据从外部存储器复制到内部 RAM 中进行处理。使用 DMA 存储器到存储器模式可以高效地完成这一任务。

数据移动

在嵌入式系统中,有时需要将数据从一个缓冲区移动到另一个缓冲区。例如,在音频处理中,可能需要将音频数据从输入缓冲区移动到输出缓冲区。使用 DMA 存储器到存储器模式可以快速完成数据移动,而不会占用 CPU 资源。

总结

STM32 的 DMA 存储器到存储器模式是一种强大的工具,可以显著提高数据传输效率,减少 CPU 的负担。通过合理配置 DMA 控制器,可以实现高效的数据复制和移动操作。

提示

在实际应用中,建议根据具体需求选择合适的 DMA 通道和流,并合理配置 DMA 参数,以确保数据传输的准确性和效率。

附加资源与练习

  • STM32 参考手册:详细了解 STM32 的 DMA 控制器及其配置方法。
  • 练习:尝试修改上述代码,实现不同数据长度和传输模式的 DMA 传输,并观察传输效果。

通过本文的学习,你应该已经掌握了 STM32 DMA 存储器到存储器模式的基本原理和配置方法。希望你能在实际项目中灵活运用这一功能,提升系统的性能。