STM32的 DMA(直接存储器访问) 详解

news2024/10/3 2:18:11

STM32的DMA(Direct Memory Access,直接存储器存取)是一种在单片机中用于高效实现数据传输的技术。它允许外设设备直接访问RAM,不需要CPU的干预,从而释放CPU资源,提高CPU工作效率,本文基于STM32F429、Hal库详细分析DMA的特性与使用。

1.DMA的特性

(1)STM32F429拥有两个DMA控制器(DMA1和DMA2),DMA1 控制器 AHB 外设端口不连接到总线矩阵,因此,只有 DMA2 数据流能够执行存储器到存储器的传输,外设包括片内外设和片外外设。

片内外设:例如GPIO(通用输入输出端口)、USART(通用同步/异步收发器)、I2C(Inter-Integrated Circuit,一种串行通信总线)、SPI(Serial Peripheral Interface,串行外设接口)等。这些外设通过DMA控制器,可以直接与内存(如SRAM、Flash等)进行数据传输。

片外外设:这是指通过外部接口连接到STM32芯片的设备,例如DHT11温度传感器、MQ2烟雾传感器等。这些设备通过相应的接口(如ADC、SPI等)与STM32连接,然后通过DMA控制器进行数据传输,要确保片外外设支持DMA功能才可以用DMA传输数据。

存储器到存储器的传输意味着DMA控制器可以直接从一个内存区域(如RAM的一个数组或缓冲区)读取数据,并将这些数据写入到另一个内存区域(同样是RAM的另一个数组或缓冲区)。这种传输模式在多种应用中都非常有用,比如:

  1. 数据移动:如果你需要将一段数据从一个位置移动到另一个位置,使用DMA可以节省CPU时间,因为CPU不需要参与数据的传输过程。

  2. 数据处理:在图像处理、音频处理或任何需要处理大量数据的应用中,你可能需要将数据从一个缓冲区读取出来,进行一些处理(如滤波、FFT等),然后将结果写回另一个缓冲区。使用DMA可以并行地进行数据的读取和写入,从而加速整个处理过程。

  3. 数据桥接:在某些应用中,你可能需要从一个硬件接口读取数据,然后将其写入到另一个硬件接口。使用DMA可以确保这两个接口之间的数据传输是高效的,不会受到CPU中断或其他任务的影响。

  4. 循环缓冲区:在处理实时数据流时,循环缓冲区是一种常见的解决方案。使用DMA可以自动地将新数据写入循环缓冲区的末尾,并将旧数据从缓冲区的开头移出,从而实现无缝的数据传输和处理。

(2)每个DMA控制器有8个数据流,每个数据流拥有8个通道,每次传输的数据最大为65535(如果数据单位为字,则一次可以传输256KB),每个通道具体是什么数据接口如下图所示:

DMA1通道

DMA2通道

(3)DMA传输具有FIFO(先进先出)模式和直接模式。FIFO用于在源数据传输到目标地址之前临时存放这些数据,每个数据流都有一个独立的 4 字 FIFO,阈值级别可由软件配置为 1/4、1/2、3/4 或满。而直接模式在每个外设请求都立即启动对存储器传输。

(4)数据流与数据流之间的传输优先级通过软件和硬件两个方面决定。软件上,可以通过DMA_SxCR寄存器配置数据流的优先级,总共有四个等级:非常高、高、中、低。硬件上,若两个请求的软件优先级相同时,仲裁器根据DMA通道的编号来决定响应顺序,序号较小的数据流优先级更高,另外,DMA1拥有比DMA2更高的优先级。

(5)DMA支持源地址和目标地址的数据宽度可以不同,如源数据是源源不断的字节数据,而目标地址要求输出字宽度的数据。源传输和目标传输在整个 4 GB 区域(地址在 0x0000 0000 和 0xFFFF FFFF 之间)都可以寻址外设和存储器。

(6)DMA拥有5个中断,分别是:半传输、传输完成、传输错误、FIFO 上溢/下溢、直接模式错误。

2.DMA的使用

下面我们将一些数据通过DMA2的UART1输出出来:

(1)使能DMA时钟

 __HAL_RCC_DMA2_CLK_ENABLE();//DMA2时钟使能    

(2) 初始化DMA通道,配置通道,外设和内存地址,传输数据量等

__HAL_LINKDMA(&UART1_Handler,hdmatx,UART1TxDMA_Handler);    //将DMA与USART1联系起来(发送DMA)
    
    //Tx DMA配置
    UART1TxDMA_Handler.Instance=DMA2_Stream7;                            //数据流选择DMA2控制器的数据流7
    UART1TxDMA_Handler.Init.Channel=DMA_CHANNEL_4;                       //通道选择4
    UART1TxDMA_Handler.Init.Direction=DMA_MEMORY_TO_PERIPH;             //存储器到外设
    UART1TxDMA_Handler.Init.PeriphInc=DMA_PINC_DISABLE;                 //外设非增量模式
    UART1TxDMA_Handler.Init.MemInc=DMA_MINC_ENABLE;                     //存储器增量模式
    UART1TxDMA_Handler.Init.PeriphDataAlignment=DMA_PDATAALIGN_BYTE;    //外设数据长度:8位
    UART1TxDMA_Handler.Init.MemDataAlignment=DMA_MDATAALIGN_BYTE;       //存储器数据长度:8位
    UART1TxDMA_Handler.Init.Mode=DMA_NORMAL;                            //外设普通模式
    UART1TxDMA_Handler.Init.Priority=DMA_PRIORITY_MEDIUM;               //中等优先级
    UART1TxDMA_Handler.Init.FIFOMode=DMA_FIFOMODE_DISABLE;              
    UART1TxDMA_Handler.Init.FIFOThreshold=DMA_FIFO_THRESHOLD_FULL;      
    UART1TxDMA_Handler.Init.MemBurst=DMA_MBURST_SINGLE;                 //存储器突发单次传输
    UART1TxDMA_Handler.Init.PeriphBurst=DMA_PBURST_SINGLE;              //外设突发单次传输
    
    HAL_DMA_DeInit(&UART1TxDMA_Handler);   
    HAL_DMA_Init(&UART1TxDMA_Handler);

(3)开启DMA通道传输

 MYDMA_USART_Transmit(&UART1_Handler,(u8*)SendBuff,SEND_BUF_SIZE); //启动传输    

(4) 查询DMA通道状态,传输结束后关闭串口DMA

while(1){
    if(__HAL_DMA_GET_FLAG(&UART1TxDMA_Handler,DMA_FLAG_TCIF3_7))//等待DMA2_Steam7传输完成
    {
         __HAL_DMA_CLEAR_FLAG(&UART1TxDMA_Handler,DMA_FLAG_TCIF3_7);//清除DMA2_Steam7传输完成标志
         HAL_UART_DMAStop(&UART1_Handler);      //传输完成以后关闭串口DMA
	     break; 
    }
     delayms(10);
}                

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1912397.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

浏览器中js外挂脚本的执行方式

1、开发工具控制台交互执行 网页中按F12打开开发者工具,选择“控制台”,键入js脚本命令回车执行,适用于临时使用脚本逻辑简单的场景,实例如下: // 获取网页元素的文本脚本 var elem document.getElementById("…

7.x86游戏实战-C++实现跨进程读写-跨进程写内存

免责声明:内容仅供学习参考,请合法利用知识,禁止进行违法犯罪活动! 本次游戏没法给 内容参考于:微尘网络安全 上一个内容:6.x86游戏实战-C实现跨进程读写-通过基址读取人物状态标志位 上一个内容通过基…

硬盘分区读不出来的危机与数据拯救指南

在数字时代,硬盘作为我们存储珍贵数据的“保险箱”,其稳定性和可访问性至关重要。然而,当硬盘分区突然读不出来时,这份安全感瞬间化为泡影,让人心急如焚。本文将深入探讨硬盘分区读不出来的原因、提供两种实用的数据恢…

使用ssh服务器管理远程主机

前言:本博客仅作记录学习使用,部分图片出自网络,如有侵犯您的权益,请联系删除 目录 一、配置网卡服务 1、配置网卡参数 2、创建网络会话 3、绑定两块网卡 二、远程控制服务 1、配置sshd服务 2、在Windows连接 3、安全密钥…

云原生必知必会-docker安装

文章目录 一、docker安装二、centos7 安装docker-compose三、修改docker的镜像源四、docker异常处理(没有那个文件或目录)五、配置虚拟机上docker的代理总结 一、docker安装 # 安装上传下载工具 上传命令rz -bey,下载命令sz 文件名 yum -y i…

自定义刷题工具-python实现

背景: 最近想要刷题,虽然目前有很多成熟的软件,网站。但是能够支持自定义的导入题库的非常少,或者是要么让你开会员,而直接百度题库的话,正确答案就摆在你一眼能看见的地方,看的时候总觉得自己…

Xubuntu24.04之设置高性能模式两种方式(二百六十一)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 优质专栏:多媒体系统工程师系列【原创干货持续更新中……】🚀 优质视频课程:AAOS车载系统+AOSP…

ArkUI开发学习随机——B站视频简介页面,美团购买界面

案例一:B站视频简介页面 代码: build() {Column(){Column(){Stack(){Image($r("app.media.genimpact")).width(200).height(125).borderRadius({topLeft:5,topRight:5})Row(){Image($r("app.media.bz_play")).height(24).fillColor…

虚拟机如何选择处理器和内核数量,实现最佳性能

一、基本概念 处理器数量指的是:虚拟的CPU数量。 每个处理器的内核数量指的是:虚拟CPU的内核数。 处理器内核总数处理器数量✖每个处理器的内核数量 此处虚拟机的处理器内核总数对应于真实物理机(或者叫宿主机)的CPU线程数&#x…

Python编程学习笔记(3)--- 操作列表

1、遍历列表 遍历列表可以采用for循环的方法,需要对列表中的每一个元素都执行相同的操作。 具体事实如下: name ["ada","cdb","dbc","bad","jinb"] for Name in name:print(Name)运行结果&#x…

灵活多变的对象创建——工厂方法模式(Python实现)

1. 引言 大家好,又见面了!在上一篇文章中,我们聊了聊简单工厂模式,今天,我们要进一步探讨一种更加灵活的工厂设计模式——工厂方法模式。如果说简单工厂模式是“万能钥匙”,那工厂方法模式就是“变形金刚”…

Windows10 企业版 LTSC 2021发布:一键点击获取!

Windows10企业版 LTSC 2021是微软发布的长达5年技术支持的Win10稳定版本,追求稳定的企业或者个人特别适合安装该系统版本。该版本离线制作而成,安全性高,兼容性出色,适合新老机型安装,力求带给用户更稳定、高效的操作系…

应急响应——勒索病毒

先上搜索引擎上搜 也可以用360来杀 但是都无法解密 可以解密的: linux

db期末复习自用[应试向 附习题]

第一章 数据库系统实现整体数据的结构化,主要特征之一,是db区别于文件系统的本质区别。 数据库系统三个阶段:人工、文件、数据库系统。 数据库管理系统的功能:数据库定义、操纵 、(保护、存储、维护)、数…

Kubernetes 为pod指定DNS

在k8s里面,默认创建pod会给pod默认分配一个默认的dns,这个dns是哪来的呢?可不可以改成其他的dns呢? 先进入到pod里面来,可以看到这里面默认设置的DNS服务器,这个服务器地址为10.96.0.10。这个地址是k8s自动…

Linux基本命令的使用示例

目录 1实现效果:在downloads目录下创建1个空文件夹empty,创建1个空文件lake.txt,输入任意数据保存后退出 2实现效果:搜索包含关键字"泉眼"的行 3实现效果:重命名文件夹empty为full,复制文件cc…

C语言入门基础题:奇偶 ASCII 值判断(C语言版)和ASCII码表,什么是ASCII码,它的特点和应用?

1.题目描述: 任意输入一个字符,判断其 ASCII 是否是奇数,若是,输出 YES ,否则,输出 NO例如,字符 A 的 ASCI 值是 65 ,则输出 YES ,若输入字符 B(ASCII 值是 66)&#xff…

解决:Flink向kafka写数据使用Producer精准一次(EXACTLY_ONCE)异常

在使用flink向kafka写入数据报错:Caused by: org.apache.kafka.common.KafkaException: Unexpected error in InitProducerIdResponse; The transaction timeout is larger than the maximum value allowed by the broker (as configured by transaction.max.timeou…

Linux Mac 安装Higress 平替 Spring Cloud Gateway

Linux Mac 安装Higress 平替 Spring Cloud Gateway Higress是什么?传统网关分类Higress定位下载安装包执行安装命令执行脚本 安装成功打开管理界面使用方法configure.shreset.shstartup.shshutdown.shstatus.shlogs.sh Higress官网 Higress是什么? Higress是基于阿里内部的…

分享一个 EF6 分页查询数据的 IQueryable 扩展方法

前言 不废话&#xff0c;直接上方法。_ IQueryable 扩展方法 方法一 /// <summary> /// 由其它 Reponsitory 提供数据源&#xff0c;分页查询数据 /// </summary> /// <typeparam name"T"></typeparam> /// <typeparam name"S&quo…