资讯动态

嵌入式面试总结(十七)——DMA总线

发布时间:2026/8/14 23:57:44 来源:尧图企业网站定制
一、引言DMADirect Memory Access直接存储器访问是嵌入式系统中一项至关重要的核心技术它允许外设与内存之间直接进行数据传输而无需 CPU 的全程干预。在传统的程序控制或中断驱动的 I/O 方式中CPU 需要频繁地参与每一个数据单元的搬运这不仅消耗了宝贵的 CPU 周期也限制了系统的整体吞吐量。DMA 技术的出现正是为了解决这一瓶颈。其核心思想是CPU 仅需在传输开始前对 DMA 控制器进行初始化配置如设置源地址、目标地址、传输数据量等随后便可“抽身”去执行其他计算任务。数据传输过程则由 DMA 控制器接管系统总线在外设与内存之间直接完成。待整个数据块传输完毕DMA 控制器再通过中断通知 CPU。这种方式将 CPU 从繁琐的、重复性的数据搬运工作中解放出来显著提高了系统效率降低了 CPU 占用率尤其适用于音频/视频流处理、高速数据采集、网络通信等对实时性和带宽要求高的场景。理解 DMA 的工作原理、工作模式及其在嵌入式系统中的应用是嵌入式软件工程师面试中的高频考点也是进行高性能系统设计的基础。本文将从 DMA 的基本概念出发系统梳理其工作原理、传输模式、控制器结构、典型应用并解答常见的面试问题。二、DMA 工作原理DMA直接存储器访问的核心在于将 CPU 从繁重的数据搬运任务中解放出来实现外设与内存之间的高效、直接数据传输。其工作原理可以概括为“CPU 配置DMA 执行中断通知”。一次完整的 DMA 传输通常包含以下五个关键步骤CPU 初始化配置CPU 作为“导演”首先对 DMA 控制器进行编程。这包括设置源地址数据从哪里来如外设数据寄存器、目标地址数据到哪里去如内存缓冲区、传输数据量字节数或字数以及传输模式单次、块传输等。配置完成后CPU 使能 DMA 通道准备开始传输。外设发起传输请求当外设例如 UART 收到一个字节、ADC 完成一次转换准备好数据或需要发送数据时它会向 DMA 控制器发出一个硬件信号——DMA 请求DREQ。这相当于外设“举手”示意自己已就绪。DMA 控制器接管系统总线收到 DREQ 后DMA 控制器作为“总线主设备”会向 CPU 发出总线保持请求HOLD 或类似信号。CPU 在当前总线周期结束后会响应此请求释放对地址总线、数据总线和控制总线的控制权并通过总线保持应答HLDA信号通知 DMA 控制器“总线现在归你使用”。这个过程称为总线仲裁。DMA 执行数据传输获得总线控制权后DMA 控制器开始独立工作。它直接操纵总线从源地址读取数据然后写入目标地址。每完成一次传输如一个字节它会自动递增或递减地址寄存器并递减字节计数器。这个过程完全由硬件完成CPU 在此期间可以执行其他任务前提是不需要访问被 DMA 占用的总线。传输完成与中断通知当字节计数器减为零表示预设的数据量已全部传输完毕。DMA 控制器会撤销总线请求HOLD将总线控制权交还给 CPU。同时它通常会向 CPU 发出一个传输完成中断TCI通知 CPU 本次 DMA 传输已经结束。CPU 响应该中断后便可对传输完成的数据进行处理例如处理内存缓冲区中已接收到的完整数据包。核心优势在整个数据传输的“核心阶段”步骤4CPU 无需像中断方式那样为每个数据单元执行保存现场、搬运数据、恢复现场等一系列指令。DMA 通过硬件接管总线实现了数据的“直接”搬移从而大幅降低了 CPU 开销显著提升了系统整体吞吐量和实时性。三、DMA 传输模式DMA 控制器支持多种传输模式以适应不同的外设特性和应用场景。理解这些模式对于合理配置 DMA、优化系统性能至关重要。1. 单次传输模式每次外设请求只传输一个数据单元如一个字节或一个字传输完成后 DMA 控制器释放总线CPU 重新获得控制权。适用于低速、非连续的外设。实战代码示例STM32 HAL 库配置单次传输// 以 STM32 UART 接收 DMA 单次传输为例 #include stm32f4xx_hal.h UART_HandleTypeDef huart2; DMA_HandleTypeDef hdma_usart2_rx; uint8_t rx_buffer[1]; // 单字节缓冲区 void MX_DMA_Init(void) { __HAL_RCC_DMA1_CLK_ENABLE(); HAL_NVIC_SetPriority(DMA1_Stream5_IRQn, 0, 0); HAL_NVIC_EnableIRQ(DMA1_Stream5_IRQn); } void MX_USART2_UART_Init(void) { huart2.Instance USART2; huart2.Init.BaudRate 115200; huart2.Init.WordLength UART_WORDLENGTH_8B; huart2.Init.StopBits UART_STOPBITS_1; huart2.Init.Parity UART_PARITY_NONE; huart2.Init.Mode UART_MODE_TX_RX; huart2.Init.HwFlowCtl UART_HWCONTROL_NONE; huart2.Init.OverSampling UART_OVERSAMPLING_16; HAL_UART_Init(huart2); } void Start_DMA_Single_Transfer(void) { // 配置 DMA 为单次模式 hdma_usart2_rx.Instance DMA1_Stream5; hdma_usart2_rx.Init.Channel DMA_CHANNEL_4; hdma_usart2_rx.Init.Direction DMA_PERIPH_TO_MEMORY; hdma_usart2_rx.Init.PeriphInc DMA_PINC_DISABLE; hdma_usart2_rx.Init.MemInc DMA_MINC_ENABLE; hdma_usart2_rx.Init.PeriphDataAlignment DMA_PDATAALIGN_BYTE; hdma_usart2_rx.Init.MemDataAlignment DMA_MDATAALIGN_BYTE; hdma_usart2_rx.Init.Mode DMA_NORMAL; // 单次模式 hdma_usart2_rx.Init.Priority DMA_PRIORITY_LOW; hdma_usart2_rx.Init.FIFOMode DMA_FIFOMODE_DISABLE; HAL_DMA_Init(hdma_usart2_rx); // 关联 DMA 到 UART 接收 __HAL_LINKDMA(huart2, hdmarx, hdma_usart2_rx); // 启动 DMA 接收单次传输一个字节 HAL_UART_Receive_DMA(huart2, rx_buffer, 1); } // DMA 传输完成中断回调 void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { if (huart-Instance USART2) { // 处理接收到的单字节数据 rx_buffer[0] // 如需继续接收需重新调用 HAL_UART_Receive_DMA } }2. 块传输模式DMA 控制器在一次总线占用期间连续传输整个数据块多个数据单元直到计数器减为零。传输效率高但会长时间占用总线。实战代码示例STM32 ADC 多通道扫描 DMA 块传输// STM32 ADC 多通道扫描使用 DMA 块传输搬运数据 #include stm32f4xx_hal.h ADC_HandleTypeDef hadc1; DMA_HandleTypeDef hdma_adc1; uint16_t adc_buffer[3]; // 存储 3 个通道的转换结果 void MX_ADC1_Init(void) { ADC_ChannelConfTypeDef sConfig {0}; hadc1.Instance ADC1; hadc1.Init.ClockPrescaler ADC_CLOCK_SYNC_PCLK_DIV4; hadc1.Init.Resolution ADC_RESOLUTION_12B; hadc1.Init.ScanConvMode ENABLE; // 扫描模式 hadc1.Init.ContinuousConvMode ENABLE; hadc1.Init.DiscontinuousConvMode DISABLE; hadc1.Init.ExternalTrigConvEdge ADC_EXTERNALTRIGCONVEDGE_NONE; hadc1.Init.ExternalTrigConv ADC_SOFTWARE_START; hadc1.Init.DataAlign ADC_DATAALIGN_RIGHT; hadc1.Init.NbrOfConversion 3; hadc1.Init.DMAContinuousRequests ENABLE; // DMA 连续请求 hadc1.Init.EOCSelection ADC_EOC_SEQ_CONV; HAL_ADC_Init(hadc1); // 配置通道 0、1、2 sConfig.Channel ADC_CHANNEL_0; sConfig.Rank 1; sConfig.SamplingTime ADC_SAMPLETIME_3CYCLES; HAL_ADC_ConfigChannel(hadc1, sConfig); sConfig.Channel ADC_CHANNEL_1; sConfig.Rank 2; HAL_ADC_ConfigChannel(hadc1, sConfig); sConfig.Channel ADC_CHANNEL_2; sConfig.Rank 3; HAL_ADC_ConfigChannel(hadc1, sConfig); } void Start_ADC_DMA_Block_Transfer(void) { // 配置 DMA 为循环模式块传输的连续形式 hdma_adc1.Instance DMA2_Stream0; hdma_adc1.Init.Channel DMA_CHANNEL_0; 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; hdma_adc1.Init.FIFOMode DMA_FIFOMODE_DISABLE; HAL_DMA_Init(hdma_adc1); __HAL_LINKDMA(hadc1, DMA_Handle, hdma_adc1); // 启动 ADC 并开始 DMA 传输块传输 3 个通道数据 HAL_ADC_Start_DMA(hadc1, (uint32_t*)adc_buffer, 3); } // DMA 传输完成中断半传输和全传输 void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc) { if (hadc-Instance ADC1) { // adc_buffer 中已更新了 3 个通道的最新数据 // 可在此进行数据处理 } }3. 请求传输模式传输由外设的 DREQ 信号控制。只要 DREQ 有效DMA 就持续传输DREQ 无效则暂停总线交还 CPU。适用于数据产生速率不固定的场景。实战场景说明在请求传输模式下DMA 控制器会持续监测外设的 DREQDMA 请求信号。例如一个外部传感器通过 GPIO 引脚产生不规则的数据就绪信号。当 DREQ 为高时DMA 启动一次传输传输完成后若 DREQ 仍为高则继续下一次传输若 DREQ 变低则暂停并释放总线。这种模式常见于需要根据外部事件节奏进行数据传输的场合如从 FIFO 读取数据。4. 级联模式多个 DMA 控制器级联扩展通道数。一个主 DMA 控制器可以管理多个从 DMA 控制器。配置要点主 DMA 控制器的通道配置为级联模式其“外设”实际上是另一个从DMA 控制器。从 DMA 控制器负责实际的数据传输其传输完成信号会触发主 DMA 控制器。这种方式可以扩展出更多的 DMA 通道用于非常复杂的多外设、多缓冲区场景。模式选择建议传输模式适用场景CPU 占用总线占用单次传输低速外设、非连续数据如按键扫描、单字节 UART低每次传输后释放总线短时占用块传输高速、连续数据流如 ADC 多通道采样、LCD 刷新极低传输期间 CPU 可执行缓存内代码长时间连续占用请求传输数据产生速率不定如外部传感器、FIFO 读取低仅在 DREQ 有效时占用间歇性占用级联模式需要大量 DMA 通道的复杂系统低由主从 DMA 协同取决于从 DMA 配置四、DMA 控制器结构DMA 控制器是执行 DMA 传输的核心硬件模块其内部结构决定了 DMA 的功能和性能。一个典型的 DMA 控制器主要由寄存器组、地址生成单元、计数器单元、控制逻辑以及总线接口单元构成。1. 核心寄存器组寄存器是 CPU 与 DMA 控制器交互的接口也是 DMA 控制器工作的依据。典型的 DMA 控制器包含以下关键寄存器基地址寄存器Base Address Register存放传输的源起始地址或目标起始地址。在传输开始前由 CPU 写入。当前地址寄存器Current Address Register存放当前正在传输的地址。每次传输完成后该寄存器的值会根据配置自动递增或递减指向下一个要访问的单元。基字节计数寄存器Base Byte Count Register存放本次 DMA 传输需要搬运的总数据量字节数或字数。当前字节计数寄存器Current Byte Count Register存放剩余待传输的数据量。每完成一次传输该计数器自动递减。当减为零时表示传输完成通常会触发中断。控制寄存器Control Register用于配置 DMA 传输的各种参数例如传输方向内存到外设Memory-to-Peripheral, M2P、外设到内存P2M或内存到内存M2M。传输模式单次、块传输、请求传输或循环模式。地址递增/递减设置每次传输后源地址和目标地址是递增、递减还是保持不变。数据宽度字节8位、半字16位或字32位。优先级在多通道 DMA 中设置通道的优先级。中断使能使能传输完成中断、半传输中断或错误中断。状态寄存器Status Register反映 DMA 控制器的当前工作状态例如传输完成标志、错误标志、通道使能状态等。CPU 可通过轮询此寄存器或结合中断来获知传输进度。2. 地址生成与计数器单元这两个单元是 DMA 控制器自动执行传输的“引擎”。地址生成单元根据控制寄存器的配置在每次传输后自动更新当前地址寄存器。例如若配置为“地址递增”则在每次传输后地址寄存器会加上数据宽度对应的字节数如1、2、4。计数器单元负责管理当前字节计数寄存器。每完成一次数据传输计数器减1或根据数据宽度减相应的值。当计数器减为零时产生“传输完成”信号并可能触发中断。3. 控制逻辑与仲裁器控制逻辑解析控制寄存器的配置协调寄存器组、地址生成单元、计数器单元和总线接口单元的工作时序生成内部控制信号。仲裁器Arbiter当多个 DMA 通道同时请求总线时仲裁器根据预设的优先级固定优先级或轮询决定哪个通道获得总线使用权。这是实现多通道 DMA 并发或顺序工作的关键。4. 总线接口单元这是 DMA 控制器与系统总线地址总线、数据总线、控制总线交互的物理接口。它负责在获得总线控制权后驱动地址总线和控制总线发出读写信号。在数据总线上读取源地址的数据或写入数据到目标地址。实现与 CPU 之间的总线请求HOLD和总线应答HLDA握手协议。5. 现代 DMA 控制器的增强特性随着技术的发展现代 MCU/SoC 中的 DMA 控制器往往集成了更高级的功能多通道独立配置一个 DMA 控制器通常包含多个独立的通道每个通道拥有自己的一套寄存器可以同时或分时处理不同外设的传输请求。链接模式Linked List或描述符模式支持将多个传输任务描述符链接成一个链表。DMA 控制器可以自动从一个描述符跳转到下一个实现复杂的、非连续的数据块传输即 Scatter/Gather DMA无需 CPU 反复介入配置。双缓冲区Double Buffer支持允许配置两个目标缓冲区。当 DMA 向其中一个缓冲区写入数据时CPU 可以安全地读取另一个缓冲区已满的数据实现“乒乓”操作避免数据竞争。内存保护MPU集成部分高端控制器集成了内存保护单元可以限制 DMA 访问的地址范围防止错误配置导致的内存覆盖提升系统安全性。理解 DMA 控制器的内部结构有助于我们更深入地掌握其工作原理并在实际编程中正确、高效地配置相关寄存器充分发挥 DMA 的性能优势。五、DMA 在嵌入式系统中的典型应用DMA 技术极大地提升了嵌入式系统的 I/O 效率其应用场景遍布各类外设与内存之间的数据搬运。以下是几个典型的应用实例并附上关键配置思路或代码片段。1. UART 串口通信在串口通信中使用 DMA 可以避免 CPU 为每个字节的收发产生中断尤其适合高速或大数据量传输。应用场景Modbus 通信、GPS 模块数据接收、调试日志输出。配置要点接收配置 DMA 为外设到内存Peripheral-to-Memory模式源地址为 UART 数据寄存器如 USARTx→DR目标地址为内存缓冲区。发送配置 DMA 为内存到外设Memory-to-Peripheral模式源地址为待发送数据缓冲区目标地址为 UART 数据寄存器。通常使用循环模式Circular Mode实现持续接收或单次/普通模式Normal Mode发送固定长度数据。// STM32 HAL 库示例UART1 使用 DMA 接收不定长数据空闲中断 DMA // 关键步骤简述 // 1. 初始化 UART 和 DMA方向 PERIPH_TO_MEMORY循环模式。 // 2. 启动 DMA 接收HAL_UART_Receive_DMA(huart1, rx_buffer, BUFFER_SIZE); // 3. 使能 UART 空闲中断__HAL_UART_ENABLE_IT(huart1, UART_IT_IDLE); // 4. 在空闲中断回调中计算已接收数据长度并处理。 void HAL_UART_IdleCallback(UART_HandleTypeDef *huart) { if (huart-Instance USART1) { // 计算本次接收到的数据长度 uint32_t remaining __HAL_DMA_GET_COUNTER(huart-hdmarx); uint32_t received_len BUFFER_SIZE - remaining; if (received_len 0) { process_rx_data(rx_buffer, received_len); // 处理数据 } // 重新启动 DMA 接收循环模式下缓冲区自动回绕 } }2. ADC 模数转换数据搬运ADC 转换速率往往很高使用 DMA 可以将转换结果自动搬运到指定数组供 CPU 后续处理避免丢失采样点。应用场景多通道传感器采样、音频采集、电源监控。配置要点配置 ADC 为扫描模式Scan Mode和连续转换模式Continuous Conversion Mode。配置 DMA 为外设到内存模式源地址为 ADC 数据寄存器如 ADCx→DR目标地址为数组。使能 DMA 连续请求DMA Continuous Requests确保 ADC 转换完成立即触发 DMA 传输。通常使用循环模式实现持续采样结合双缓冲区Double Buffer或半传输/全传输中断实现“乒乓”操作确保数据处理时 DMA 正在写入另一个缓冲区。// STM32 HAL 库示例ADC1 三通道扫描DMA 循环传输 // 关键配置 // hadc1.Init.ScanConvMode ENABLE; // hadc1.Init.ContinuousConvMode ENABLE; // hadc1.Init.DMAContinuousRequests ENABLE; // hadc1.Init.NbrOfConversion 3; // hdma_adc1.Init.Mode DMA_CIRCULAR; // 循环模式 // 启动HAL_ADC_Start_DMA(hadc1, (uint32_t*)adc_buffer, 3); // 在 DMA 传输完成中断HAL_ADC_ConvCpltCallback中处理 adc_buffer 数据。3. SPI/I2C 总线通信SPI 和 I2C 常用于连接传感器、存储器等外设。在大块数据读写时DMA 能显著提升吞吐量。应用场景读写 SD 卡、Flash 存储器、高分辨率传感器如摄像头、OLED 屏数据更新。配置要点SPI全双工通信时需同时使能 TX 和 RX 的 DMA。注意 SPI 时钟相位和极性的匹配。I2C部分 MCU 的 I2C 外设支持 DMA如 STM32 的 I2C 与 DMA 联动。需注意 I2C 的时钟拉伸Clock Stretching特性。通常使用内存到外设发送和外设到内存接收的组合。// STM32 示例SPI1 使用 DMA 发送数据到外部 Flash // 初始化 SPI 和 DMA方向 MEMORY_TO_PERIPHERAL // 启动传输HAL_SPI_Transmit_DMA(hspi1, tx_buffer, size); // 在传输完成中断HAL_SPI_TxCpltCallback中处理后续逻辑如切换片选。4. 内存到内存Memory-to-Memory拷贝某些 DMA 控制器支持在两个内存区域之间直接搬运数据速度远高于 CPU 的逐字节拷贝。应用场景图像处理中的缓冲区交换、数据块搬移、加密/解密前的数据准备。配置要点配置 DMA 通道为内存到内存模式。设置源地址和目标地址均为内存地址如 SRAM 中的两个数组。数据宽度通常设置为字32位以获得最佳性能。注意源和目标地址的对齐不对齐可能降低性能或需要特殊处理。// STM32 内存到内存 DMA 拷贝示例伪代码 // hdma_memtomem.Init.Direction DMA_MEMORY_TO_MEMORY; // hdma_memtomem.Init.PeriphInc DMA_PINC_ENABLE; // 源地址递增 // hdma_memtomem.Init.MemInc DMA_MINC_ENABLE; // 目标地址递增 // HAL_DMA_Start(hdma_memtomem, (uint32_t)src, (uint32_t)dst, size); // HAL_DMA_PollForTransfer(hdma_memtomem, HAL_DMA_FULL_TRANSFER, 1000); // 或使用中断5. LCD 显示刷新图形界面需要持续向 LCD 控制器发送帧缓冲区数据使用 DMA 可以解放 CPU实现流畅的动画效果。应用场景TFT-LCD 屏驱动、OLED 屏刷新、图形用户界面GUI。配置要点通常通过 FSMCFlexible Static Memory Controller或专用 LCD 控制器接口如 LTDC连接 LCD。配置 DMA 为内存到外设模式源地址为帧缓冲区Frame Buffer目标地址为 LCD 数据寄存器。使用循环模式或配合垂直/水平同步信号触发 DMA 传输实现自动刷新。结合双缓冲区技术避免屏幕撕裂Tearing Effect。6. 音频流处理音频数据的实时采集和播放对时序要求严格DMA 能确保数据流的连续性。应用场景麦克风录音、扬声器播放、音频编解码器Codec数据搬运。配置要点使用 I2S 或 SAIAI 接口连接音频 Codec。配置两个 DMA 流一个用于接收录音一个用于发送播放。使用循环模式和双缓冲区结合半传输中断Half Transfer Complete和全传输中断Transfer Complete实现“乒乓”缓冲确保音频流无中断。// 音频 DMA 双缓冲区“乒乓”操作示意 // 定义两个缓冲区buffer[0] 和 buffer[1] // 启动 DMA 循环传输目标为 I2S 数据寄存器长度为单个缓冲区大小。 // 在 DMA 半传输中断中处理 buffer[0] 的数据已填满前半部分。 // 在 DMA 全传输中断中处理 buffer[1] 的数据已填满后半部分。 // 如此循环实现连续音频流处理。总结与选型建议在选择 DMA 应用模式时需综合考虑外设特性、数据量、实时性要求以及系统总线负载。对于低速、零星数据单次传输模式即可对于高速连续流如音频、视频块传输或循环模式是首选对于数据产生不规律的场景如外部传感器请求传输模式更为合适。合理运用 DMA 可以大幅降低 CPU 负载提升系统整体性能和响应能力。六、面试常见问题1. DMA 相比中断方式传输数据有何优势答中断方式每次传输一个数据单元都需要 CPU 介入进行保存现场、处理数据、恢复现场等操作开销大。DMA 将 CPU 从繁琐的 I/O 操作中解放出来仅在传输开始和结束时参与大大降低了 CPU 占用率提高了数据传输效率尤其适合大批量、高速的数据传输。2. DMA 传输过程会占用系统总线这会影响 CPU 访问内存吗答会。在 DMA 传输期间DMA 控制器作为总线主设备CPU 对内存的访问会被暂时挂起等待或插入等待周期。这称为“周期窃取”。现代系统通常采用总线仲裁和内存控制器来优化例如支持并发访问的存储器、设置 DMA 传输的优先级、利用 CPU 缓存减少总线争用等以最小化对 CPU 性能的影响。3. 如何防止 DMA 传输覆盖关键内存区域答硬件层面一些高级 MCU/MPU 的 DMA 控制器支持内存保护单元MPU可以配置 DMA 可访问的内存地址范围。软件层面驱动程序在配置 DMA 源/目标地址时必须进行严格的边界检查确保地址位于合法的缓冲区范围内。同时操作系统如 Linux会通过 I/O 内存管理单元IOMMU或类似机制为 DMA 分配专用的、受保护的物理内存区域。4. 解释一下“分散/聚集”Scatter/GatherDMA。答这是一种高级 DMA 模式。传统 DMA 要求数据在物理内存中是连续的。“分散/聚集” DMA 允许 DMA 控制器通过一个描述符链表来执行一次传输。每个描述符包含一个内存块的起始地址和长度。DMA 控制器可以自动按顺序从一个不连续的物理内存区域聚集读取数据并传输到外设或者从外设读取数据并写入到多个不连续的内存块分散。这极大地提高了处理碎片化缓冲区的效率常见于网络数据包处理、文件 I/O 等场景。七、总结DMA直接存储器访问作为嵌入式系统性能优化的核心技术其核心价值在于将 CPU 从繁重的数据搬运任务中解放出来实现外设与内存之间的高效、直接数据传输。通过“CPU 配置DMA 执行中断通知”的工作流程DMA 大幅降低了 CPU 开销提升了系统整体吞吐量和实时性。本文系统梳理了 DMA 的关键知识点工作原理基于总线仲裁与周期窃取实现 CPU 与 DMA 控制器的协同工作。传输模式包括适用于低速外设的单次传输、适合高速连续流的块传输、适应不规则数据节奏的请求传输以及用于扩展通道的级联模式。控制器结构由寄存器组、地址生成与计数器单元、控制逻辑与仲裁器、总线接口单元构成现代控制器还集成了多通道、描述符链表、双缓冲区、内存保护等增强特性。典型应用涵盖 UART、ADC、SPI/I2C、内存拷贝、LCD 刷新、音频流处理等场景并提供了关键配置思路与代码片段。面试要点深入探讨了 DMA 相比中断的优势、总线占用影响、内存保护机制以及高级的分散/聚集Scatter/GatherDMA 模式。掌握 DMA 技术不仅要求理解其底层硬件机制更需要结合具体外设和实际场景进行灵活配置与优化。在嵌入式系统设计中合理运用 DMA 能够显著提升 I/O 效率降低 CPU 负载是构建高性能、低功耗、高实时性系统的关键技能。建议读者在理解本文概念的基础上动手实践文中的代码示例并在实际项目中根据数据特性、时序要求和系统资源选择最合适的 DMA 传输模式与配置策略。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价