当前位置: 首页 > news >正文

stm32入门教程--DMA

目录

简介

存储器映像​编辑

ROM区

 RAM区

DMA基本结构


简介

DMA(Direct Memory Access)直接存储器存取

DMA可以提供外设和存储器或存储器和存储器之间的高速数据传输,无需CPU干预,节省了CPIU资源,这里的外设。指的是外设的寄存器,一般是外设的数据寄存器DR,DataRegister,比如ADC的数据寄存器,串口的数据寄存器等等;这里的存储器,指的是运行内存SRAM和程序存储器Flash,是我们春初变量数组和程序代码的地方

12个独立可配置的通道:DMA1(7个通道),DMA2(5个通道)

每个通道都支持软件触发和特定的硬件触发

STM32F103C8T6资源:DMA1(7个通道)

存储器映像

存储器映像,即可以让我们知道stm32中有哪些存储器,这些存储器又被安排在哪些地址上。

表中存储器分成两大类,RAM和ROM,ROM为只读存储器,是一种非易失型、掉电不丢失的存储器;RAM就是随机存储器,是一种易失性,掉电丢失的存储器。

ROM区

第一块是程序存储器Flash,也就是主闪存,它的用途就是存储C语言编译后的程序代码,运行程序,一般也是从主闪存里开始运行的,也就是我们下载程序的位置,这块存储器stm32给分配的地址是0x0800 0000,起始地址,也就是第一个字节的地址0800 0000这个,剩余字节的地址依次增长,每个字节都分配一个独一无二的地址,就像给每个住户编门牌号一样,只有分配了独一无二的门牌号,程序才能精准的访问这个存储器,最终终止地址是多少呢,着取决于它的容量,编到哪里,哪里就是终止地址,这就是主闪存地址的范围,之后如果在软件看到,某个数据的地址是0800开头的,那就可以确定,它是属于主闪存的数据。

第二块是系统存储器,第三块是选项字节,这两块存储器也是ROM的一种,掉电不丢失,实际上他们的存储介质也是Flash,只不过,我们一般说Flash指的是主闪存Flash,而不指这两块区域;他们的地址都是1FFF开头的 ,再往下0x2000就是RAM区了,所以可以看出,这两块存储器的位置是在ROM区的最后面;系统存储器的用途是存储BootLoader,用于串口下载,BootLoader程序是芯片出厂自动写入的,一般也不允许我们修改,而选项字节,是用于存储一些独立于程序代码的配置参数,他的位置是在ROM区的最后面,下载程序可以不刷新选项字节的内容,这样选项字节的配置就可以保持不变,选项字节里,存的主要是Flash的读保护,写保护,还有看门狗等等

 RAM区

首先是云心内存SRAM,分配的地址是0x2000 0000 ,用途是存储运行过程中的临时变量,也就是我们在程序中定义变量、数组、结构体的地方,可以试一下,定义一个变量,再取他的地址,显示出来那这个地址肯定就是2000开头,类比于电脑的话,运行内存就是内存条;

然后RAM区剩下的还有外设寄存器,他的地址是0x4000 0000这块区域用途是存储各个外设的配置参数,也就是我们初始化的各个外设,最终所读写的东西,外设寄存器也是存储器的一种,他的存储介质其实也是SRAM,只不过我们一般,习惯把运行内存叫SRAM,外设寄存器就直接叫寄存器了;

最后是内核外设寄存器,地址是0xE000 0000这片区域,用途是存储内核各个外设的配置参数,内核外设就是NVIC和SysTick,因为内核外设和其他外设不是一个厂家设计的,所以他们的地址也被分开了,内核外设是E000,其他外设是4000,

DMA基本结构

我们来可以从这个图中知道DMA具体是怎么工作的 ,在这个图里, 这两部分就是数据转运的两大站点了,左边是外设寄存器站点,右边是存储器站点,包括Flash和SRAM

在stm32手册中指的存储器,一般特指Flash和SRAM,不包括外设寄存器,外设寄存器一般称作外设,虽然外设也是存储器的一种,但是 stm32中,还是使用了外设和存储器来区分。

stm32中,数据的转运方向,可以从外设到存储器,也可以从存储器到外设,具体向左还是向右,有一个方向的参数,可以进行控制,另外还有一种转运方式,就是存储器到存储器,比如Flash到SRAM或者SRAM到SRAM这两种方式,由于Flash是只读的,所以DMA不可以进行SRAM到Flash,或者Flash到Flash的转运操作,然后我们继续看这两边的参数 ,既然要进行数据转运,就肯定要指定从哪里转到哪里,具体怎么转了,

第一个是起始地址,有外设端的起始地址,和存储器的起始地址。左边的外设地址一个是起始地址,有外设端的起始地址,和存储器端的起始地址,这两个参数决定了数据是从哪里来到哪里去的

之后第二个参数是数据宽度 ,这个参数的作用是,指定一次转运要按多大数据宽度进行 ,它可以选择Byte,半字HalfWord和字Word,字节就是8位,也就是一次转运一个uint8_t,半字是16位,也就是一次转运一个uint16_t这么大的数据,字是32位,也就是一次转运uint32_t这么大 ,比如转运ADC的数据,ADC的结果是uint16_t这么大,所以这个参数就要选择半字,一次转运一个uint16_t,这样才对。

第三个参数的作用是,指定一次转运完成后,下一次转运是不是就要把地址,这就相当于是指针p++,这个个意思,比如ADC扫描模式,用DMA进行数据转运,外设地址是ADC_DR寄存器,寄存器这边显然地址是不用自增的,如果自增,那下一次转运就跑到别的寄存器那里去了;存储器这边就需要自增 ,每转运一个数据后,就往后挪个坑 ,要不然下次再转,就把上次的覆盖掉了。

如果要进行存储器到存储器的数据转运 ,就需要把其中一个存储器的地址,放在外设的这个站点 这样就能进行存储器到存储器的转运了 。


http://www.mrgr.cn/news/60648.html

相关文章:

  • java脚手架系列9-统一权限认证gateway
  • 关于ETL的两种架构(ETL架构和ELT架构)
  • 【Vulnhub靶场】DC-2
  • xlnt加载excel报错:‘localSheetId‘ expected
  • Vue 3 的组件式开发(2)
  • gateway 整合 spring security oauth2
  • Python:现代编程的必备技能
  • 程序设计挑战赛A卷
  • CXL与近内存计算结合,会发生什么?--part2
  • 流量特征分析-常见攻击事件 tomcat
  • python3的基本数据类型:List(列表)创建与索引
  • 存储引用服务(OSS)Minio 环境搭建
  • 审阅员工聊天行为|企业该怎么审阅员工的聊天行为?5个方法分享(实用+收藏)
  • 当代年轻人的“发疯文学”也能涨粉变现!报价¥2w+的笔记,你也能做!
  • 长思维PRM
  • 浅析Android View绘制过程中的Surface
  • 时间序列预测(十五)——有关Python项目框架的实例分析
  • 双十一买什么数码好物比较好?五大闭眼入的数码好物别错过!
  • 浅析Android中View的软件绘制流程
  • 【C++】How the C++ Compiler Works
  • Shiro 会话管理和加密
  • 溪源飨提高免疫力治未病:硒+辅酶Q10强力组合
  • numpy——数学运算
  • C++ vector
  • 西门子S7-200 SMART 多泵轮换功能库案例下载
  • 超子物联网HAL库笔记:准备篇