玩转STM32-直接存储器DMA(详细-慢工出细活)

文章目录

  • 一、DMA介绍
    • 1.1 DMA简介
    • 1.2 DMA结构
  • 二、DMA相关寄存器(了解)
  • 三、DMA的工作过程(掌握)
  • 四、DMA应用实例
    • 4.1 DMA常用库函数
    • 4.2 实例程序

一、DMA介绍

1.1 DMA简介

DMA用来提供外设与外设之间、外设与存储器之间、存储器与存储器之间的高速数据传输,无需CPU干预,数据可以通过DMA快速传输,节省CPU的资源。
在实现DMA传输时,由DMA控制器直接掌管总线,因此,存在着一个总线控制权转移的问题,即DMA传输前,CPU把总线控制权交给DMA控制器,在结束DMA传输后,DMA控制器立即把总线控制权交回CPU。
一个完整的DMA传输过程包括DMA请求、DMA响应、DMA传输、DMA结束等4个步骤。
(1)DMA请求:CPU对DMA控制器初始化,并向IO接口发出操作命令,IO接口提出DMA请求。
(2)DMA响应:DMA控制器对DMA请求判别优先级及屏蔽,向总线裁决逻辑提出总线请求。当CPU执行完当前总线周期即可释放总线控制权。此时,总线裁决逻辑输出总线应答,表示DMA已经响应,通过DMA控制器通知IO接口开始DMA传输。
(3)DMA传输:DMA控制器获得总线控制权后,CPU即刻挂起或只执行内部操作,由DMA控制器输出读写命令,直接控制RAM与IO接口进行DMA传输。在DMA控制器的控制下,CPU只要提供传送数据的起始位置和数据长度,然后存储器和外设之间直接进行数据传输,CPU不参与传送过程。
(4)DMA结束:当完成规定的成批数据传送后,DMA控制器释放总线控制权,并向IO接口发出结束信号。当IO接口收到结束信号后,一方面停止IO设备的工作,另一方面向CPU提出中断请求,CPU响应中断,执行一段检查本次DMA传输操作正确性的代码。最后,带着本次操作结果及状态继续执行原来程序。

1.2 DMA结构

STM32最多拥有两个DMA控制器,DMA1控制器拥有7个独立的可配置通道,DMA2有5个独立的可配置通道,每个通道用来管理来自一个或多个外设对存储器访问的请求。
DMA是AHB总线上的设备,它有2个AHB端口:一个是从端口,用于配置DMA;一个是主端口,用于设备间数据传输。两个AHB/APB桥在AHB和两个APB总线间提供同步连接。APB1操作速度限于36MHz,APB2操作速度限于72MHz。STM32F103的DMA结构图如下所示:
来自STM32F103手册
STM32的Cortex-M3核心和DMA控制器通过总线矩阵连接到Flash控制总线、SRAM总线和AHB总线,进而通过AHB总线连接到APB总线服务外设。
总线矩阵有两个主要特征:循环优先调度、多层结构和总线挪用。

  1. 循环优先调度
    NVIC和Cortex-M3处理器实现了高性能低延时中断调度。所有的Cortex-M3指令即可以在单周期内执行,也可以在总线周期上被中断。循环优先级调度能够确保CPU在必要时每两个总线周期就去访问其他总线。
  2. 多层结构和总线挪用
    多层结构允许两个主设备并行执行数据传输。使用总线挪用存取机制,CPU访问和DMA通过APB总线存取外设可以并行工作。DMA总线挪用机制使得总线利用效率更高。

DMA功能的是通过操作两类寄存器实现的:
一类是具有DMA功能的相关外设寄存器,主要来自外设开启DMA功能,例如在通用定时器中的DMA/中断使能寄存器、DMA控制寄存器和连续式的DMA地址寄存器。
另一类是DMA相关寄存器,用来设置DMA的具体工作方式,DMA相关寄存器包括DMA中断状态寄存器(DMA_ISR)、DMA中断标志清除寄存器(DMA_IFCR)等。

二、DMA相关寄存器(了解)

  1. DMA中断状态寄存器——DMA_ISR
    该寄存器保存着DMA中断的状态。
    在这里插入图片描述
    在这里插入图片描述

  2. DMA中断标志清除寄存器——DMA_IFCR
    该寄存器用来清除DMA中断标志。
    在这里插入图片描述

  3. DMA通道x配置寄存器——DMA_CCRx
    该寄存器用来配置DMA工作模式。
    在这里插入图片描述
    在这里插入图片描述

  4. DMA通道x传输数量寄存器——DMA_CNDTRx
    该寄存器用来配置DMA传输数据量。
    在这里插入图片描述

  5. DMA通道x外设地址寄存器——DMA_CPARx
    该寄存器用来配置DMA通道外设地址。
    在这里插入图片描述

  6. DMA通道x存储器地址寄存器——DMA_CMARx
    该寄存器用来配置DMA通道存储器地址。
    在这里插入图片描述

三、DMA的工作过程(掌握)

1. DMA传送
当发生一个事件后,外设发送一个时间请求信号到DMA控制器,DMA控制器根据通道的优先权来处理请求。当DMA控制器开始访问外设时,DMA控制器首先向外设发送一个应答信号;外设得到应答信号后立即撤销请求;外设撤销请求后,DMA控制器同时撤销应答信号。如果载磁发生请求,外设则可以启动下次传送。每个DMA传送由以下3个操作组成;
(1) 从外设数据寄存器或由DMA_CMARx寄存器指定地址的存储单元执行加载操作。(取数据)
(2)存储数据到外设数据寄存器或存数据到DMA_CMARx寄存器指定地址的存储单元。(存储)
(3)执行依次DMA_CNDTRx寄存器的递减操作,该寄存器内容为完成的传输内容数量。
2. 仲裁器
仲裁器根据通道请求的优先级来启动外设/存储器的访问。优先权管理分2个阶段:
(1)软件:每个通道的优先权可以在DMA_CCRx寄存器中设置,有4个等级: 最高优先级、高优先级 、中等优先级 、低优先级。
(2)硬件:如果2个请求有相同的软件优先级,则较低编号的通道比较高编号的通道有较高的优先权。举个例子,通道2优先于通道4。
3. DMA通道
每个通道都可以在有固定地址的外设寄存器和存储器地址之间执行DMA传输。DMA传输的数据量是可编程的,最大达到65535。包含要传输的数据项数量的寄存器,在每次传输后递减。
(1)传输的数据量
外设和存储器的传输数据量可以通过DMA_CCRx寄存器中的PSIZE和MSIZE位编程。
(2)指针自增
通过设置DMA_CCRx寄存器中的PINC和MINC标志位,外设和存储器的指针在每次传输后可以有选择地完成自动增量。当设置为增量模式时,下一个要传输的地址将是前一个地址加上增量值,增量值取决与所选的数据宽度为1、2或4。第一个传输的地址是存放在DMA_CPARx /DMA_CMARx寄存器中地址。
(3)通道配置过程
下面是配置DMA通道x的过程(x代表通道号):
①在DMA_CPARx寄存器中设置外设寄存器的地址。发生外设数据传输请求时,这个地址将是数据传输的源或目标。
② 在DMA_CMARx寄存器中设置数据存储器的地址。发生外设数据传输请求时,传输的数据将从这个地址读出或写入这个地址。
③ 在DMA_CNDTRx寄存器中设置要传输的数据量。在每个数据传输后,这个数值递减。
④ 在DMA_CCRx寄存器的PL[1:0]位中设置通道的优先级。
⑤ 在DMA_CCRx寄存器中设置数据传输的方向、循环模式、外设和存储器的增量模式、外设和存储器的数据宽度、传输一半产生中断或传输完成产生中断。
⑥ 设置DMA_CCRx寄存器的ENABLE位,启动该通道。
⑦一旦启动了DMA通道,它既可响应连到该通道上的外设的DMA请求。
⑧当传输一半的数据后,半传输标志(HTIF)被置1,当设置了允许半传输中断位(HTIE)时,将产生一个中断请求。在数据传输结束后,传输完成标志(TCIF)被置1,当设置了允许传输完成中断位(TCIE)时,将产生一个中断请求。
(4)循环模式
循环模式用于处理循环缓冲区和连续的数据传输(如ADC的扫描模式)。在DMA_CCRx寄存器中的CIRC位用于开启这一功能。当启动了循环模式,数据传输的数目变为0时,将会自动地被恢复成配置通道时设置的初值,DMA操作将会继续进行。
(5)存储器到存储器模式
DMA通道的操作可以在没有外设请求的情况下进行,这种操作就是存储器到存储器模式。 当设置了DMA_CCRx寄存器中的MEM2MEM位之后,在软件设置了DMA_CCRx寄存器中的EN位启动DMA通道时,DMA传输将马上开始。当DMA_CNDTRx寄存器变为0时,DMA传输结束。存储器到存储器模式不能与循环模式同时使用。
4. 错误管理
读写一个保留的地址区域,将会产生DMA传输错误。当在DMA读写操作时发生DMA传输错误时,硬件会自动地清除发生错误的通道所对应的通道配置寄存器(DMA_CCRx)的EN位,该通道操作被停止。此时,在DMA_IFR寄存器中对应该通道的传输错误中断标志位(TEIF)将被置位,如果在DMA_CCRx寄存器中设置了传输错误中断允许位,则将产生中断。
5. DMA请求映射
从外设(TIMx[x=1、2、3、4]、ADC1、SPI1、SPI/I2S2、I2Cx[x=1、2]和USARTx[x=1、2、3])产生的7个请求,通过逻辑或输入到DMA1控制器,这意味着同时只能有一个请求有效。
在这里插入图片描述

四、DMA应用实例

4.1 DMA常用库函数

函数名称功能
DMA_DeInit将DMA的通道x寄存器重设为缺省值
DMA_Init根据DMA_InitStruct中指定的参数初始化DMA通道x寄存器
DMA_StructInit把DMA_InitStruct中的每一个参数按缺省值填入
DMA_Cmd使能或使能指定的通道x
DMA_ITConfig使能或是能指定的通道x中断
DMA_GetCurrDataCounte返回当前DMA通道x剩余的待传输数据数目
DMA_GetFlagStatus检查指定的DMA通道x标志位设置与否
DMA_ClearFlag清除DMA通道x待处理标志位
DMA_GetITStatus检查指定的DMA通道x中断发生与否
DMA_ClearITPendingBit清除DMA通道x中断待处理标志位

4.2 实例程序

  1. 实例介绍: 利用DMA将Flash中的32位数据缓冲区的内容传送到RAM中所定义的缓冲区内。传输完成后产生传输完成中断,最后将源缓冲区中数据与目的缓冲区中数据对比来检测所有数据是否传输正确。
  2. 实例
    (1)DMA初始化
void DMADriver_Init(void)
{DMA_InitTypeDef DMA_InitStructure;RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);// 外设基地址, 源地址DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)SRC_Const_Buffer;// RAM基地址, 目的地址DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)DST_Buffer;// 传输方向,外设为源地址DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;// 缓冲区大小, 0~65536DMA_InitStructure.DMA_BufferSize = BufferSize;// 外设地址自增1DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Enable;// RAM地址自增1DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;// 外设数据宽度DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;  // 字,4个字节// RAM数据宽度DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;// 传输模式 一次传送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_ITConfig(DMA1_Channel1,DMA_IT_TC,ENABLE);// 开始传输前数据量CurrDataCounterBegin = DMA_GetCurrDataCounter(DMA1_Channel1);// 开启DMADMA_Cmd(DMA1_Channel1,ENABLE);
}

(2)中断处理函数

void DMA1_Channel1_IRQHandler(void)
{// 检测DMA1通道1传输完成中断if(DMA_GetITStatus(DMA1_IT_TC1)){// 传输完成后得到当前计数CurrDataCounterEnd = DMA_GetCurrDataCounter(DMA1_Channel1);// 清除标志位DMA_ClearITPendingBit(DMA1_IT_TC1);}
}

(3)串口初始化在前几章有写过,这里就不介绍了

// 定义存储大小
#define BufferSize   32uint32_t CurrDataCounterBegin = 0;
uint32_t CurrDataCounterEnd = 0x01;
const uint32_t SRC_Const_Buffer[BufferSize] = {
0x01022231,0x19234012,0x02348192,0x19384910,
0x01022231,0x19234012,0x02348192,0x19384910,
0x01022231,0x19234012,0x02348192,0x19384910,
0x01022231,0x19234012,0x02348192,0x19384910,
0x01022231,0x19234012,0x02348192,0x19384910,
0x01022231,0x19234012,0x02348192,0x19384910,
0x01022231,0x19234012,0x02348192,0x19384910,
0x01022231,0x19234012,0x02348192,0x19384910};
uint32_t DST_Buffer[BufferSize];void main()
{UsartDriver_Init();DMADriver_Init();Delay_ms(10);while(CurrDataCounterEnd  != 0);printf("Complete transfer!\r\n")}

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

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

相关文章

有免费通配符证书吗?哪里可以申请?

市面上的免费SSL证书大多数为单域名证书,如果您的主域名拥有众多子域名,逐一申请单域名SSL证书不太现实,下面为介绍一款永久免费使用的通配符SSL证书申请流程 1 选择免费通配符证书提供商 免费通配符证书申请点击这里直接获取https://www.…

前端渲染页面的原理

之前一直不愿意写一篇关于原理的,因为说起来实在是太繁杂,要写得细,码字梳理,计算下来起码都要差不多三周。以前一直躲避这个事情,现在反正有时间,为了不荒废自己,那就从头捋一遍。也方便自己后…

数据分析项目有哪些实施流程?揭示从数据准备到解决方案全过程

在当今数据驱动的商业环境中,数据分析项目的成功实施对于企业洞察市场趋势、优化产品服务、提升用户体验以及增强竞争力具有至关重要的作用。特别是对于直播类应用软件这样的快速增长领域,如何通过数据分析来扩大付费用户基础、提高用户留存率&#xff0…

音视频开发10 FFmpeg 内存模型-AVPacket, AVFrame

从现有的 Packet 拷贝一个新 Packet 的时候,有两种情况: • ①两个 Packet 的 buf 引用的是 同一数据缓存空间 ,这时 候要注意数据缓存空间的释放问题; • ②两个 Packet 的 buf 引用不同的数据缓存空间 ,每个 Pac…

D2Admin:企业中后台产品前端集成方案的探索与实践

D2Admin:企业中后台产品前端集成方案的探索与实践 摘要:随着企业信息化建设的不断深入,中后台管理系统的前端技术选型与集成方案成为了关键。D2Admin作为一款完全开源免费的前端集成方案,通过采用最新的前端技术栈,提…

惠海半导体 30V-60V-100V-150VMOS管 打火机、加湿器NMOS管 高耐压

MOS管的工作原理 MOS管,即金属-氧化物-半导体场效应晶体管,是一种重要的电子元件,在电路中起着关键的作用。其工作原理主要基于半导体材料的特性以及电场对电荷的控制。 首先,MOS管的基本结构包括源极、栅极和漏极。其中&#xf…

我国赤泥年产量庞大 政策引导下赤泥绿色利用率将不断提升

我国赤泥年产量庞大 政策引导下赤泥绿色利用率将不断提升 赤泥是指从铝土矿中提炼氧化铝后产生的强碱性工业固体废渣,由于含大量氧化铁,表面呈现红色,而得名赤泥。   赤泥通常包含氧化铝、氧化铁、二氧化硅、氧化钙、碱金属及其他微量元素&…

排序专题(常见8种)【思路解析和代码实现】【2w字长文】

排序专题(常见8种) 1.排序的概念及其运用 1.1排序的概念 排序:所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作。 稳定性:假定在待排序的记录序列中…

【设计模式】JAVA Design Patterns——Dependency Injection(依赖注入模式)

🔍目的 依赖注入是一种软件设计模式,其中一个或多个依赖项(或服务)被注入或通过引用传递到一个依赖对象(或客户端)中,并成为客户端状态的一部分。该模式将客户的依赖关系的创建与其自身的行为分…

ABAP WRITE换行输出

不换行: write hello world!. write 春天马上就到了!. 换行: write hello world!. write /春天马上就到了!. 换行的第二种: write: hello world! ,/,春天马上就到了!.

基于STM32实现智能水下机器人控制系统

目录 引言环境准备智能水下机器人控制系统基础代码示例:实现智能水下机器人控制系统 电机控制深度传感器数据读取IMU传感器数据读取用户界面与显示应用场景:水下探测与环境监测问题解决方案与优化收尾与总结 1. 引言 本教程将详细介绍如何在STM32嵌入式…

Comfyui导出图片的命名技巧,日期文件夹

种子序号命名:%KSampler.seed% 图片宽高序号命名:%Empty Latent Image.width%x%Empty Latent Image.height% 年月日:%date:yyyy-MM-dd% 时分秒:%date:hhmmss% 年月日种子序号:%date:yyyy-MM-dd%/%KSampler.seed%

长安杯2021年wp

背景: 2021年4月25日,上午8点左右,警方接到被害人金某报案,声称自己被敲诈数万元;经询问,昨日金某被嫌疑人诱导裸聊,下载了某“裸聊”软件,导致自己的通讯录和裸聊视频被嫌疑人获取…

免费时代到来!价格战带领AI大模型走出商业化困局?

电子发烧友网报道(文/梁浩斌)大模型厂商彻底疯狂!电商618大促刚刚开始,大模型厂商就开始轮番疯狂降价。每千Tokens的价格,从过去几分钱,再下降一个数量级至几厘,甚至还有直接开放大模型全面免费…

设计和输出一个钻石图形

只能对字符数组的元素赋值,而不能用赋值语句对整个数组赋值。如 char c[5]; c {C,h,P,n,a}; //错误,不能对整个数组一次赋值 c[0]C; c[1]h; c[2]i; c[3]n; c[4]a; //正确,分别对数组元素…

重生奇迹mu卡智力的方法

1、准备3个号A打手,B智力MM,C随意。 2、使用C匹配组队,但是不能选择自动进入队伍。 3、用A申请C的队伍,但是C不做通过处理。 4、用A组B,用快捷键D的方式。 5、所谓的卡智力就是智力MM可以给打手加属性加血,但是并不在一个队伍里享受经验,适用于MM不是…

SpringCloud:Nacos配置管理

程序员老茶 🙈作者简介:练习时长两年半的Java up主 🙉个人主页:程序员老茶 🙊 P   S : 点赞是免费的,却可以让写博客的作者开心好久好久😎 📚系列专栏:Java全栈&#…

【跟着例子学MySQL】SQL进阶 – 视图、事务和变量

文章目录 前言回顾视图事务用户变量未完待续 前言 举例子,是最简单有效的学习方法。本系列文章以一个贯穿始终的场景,结合多个实例讲解MySQL的基本用法。 ❔ 为什么要写这个系列? 模仿是最好的老师,实践是检验成果的方法。本系列…

【EI会议|检索稳定】2024年通讯工程与云计算国际会议(CECC 2024)

2024年通讯工程与云计算国际会议(CECC 2024) 2024 International Conference on Communication Engineering and Cloud Computing 【重要信息】 大会地点:武汉 大会官网:http://www.iaccecc.com 投稿邮箱:iacceccsub-…

1794 jsp蛋糕店管理系统Myeclipse开发mysql数据库web结构java编程计算机网页项目

一、源码特点 jsp 蛋糕店管理系统 是一套完善的web设计系统,对理解JSP java编程开发语言有帮助采用了java设计,系统具有完整的源代码和数据库,系统采用web模式,系统主要采用B/S模式开发。开发环境为TOMCAT7.0,Myeclipse8.5开发&…