DMA(直接存储器访问)核心用法(实操指南)
2026/7/3 17:29:24 网站建设 项目流程

一、DMA核心原理(极简理解)
DMA(Direct Memory Access,直接存储器访问)是一种硬件机制,核心作用是:无需CPU干预,直接实现「内存与外设」「内存与内存」之间的数据传输,将CPU从繁琐的IO传输任务中解放出来,让CPU专注于核心运算,这也是提升CPU利用率的关键手段。
核心优势:传输过程不占用CPU资源,仅在传输开始和结束时,通过中断通知CPU(可选),大幅减少CPU的IO等待时间。
二、DMA核心用法(按场景分类,嵌入式实操为主)
2.1 核心适用场景(必记)
DMA仅用于「数据传输」,不执行任何运算,以下场景优先使用,效果最明显:

  • 外设→内存:如UART串口接收数据、ADC采集数据,直接传输到RAM,无需CPU逐字节读取。
  • 内存→外设:如UART串口发送数据、DAC输出数据,直接从RAM读取数据传输到外设,无需CPU干预。
  • 内存→内存:如RAM中数据复制、缓存数据搬运,适合大量数据快速传输(如数组复制)。
    2.2 DMA核心操作步骤(通用流程,所有场景适配)
    无论哪种场景,DMA使用都遵循「初始化→配置→启动→中断(可选)→关闭」的核心流程,以STM32(嵌入式最常用)为例,步骤如下:
  1. 开启DMA时钟:启动DMA控制器及对应外设的时钟(如UART、ADC时钟),确保硬件正常工作。
  2. 配置DMA通道:选择对应的DMA通道(不同外设对应固定DMA通道,参考芯片手册),设置通道优先级(高/中/低)。
  3. 配置传输参数:设置传输方向(如外设→内存)、数据宽度(8位/16位/32位)、传输数量(需传输的字节数/数据个数)。
  4. 设置源地址与目标地址:
  • 源地址:传输数据的起始地址(如外设数据寄存器地址、RAM数组起始地址),需设置为「不可变」或「可变」(根据传输需求)。

  • 目标地址:接收数据的起始地址(如RAM数组起始地址、外设数据寄存器地址),同理设置地址变化模式。

  1. 开启DMA中断(可选):若需要知道传输完成状态,开启「传输完成中断」,在中断服务函数中处理后续逻辑(如标记传输完成、启动下一次传输)。
  2. 启动DMA传输:开启DMA通道,开始自动数据传输,此时CPU可执行其他运算任务。
  3. 传输结束处理:传输完成后,关闭DMA通道(按需),清除中断标志(若开启中断)。
    2.3 三大核心场景实操示例(STM32,C语言)
    场景1:内存→外设(UART串口DMA发送数据)
    需求:将RAM中数组的数据,通过UART串口DMA发送,无需CPU干预。
    // 1. 定义发送数据(RAM中)
    uint8_t send_buf[] = “DMA UART Send Test”;
    uint16_t send_len = sizeof(send_buf) - 1; // 排除字符串结束符

// 2. DMA初始化(STM32F103,DMA1_Channel4对应USART1_TX)

voidDMA_UART_Send_Init(void){// 开启时钟RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);// DMA配置结构体DMA_InitTypeDef DMA_InitStruct;DMA_InitStruct.DMA_PeripheralBaseAddr=(uint32_t)&USART1->DR;// 外设地址(UART数据寄存器)DMA_InitStruct.DMA_MemoryBaseAddr=(uint32_t)send_buf;// 内存地址(发送数组)DMA_InitStruct.DMA_DIR=DMA_DIR_PeripheralDST;// 传输方向:内存→外设DMA_InitStruct.DMA_BufferSize=send_len;// 传输数量DMA_InitStruct.DMA_PeripheralInc=DMA_PeripheralInc_Disable;// 外设地址不变DMA_InitStruct.DMA_MemoryInc=DMA_MemoryInc_Enable;// 内存地址递增(逐字节发送)DMA_InitStruct

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询