首页 > 其他分享 >嵌入式杂谈——什么是DMA?有什么用?

嵌入式杂谈——什么是DMA?有什么用?

时间:2025-01-17 23:58:10浏览次数:3  
标签:DMA UART 杂谈 rx 嵌入式 传输 内存 外设

什么是DMA?——直接内存访问技术详解

在嵌入式系统和计算机体系结构中,DMA(Direct Memory Access,直接内存访问) 是一种重要的数据传输技术。它允许外设(如UART、SPI、ADC等)直接与内存进行数据交换,而无需CPU的干预。DMA技术可以显著提高系统的效率和性能,尤其是在需要高速数据传输的场景中。本文将详细解释DMA的工作原理、优势、应用场景以及如何使用DMA。

2. DMA的工作原理

2.1 DMA的基本组成

  • DMA控制器:负责管理数据传输的硬件模块。

  • 源地址:数据来源的地址(如外设的数据寄存器)。

  • 目标地址:数据存储的目标地址(如内存中的缓冲区)。

  • 传输长度:需要传输的数据量。

  • 传输模式:DMA支持多种传输模式,如单次传输、循环传输等。

2.2 DMA的工作流程

  1. 初始化

    • CPU配置DMA控制器,设置源地址、目标地址、传输长度和传输模式。

    • 启动DMA传输。

  2. 数据传输

    • DMA控制器从源地址读取数据,并将数据写入目标地址。

    • 每次传输完成后,DMA控制器更新地址指针和传输计数器。

  3. 传输完成

    • 当传输计数器归零时,DMA控制器发出传输完成信号(通常是一个中断)。

    • CPU可以处理传输完成后的任务(如数据处理或下一次传输的初始化)。

3. DMA的优势

3.1 提高系统性能

  • 减少CPU占用:CPU无需参与数据传输,可以专注于其他任务。

  • 提高数据传输速度:DMA控制器通常比CPU更快地完成数据搬运。

3.2 降低功耗

  • 由于CPU无需频繁参与数据传输,系统的功耗可以显著降低。

3.3 支持大数据量传输

  • DMA非常适合处理大数据量的传输任务,如音频、视频数据的传输。


4. DMA的应用场景

4.1 外设与内存的数据交换

  • UART通信:DMA可以用于接收和发送大量串口数据。

  • SPI/I2C通信:DMA可以加速传感器数据的读取和写入。

  • ADC采样:DMA可以将ADC的采样数据直接存储到内存中。

4.2 内存到内存的数据传输

  • DMA可以用于在内存的不同区域之间快速复制数据,如图像处理中的缓冲区拷贝。

4.3 高速数据传输

  • 音频处理:DMA可以用于音频数据的实时传输和处理。

  • 视频处理:DMA可以加速视频帧的传输和显示。


5. DMA的配置与使用(以STM32为例)

5.1 DMA的配置步骤

  1. 选择DMA通道:根据外设选择对应的DMA通道。

  2. 设置源地址和目标地址

    • 源地址:外设的数据寄存器地址。

    • 目标地址:内存中的缓冲区地址。

  3. 配置传输方向

    • 外设到内存(如UART接收)。

    • 内存到外设(如UART发送)。

    • 内存到内存(数据拷贝)。

  4. 设置传输长度:指定需要传输的数据量。

  5. 选择传输模式

    • 单次传输:传输完成后停止。

    • 循环传输:传输完成后自动重新开始。

  6. 启用DMA中断:配置传输完成中断,以便在传输完成后通知CPU。

5.2 示例代码(STM32 HAL库)

以下是一个使用DMA进行UART接收的示例代码:

// 定义接收缓冲区
uint8_t rx_buffer[100];

// 配置DMA
void DMA_UART_Config(void) {
    // 使能DMA时钟
    __HAL_RCC_DMA1_CLK_ENABLE();

    // 配置DMA
    hdma_usart_rx.Instance = DMA1_Channel5; // DMA通道
    hdma_usart_rx.Init.Direction = DMA_PERIPH_TO_MEMORY; // 传输方向:外设到内存
    hdma_usart_rx.Init.PeriphInc = DMA_PINC_DISABLE; // 外设地址不递增
    hdma_usart_rx.Init.MemInc = DMA_MINC_ENABLE; // 内存地址递增
    hdma_usart_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; // 外设数据对齐:字节
    hdma_usart_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; // 内存数据对齐:字节
    hdma_usart_rx.Init.Mode = DMA_NORMAL; // 传输模式:单次传输
    hdma_usart_rx.Init.Priority = DMA_PRIORITY_HIGH; // 优先级:高
    HAL_DMA_Init(&hdma_usart_rx);

    // 关联DMA到UART
    __HAL_LINKDMA(&huart1, hdmarx, hdma_usart_rx);

    // 启动DMA传输
    HAL_UART_Receive_DMA(&huart1, rx_buffer, 100);
}

// DMA传输完成中断回调函数
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
    if (huart->Instance == USART1) {
        // 处理接收到的数据
    }
}

6. DMA的局限性

  1. 硬件资源有限

    • DMA通道的数量有限,可能无法满足所有外设的需求。

  2. 配置复杂

    • DMA的配置相对复杂,需要仔细设置源地址、目标地址、传输长度等参数。

  3. 调试难度较高

    • 由于DMA是硬件实现的,调试时可能难以追踪数据传输的过程。

标签:DMA,UART,杂谈,rx,嵌入式,传输,内存,外设
From: https://blog.csdn.net/JK03820/article/details/145216869

相关文章

  • 华为2024嵌入式研发面试题
    01你认为最好的排序算法是什么?在实际的编程中,最好的排序算法要根据实际需求和数据规模来选择,因为每种排序算法都有其优势和劣势。以下是一些常见排序算法及其优缺点:冒泡排序冒泡排序是一种简单直观的排序算法,它的时间复杂度是O(n^2)。虽然它的时间复杂度比较高,但它的实现方......
  • 【嵌入式人生】1.2025应届生四处碰壁的思考:若回到大一,我将这么干
    803.001 若笔者回到大一,将会按照如下方式过,根据一路以来找工作最后成功上岸的经验简单的总结为以下几点(以就业为标准,以走嵌入式道路为标准),想到还会继续更新  1.门门都要学好,争做好学生?大学学习的知识不足以让你达到社会上的就业标准,若不选择保研,与其花100%的精力让自......
  • 三层24千兆+4万兆光电可选网管型嵌入式交换机核心模块SW-24G4F-301EM
    先来解读一下标题,这是一款交换机核心模块,也就是交换机的核心部分模块化了;方便为了嵌入式集成;是管理型(也就是核心模块带了软件,对应底板结合自身板框,根据参考设计随性设计),还是三层管理;可以最多支持28个通信口,分别是24千兆+4万兆,接口的方式可以电口,也可以光口。可广泛应用于煤......
  • 嵌入式教学楼火灾报警系统设计与实现
    随着现代社会对安全问题的日益关注,火灾防控已成为公共安全系统中的一个重要环节。在教学楼、商场、医院等场所,火灾隐患一旦发生,若未能及时发现并有效应对,可能会造成极其严重的后果。因此,一个高效、智能的火灾报警系统至关重要。本文将详细介绍如何设计和实现一个基于嵌入式......
  • 嵌入式_相关英文(不定时更新...)
    一、在嵌入时准备阶段、linux基础时接触的专业英文(1)知识点中的单词Crack:破解,裂开virtualmachine:虚拟机terminal:终端,站台Permissiondenied:权限不允许password:密码remove:删除regular:普通的necessary:必须的catch:抓取omitting:省略,遗漏insert:插入wave:保存quit:退......
  • 嵌入式杂谈——(问题解决三:嵌入式中的数据类型)
    列举1. 标准固定宽度整数类型这些类型定义在 <stdint.h> 头文件中,用于明确指定数据的位数,适合嵌入式系统中需要精确控制数据大小的场景。类型位数范围(有符号)范围(无符号)说明int8_t8-128到127-8位有符号整数uint8_t8-0到2558位无符号整数int16_t16-32,768到32,767-......
  • 自学嵌入式
    #学习嵌入式第二天##C语言的基本数据类型C语言的基本数据类型,基本的数据类型有整型、浮点型(单精度、双精度)、字符型。整型数据有int、short、long、longlong四种类型。数据又分为有符号数和无符号数,二者数据表示的范围不同。int型:占4个字节;对于有符号数(signed)数据表示......
  • 嵌入式学习
    #C语言基础#今天学习了输入输出函数(printf、scanf)、流程控制——选择结构(if语句)#输入输出函数#printf()函数printf()函数为格式化输入输出函数,其函数原型为:intprintf(constchar*format,...);调用方法为:printf("格式化控制字符串",输出参数列表)。格式化字符串中分为普通字......
  • Open FPV VTX开源之嵌入式OSD配置
    OpenFPVVTX开源之嵌入式OSD配置1.源由2.安装3.配置步骤一:备份`/etc/telemetry.conf`步骤二:修改`/etc/telemetry.conf`步骤三:配置时区步骤四:重启摄像头4.实测5.参考资料1.源由穿越机模拟图传延迟通常在10ms左右。最近为什么OpenIPC这么热,主要原因就是该项目......
  • 嵌入式中fputc重定向
    #include"stm32f4xx_hal.h"#include<stdio.h>//假设存在两个输出目标externUART_HandleTypeDefhuart1;//UART1externUART_HandleTypeDefhuart2;//UART2//自定义fputc,区分不同的FILE*流intfputc(intch,FILE*f){  if(f==stdout){   ......