🎓 总站 🏠 本课目录 01 概述 02 ARM与STM32 03 开发环境 04 最小系统与C 05 GPIO 06 中断 07 串口通信 08 DMA 09 定时器 10 ADC 11 从模块到项目 12 嵌入式操作系统
智能嵌入式系统设计 · 第8章

直接存储器访问 DMA

基于 STM32F103 · 零基础讲解 DMA 原理、通道配置、标准库与 HAL 库编程。

📚 学习进度
0%

🎯学习目标

  • 了解 DMA 的基本概念、用途和优势;
  • 理解 DMA 与 CPU 的关系,明白为什么需要 DMA;
  • 理解 STM32 的 DMA 模块结构和工作原理;
  • 熟悉 DMA 通道、优先级、传输方向等核心概念;
  • 掌握 DMA 配置流程和关键参数设置;
  • 熟悉 STM32 标准库和 HAL 库中有关 DMA 的库函数;
  • 掌握用标准库开发 DMA 应用程序的方法;
  • 掌握用 HAL 库开发 DMA 应用程序的方法;
  • 能够独立完成 ADC+DMA、串口+DMA 等常见应用。

1DMA 概述

DMA(Direct Memory Access,直接存储器访问)是一种在存储器和外设之间、存储器和存储器之间进行高速数据传输的方式。

💡 一句话理解DMA 就是数据搬运工,不需要 CPU 亲自搬数据,CPU 只需告诉 DMA 从哪搬、搬到哪、搬多少,然后就可以去做其他事情了。
💡 通俗理解:为什么需要 DMA?

想象你要把一箱书从房间 A 搬到房间 B。没有 DMA:你(CPU)必须自己一本一本搬,搬的时候什么都干不了。有 DMA:你叫一个搬运工(DMA),告诉他从哪搬、搬到哪、搬多少本,然后你就可以去学习了。搬运工搬完会告诉你(中断)。

好处:CPU 不被数据搬运占用,可以同时处理其他任务,系统效率大大提高。

💡 通俗理解:DMA 和 CPU 的关系

把 CPU 想象成公司老板,DMA 是快递员

没有 DMA 的公司:老板(CPU)亲自搬货,累得要死,没时间做决策(处理业务逻辑)。

有 DMA 的公司:老板(CPU)告诉快递员(DMA):从仓库A(外设)搬到办公室B(内存),搬100箱。然后老板就可以去开会了。快递员搬完后打电话(中断)告诉老板:"搬完了!"

关键点:DMA 搬运数据时,CPU 完全"解放",可以去执行其他代码。这就是为什么 DMA 能大幅提高系统效率。

⭐ DMA 的三大优势
  • 高速传输:DMA 直接控制总线,传输速度可达总线最高速度,不经过 CPU 中转;
  • CPU 解放:CPU 只需配置一次,之后 DMA 自动搬运,CPU 可以处理其他任务;
  • 实时性好:对于 ADC 采样、串口通信等实时性要求高的场景,DMA 能保证数据及时搬运。
💡 什么时候用 DMA?
  • ADC 连续采集:ADC 每转换完一次,数据自动存入内存数组,CPU 不用每次都去读;
  • 串口大批量发送:把内存数组通过串口发出,CPU 不用一个字节一个字节地发;
  • 串口接收数据:串口收到数据自动存入内存,CPU 不用每次都去读寄存器;
  • 存储器拷贝:把一块内存数据快速拷贝到另一块内存;
  • SPI/I2C 通信:高速数据传输场景。

2DMA 工作原理

DMA 传输不需要 CPU 干预,DMA 控制器直接控制总线,完成数据搬运。传输过程:

  1. CPU 配置 DMA:源地址、目标地址、传输数量、传输方向等;
  2. DMA 请求:外设发出请求(如 ADC 转换完成、串口收到数据);
  3. DMA 响应:DMA 控制器获得总线控制权;
  4. DMA 传输:自动搬运数据,每搬一个数据,地址和计数器自动更新;
  5. 传输完成:DMA 释放总线,可触发中断通知 CPU。
CPU DMA 存储器 外设 总线 ① 配置 ② 请求 ③ 传输 ④ 中断
图1 · DMA 工作流程:CPU 配置 → 外设请求 → DMA 传输 → 中断通知
⭐ DMA 传输方向
  • 外设 → 存储器:如 ADC 采集数据存入内存;
  • 存储器 → 外设:如内存数据通过串口发送;
  • 存储器 → 存储器:如内存数据拷贝到另一块内存。
💡 通俗理解:三种传输方向

外设→存储器(收快递):数据从外部设备(如 ADC、串口)送到内存。比如温度传感器采集数据,通过 DMA 自动存到数组里。

存储器→外设(寄快递):数据从内存送到外部设备(如串口)。比如要把一个数组通过串口发出去,DMA 自动从数组取数据发给串口。

存储器→存储器(搬家):数据从一块内存搬到另一块内存。比如把数组 A 的内容拷贝到数组 B。

DMA 传输的关键参数

参数说明举例
源地址数据从哪里来ADC 数据寄存器地址
目标地址数据送到哪里去内存数组首地址
传输方向外设→存储器、存储器→外设、存储器→存储器外设→存储器
传输数量要搬运多少个数据100 个
数据宽度每次搬运多大的数据(字节/半字/字)半字(16位)
地址自增每搬完一个数据,地址是否自动+1存储器地址自增
循环模式搬完一轮后是否自动重新开始循环模式
优先级多个通道同时请求时谁先搬高优先级

3STM32 DMA 结构

STM32F103 有 2 个 DMA 控制器,DMA1 有 7 个通道,DMA2 有 5 个通道(仅大容量产品有 DMA2)。

💡 通道与请求每个通道对应一个外设请求,不同通道有不同的优先级。同一时刻,一个通道只能服务一个外设。
DMA1 DMA2 CH1 CH2 CH3 CH4 CH5 CH6 CH7 ADC1、TIM2_CH3、TIM4_CH1 ... USART3_TX、TIM3_CH4、TIM2_CH2 ... USART3_RX、TIM3_CH3、TIM2_CH4 ... USART1_TX、SPI2_TX、TIM1_CH4 ... USART1_RX、SPI2_RX、TIM1_CH3 ... USART2_RX、I2C1_TX、TIM1_CH1 ... USART2_TX、I2C1_RX、TIM1_CH2 ...
图2 · DMA1 通道与外设请求映射(DMA2 类似,仅大容量产品有)
DMA 控制器通道数请求源
DMA17 个通道ADC1、USART1/2/3、SPI1/2、I2C1/2、TIM1/2/3/4 等
DMA25 个通道ADC3、SPI/I2S3、UART4/5、TIM5/6/7/8 等

DMA 优先级

当多个 DMA 通道同时请求传输时,需要仲裁器决定谁先传输。STM32 DMA 优先级分为 4 个等级

优先级说明
非常高(Very High)最高优先级,最先响应
(High)第二优先级
(Medium)第三优先级
(Low)最低优先级,最后响应
💡 优先级规则
  • 优先级高的通道先传输;
  • 如果优先级相同,通道号小的先传输(CH1 > CH2 > CH3 ...);
  • 优先级在配置时设置,运行时不能改变。

DMA 传输模式

模式说明适用场景
正常模式传输完成后停止,需要重新使能才能再次传输单次数据传输
循环模式传输完成后自动重新开始,循环往复ADC 连续采集、音频播放
⭐ 循环模式 vs 正常模式

正常模式:搬完一轮就停止,适合"一次性搬运"场景,比如发送一帧数据。

循环模式:搬完一轮自动重头开始,适合"持续采集"场景,比如 ADC 不断采样。循环模式下,DMA 会自动覆盖之前的数据(除非你及时处理)。

4DMA 配置流程

使用 DMA 的一般步骤:

  1. 使能 DMA 时钟;
  2. 配置 DMA 通道参数:外设地址、存储器地址、传输方向、数据量、地址自增、循环模式等;
  3. 使能 DMA 通道;
  4. 使能外设的 DMA 请求(如 ADC_DMACmd、USART_DMACmd);
  5. (可选)配置 DMA 中断,处理传输完成事件。
配置结构体(标准库)
DMA_InitTypeDef DMA_InitStructure;
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR;  // 外设地址
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&adc_buf;       // 存储器地址
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;               // 方向:外设→存储器
DMA_InitStructure.DMA_BufferSize = 100;                           // 传输数量
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;  // 外设地址不自增
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;           // 存储器地址自增
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;                   // 循环模式
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;                     // 非存储器到存储器
DMA_Init(DMA1_Channel1, &DMA_InitStructure);
💡 配置参数详解
  • PeripheralBaseAddr:外设数据寄存器地址,如 ADC1->DR、USART1->DR;
  • MemoryBaseAddr:内存数组首地址,如 adc_buf[0] 的地址;
  • DIR:传输方向,DMA_DIR_PeripheralSRC(外设→存储器)、DMA_DIR_PeripheralDST(存储器→外设);
  • BufferSize:要传输的数据个数,不是字节数;
  • PeripheralInc:外设地址是否自增,一般外设只有一个数据寄存器,不需要自增;
  • MemoryInc:存储器地址是否自增,存到数组时需要自增;
  • PeripheralDataSize / MemoryDataSize:数据宽度,字节(8位)、半字(16位)、字(32位);
  • Mode:DMA_Mode_Normal(正常)、DMA_Mode_Circular(循环);
  • Priority:优先级,Low/Medium/High/VeryHigh;
  • M2M:是否为存储器到存储器模式,ENABLE/DISABLE。
💡 配置顺序很重要

① 先使能 DMA 时钟(RCC_AHBPeriphClockCmd);

② 再配置 DMA 通道参数(DMA_Init);

③ 然后使能 DMA 通道(DMA_Cmd);

④ 最后使能外设的 DMA 请求(如 ADC_DMACmd)。

注意:如果先使能外设 DMA 请求,再使能 DMA 通道,可能会丢失第一次请求。

5标准库函数

常用 DMA 标准库函数(源码在 stm32f10x_dma.c):

函数功能参数说明
DMA_Init()初始化 DMA 通道DMA_Channelx, DMA_InitStruct
DMA_DeInit()恢复默认值DMA_Channelx
DMA_Cmd()使能/禁用 DMA 通道DMA_Channelx, ENABLE/DISABLE
DMA_SetCurrDataCounter()设置传输数量DMA_Channelx, DataNumber
DMA_GetCurrDataCounter()获取剩余传输数量DMA_Channelx
DMA_GetFlagStatus()获取 DMA 标志位DMA_FLAG_xxx
DMA_ClearFlag()清除 DMA 标志位DMA_FLAG_xxx
DMA_ITConfig()配置 DMA 中断DMA_Channelx, DMA_IT_xxx, ENABLE/DISABLE
DMA_GetITStatus()获取中断状态DMA_IT_xxx
DMA_ClearITPendingBit()清除中断挂起位DMA_IT_xxx
函数原型示例
// 初始化 DMA 通道
void DMA_Init(DMA_Channel_TypeDef* DMA_Channelx, DMA_InitTypeDef* DMA_InitStruct);

// 使能/禁用 DMA 通道
void DMA_Cmd(DMA_Channel_TypeDef* DMA_Channelx, FunctionalState NewState);

// 设置传输数量(可在运行时修改)
void DMA_SetCurrDataCounter(DMA_Channel_TypeDef* DMA_Channelx, uint16_t DataNumber);

// 获取剩余传输数量
uint16_t DMA_GetCurrDataCounter(DMA_Channel_TypeDef* DMA_Channelx);

// 获取标志位状态
FlagStatus DMA_GetFlagStatus(uint32_t DMA_FLAG);

// 清除标志位
void DMA_ClearFlag(uint32_t DMA_FLAG);

// 配置中断
void DMA_ITConfig(DMA_Channel_TypeDef* DMA_Channelx, uint32_t DMA_IT, FunctionalState NewState);
💡 常用标志位
  • DMA1_FLAG_TC1:DMA1 通道 1 传输完成标志;
  • DMA1_FLAG_HT1:DMA1 通道 1 半传输完成标志;
  • DMA1_FLAG_GL1:DMA1 通道 1 全局标志(传输完成或半传输);
  • DMA1_FLAG_TE1:DMA1 通道 1 传输错误标志。

6HAL 库函数

HAL 库中 DMA 相关函数(源码在 stm32f1xx_hal_dma.c):

函数功能参数说明
HAL_DMA_Init()初始化 DMAhdma(DMA_HandleTypeDef 指针)
HAL_DMA_Start()启动 DMA 传输(无中断)hdma, SrcAddress, DstAddress, DataLength
HAL_DMA_Start_IT()启动 DMA 传输(带中断)hdma, SrcAddress, DstAddress, DataLength
HAL_DMA_Abort()中止 DMA 传输hdma
HAL_DMA_GetState()获取 DMA 状态hdma
HAL_DMA_GetError()获取 DMA 错误hdma
HAL 库 DMA 配置示例
// DMA 句柄
DMA_HandleTypeDef hdma_adc1;

// 配置 DMA
hdma_adc1.Instance = DMA1_Channel1;  // DMA1 通道 1
hdma_adc1.Init.Direction = DMA_PERIPH_TO_MEMORY;  // 外设→存储器
hdma_adc1.Init.PeriphInc = DMA_PINC_DISABLE;      // 外设地址不自增
hdma_adc1.Init.MemInc = DMA_MINC_ENABLE;           // 存储器地址自增
hdma_adc1.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;  // 外设数据半字
hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;     // 存储器数据半字
hdma_adc1.Init.Mode = DMA_CIRCULAR;  // 循环模式
hdma_adc1.Init.Priority = DMA_PRIORITY_HIGH;  // 高优先级
HAL_DMA_Init(&hdma_adc1);

// 启动 DMA 传输(带中断)
HAL_DMA_Start_IT(&hdma_adc1, (uint32_t)&ADC1->DR, (uint32_t)adc_buf, 100);
💡 HAL 库 DMA 配置使用 STM32CubeMX 可以图形化配置 DMA,自动生成初始化代码。在 CubeMX 中,点击 "DMA" 标签页,添加通道,设置参数即可。
💡 HAL 库回调函数

HAL 库提供了 DMA 传输完成回调函数,可以在中断中自动调用:

// 传输完成回调
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc) {
    // DMA 传输完成,处理数据
}

// 半传输完成回调(循环模式下很有用)
void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef* hadc) {
    // 半传输完成,可以处理前半部分数据
}

重点例题

例题1:ADC+DMA 采集(标准库)

用 DMA 方式采集 ADC1 通道 0 的数据,存入数组 思路:① 配置 ADC1 通道 0;② 配置 DMA1 通道 1;③ 使能 ADC 的 DMA 请求;④ 启动 ADC 和 DMA。
// 1. 配置 ADC(省略详细配置)
// 2. 配置 DMA
DMA_InitTypeDef DMA_InitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);  // 使能 DMA1 时钟

DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR;
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)adc_buf;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize = 100;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel1, &DMA_InitStructure);
DMA_Cmd(DMA1_Channel1, ENABLE);

// 3. 使能 ADC 的 DMA 请求
ADC_DMACmd(ADC1, ENABLE);

// 4. 启动 ADC 转换
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
关键点:① 必须先使能 DMA 时钟;② ADC 的 DMA 请求必须在 DMA 使能之后;③ 循环模式下 DMA 会自动重新开始。

例题2:ADC+DMA 采集(HAL 库)

用 HAL 库实现 ADC+DMA 采集 思路:① CubeMX 配置 ADC 和 DMA;② 生成代码;③ 启动 DMA 传输。
// CubeMX 自动生成的代码
ADC_HandleTypeDef hadc1;
DMA_HandleTypeDef hdma_adc1;
uint16_t adc_buf[100];

// 启动 ADC+DMA 采集
HAL_ADC_Start_DMA(&hadc1, (uint32_t*)adc_buf, 100);

// 传输完成回调(自动调用)
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc) {
    // 100 个数据采集完成,可以处理数据
}

// 半传输完成回调
void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef* hadc) {
    // 前 50 个数据采集完成
}
关键点:① CubeMX 配置更简单;② HAL 库自动处理中断;③ 回调函数自动调用。

例题3:串口+DMA 发送(标准库)

用 DMA 方式通过 USART1 发送数据 思路:① 配置 USART1;② 配置 DMA1 通道 4(USART1_TX);③ 使能 USART 的 DMA 发送请求;④ 启动 DMA。
// 1. 配置 USART1(省略详细配置)
// 2. 配置 DMA1 通道 4(USART1_TX)
DMA_InitTypeDef DMA_InitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART1->DR;
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)tx_buf;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;  // 存储器→外设
DMA_InitStructure.DMA_BufferSize = 100;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;  // 正常模式
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel4, &DMA_InitStructure);

// 3. 使能 USART1 的 DMA 发送请求
USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);

// 4. 启动 DMA 传输
DMA_Cmd(DMA1_Channel4, ENABLE);
关键点:① 串口发送用 DMA1 通道 4;② 方向是存储器→外设;③ 正常模式(发完就停)。

例题4:串口+DMA 接收(标准库)

用 DMA 方式通过 USART1 接收数据 思路:① 配置 USART1;② 配置 DMA1 通道 5(USART1_RX);③ 使能 USART 的 DMA 接收请求;④ 启动 DMA。
// 1. 配置 USART1(省略详细配置)
// 2. 配置 DMA1 通道 5(USART1_RX)
DMA_InitTypeDef DMA_InitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART1->DR;
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)rx_buf;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;  // 外设→存储器
DMA_InitStructure.DMA_BufferSize = 100;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;  // 正常模式
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel5, &DMA_InitStructure);

// 3. 使能 USART1 的 DMA 接收请求
USART_DMACmd(USART1, USART_DMAReq_Rx, ENABLE);

// 4. 启动 DMA 传输
DMA_Cmd(DMA1_Channel5, ENABLE);
关键点:① 串口接收用 DMA1 通道 5;② 方向是外设→存储器;③ 可以配置循环模式持续接收。

例题5:存储器到存储器拷贝(标准库)

用 DMA 方式将数组 A 拷贝到数组 B 思路:① 配置 DMA 为存储器到存储器模式;② 设置源地址和目标地址;③ 启动传输。
uint8_t src_buf[100] = {1, 2, 3, ...};
uint8_t dst_buf[100];

// 配置 DMA1 通道 1(存储器到存储器模式)
DMA_InitTypeDef DMA_InitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)src_buf;
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)dst_buf;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;  // 外设→存储器(这里的"外设"是源存储器)
DMA_InitStructure.DMA_BufferSize = 100;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Enable;  // 源地址自增
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;           // 目标地址自增
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Enable;  // 存储器到存储器模式
DMA_Init(DMA1_Channel1, &DMA_InitStructure);

// 启动传输(存储器到存储器模式不需要外设请求)
DMA_Cmd(DMA1_Channel1, ENABLE);

// 等待传输完成
while(DMA_GetFlagStatus(DMA1_FLAG_TC1) == RESET);
DMA_ClearFlag(DMA1_FLAG_TC1);
关键点:① M2M 必须设置为 ENABLE;② 两个地址都要自增;③ 存储器到存储器模式不需要外设请求,使能 DMA 通道就开始传输。

🎯自测(点击展开)

DMA 的全称是什么?
Direct Memory Access,直接存储器访问。
DMA 传输有哪三个方向?
外设→存储器、存储器→外设、存储器→存储器。
STM32F103 有几个 DMA 控制器?
2 个:DMA1(7 通道)和 DMA2(5 通道,仅大容量产品)。
DMA 传输完成后如何通知 CPU?
通过中断通知 CPU。
DMA 优先级有几个等级?
4 个:低、中、高、非常高。
循环模式和正常模式有什么区别?
正常模式传输完成后停止;循环模式传输完成后自动重新开始。
ADC+DMA 采集时,DMA 的源地址是什么?
ADC 的数据寄存器地址,如 ADC1->DR。
串口发送用 DMA1 的哪个通道?
DMA1 通道 4(USART1_TX)。
存储器到存储器模式需要设置哪个参数?
M2M 参数设置为 ENABLE。
使能 DMA 时钟的函数是什么?
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE)。

📝强化题库

选择题点选即时判分;填空题输入后"检查"或"显示答案"。

已答 0/0答对 0正确率
已答 0/0答对 0
智能嵌入式系统设计 · 第8章 DMA · 零基础交互讲义