DMA数据转运

DMA Direct Memory Access )直接存储器存取
DMA 可以提供外设和存储器或者存储器和存储器之间的高速数据传输,无须 CPU 干预,节省了 CPU 的资源
12 个独立可配置的通道: DMA1 7 个通道), DMA2 5 个通道)
每个通道都支持软件触发和特定的硬件触发
STM32F103C8T6 DMA 资源: DMA1 7 个通道)

协助CPU,完成数据转运的工作

DMA可以直接访问STM32的内部存储器,包括运行内存SRAM、程序存储器Flash和寄存器等

外设的数据寄存器(DR,Data Register)

存储器指的是运行内存SRAM和程序存储器Flash,是我们存储变量数组和程序代码的地方

存储器到存储器之间需要软件触发

外设到存储器之间的数据转运需要硬件触发(需要一定时机)

ADC每个通道AD转换完成后,硬件触发一次DMA,之后DMA再转运,触发一次,转运一次

每个不同的DMA通道,它的硬件触发源是不一样的,你要使用某个外设的硬件触发源,就得使用它连接的那个通道,而不能任意选择通道

计算机系统的五大组成部分是运算器、控制器、存储器、输入设备和输出设备,运算器和控制器合在一起叫做CPU

ROM是只读存储器,是一种非易失性、掉电不丢失的存储器;RAM是随机存储器,是一种易失性、掉电丢失的存储器

每个字节都有独一无二的地址,实际上系统存储器和选项字节本质都是Flash,只不过我们一般说Flash指的是主闪存Flash,而不指这两块区域

BootLoader程序是芯片出厂自动写入的,一般也不允许我们修改

下载程序可以不刷新选项字节的内容,这样选项字节的配置就可以保持不变,选项字节里存的主要是Flash的读保护、写保护,还有看门狗等等的配置

内核外设就是NVIC和SysTick,因为内核外设和其他外设不是一个厂家设计的,所以他们的地址也是被分开了

程序从0开始运行,所以需要把我们想要执行的程序映射到0地址上,如果映射到Flash区,就是从Flash执行,如果映射到系统存储器区,就是从系统存储器运行BootLoader,如果映射到SRAM,就是从SRAM启动,怎么选择,由BOOT0和BOOT1两个引脚来决定

Cortex-M3内核包含了CPU和内核外设等,剩下所有都可以看成是存储器

Flash是主闪存,SRAM是运行内存,各个外设可以看成是寄存器,也是一种SRAM存储器

为了高效有条理地访问存储器,这里设计了一个总线矩阵,总线矩阵的左端是主动单元,也就是拥有寄存器的访问权;右边是被动单元,他们的存储器只能被左边的主动单元读写。主动单元这里,内核由DCode和系统总线,可以访问右边的存储器,其中DCode总线式专门访问Flash的,系统总线是访问其他东西的,另外,由于DMA要转运数据,所以DMA也必须要有访问的主动权。那主动单元,除了内核CPU,剩下的就是DMA总线了。

以太网外设自己私有DMA

仲裁器的存在是因为虽然多个通道可以独立转运数据,但是最终DMA总线只有1条,所以所有的通道都只能分时复用这一条DMA总线,如果产生了冲突,那就会由仲裁器,根据通道的优先级决定谁先用、谁后用。另外在总线矩阵也有个仲裁器,如果DMA和CPU都要访问同一个目标,那么DMA就会暂停CPU的访问,以防止冲突。不过总线仲裁器,仍然会保证CPU得到一半的总线带宽,使CPU也能正常的工作。

AHB从设备是DMA自身的寄存器,DMA作为外设,自己也会有相应的配置寄存器,这里连接在了总线右边的AHB总线上,所以DMA,即是总线矩阵的主动单元,可以读写各种存储器,也是AHB总线上的被动单元。CPU通过这条线路可以对DMA进行配置。

DMA请求,请求就是触发的意思,这条线路右边的触发源是各个外设,所以这个DMA请求就是DMA的硬件触发源

转运过程中,每转运一次,计数器的数就会减1,当传输计数器减到0之后,DMA就不会再进行数据转运了。另外,它减到0之后,之前自增的地址,也会恢复到起始地址的位置,以方便之后DMA开始新一轮的转运。自动重装器的作用就是,传输计数器减到0之后,是否要自动恢复到最初的值。 如果不重装就是单次模式,如果重装就是循环模式。

M2M:Memory to Memory,存储器到存储器

软件触发的执行逻辑是,以最快的速度,连续不断地触发DMA,争取早日把传输计数器清零,完成这一轮的转换,可以理解为连续触发。这个软件触发和循环模式,不能同时使用,因为软件触发就是想把传输计数器清零,循环模式是清零后自动重装,如果同时用的话DMA就停不下来了。软件触发一般适用于存储器到存储器的转运。硬件触发源可以选择ADC、串口、定时器等等,使用硬件触发的转运,一般都是与外设有关的转运。

开关控制  DMA_Cmd使能DMA,传输计数器必须大于0,必须要有触发信号。传输计数器为0之后,需要Disable,然后关闭DMA,再为传输计数器写入一个大于0的数,再DMA_Cmd,给Enable开启DMA。注意:写传输计数器时,必须要先关闭DMA,再进行,不能在DMA开启时,写传输计数器,这是手册的规定。

EN位是开关控制,EN=0时数据选择器不工作,EN=1时数据选择器工作,EN并不是数据选择器的控制位,而是决定这个数据选择器要不要工作 ;当M2M位=1时,选择软件触发

比如你要使用ADC1,那会有个库函数叫ADC_DMACmd,必须使用这个库函数开启ADC1的这一路输出,它才有效

默认优先级是通道号越小,优先级越高,当然也可以在程序中配置优先级

数据宽度与对齐(数据宽度不一样怎么处理):

 

 位段区相当于是位寻址,它把外设寄存器和SRAM中所有的位都分配了地址,你操作这个新的地址,就相当于操作其中的一位,因为32位的地址有99%是空的,所以地址空间很充足,即使把每一位都单独编码,那也是毫无压力,所以就存在了这样一个位段,用于单独操作寄存器或SRAM的某一位。位段区是另找了一个地方,开辟了一段地址区域,其中SRAM位段区是2200开头的区域,外设寄存器的位段是4200开头的区域。

当读写一个保留的地址,将会产生DMA传输错误。

有传输过半、传输完成和传输错误的中断

--------------------------------------------------------------------------------------------

第一步,RCC开启DMA的时钟

第二步,直接调用DMA_Init,初始化参数,包括外设和存储器站点的起始地址、数据宽度、地址是否自增、方向、传输计数器、是否需要自动重装、选择触发源还有通道优先级。然后DMA_Cmd就使能DMA了。如果是硬件触发,不要忘了在对应的外设调用XXX_DMACmd,开启触发信号的输出。如果需要DMA的中断,那就调用DMA_ITConfig,开启中断输出,再在NVIC里,配置相应的中断通道,然后写中断函数就行了。如果传输计数器清零了,还想传输的话,就失能DMA、写传输计数器、DMA使能。

//恢复缺省配置
void DMA_DeInit(DMA_Channel_TypeDef* DMAy_Channelx);

//初始化
void DMA_Init(DMA_Channel_TypeDef* DMAy_Channelx, DMA_InitTypeDef* DMA_InitStruct);

//结构体初始化
void DMA_StructInit(DMA_InitTypeDef* DMA_InitStruct);

//使能DMA
void DMA_Cmd(DMA_Channel_TypeDef* DMAy_Channelx, FunctionalState NewState);

//中断输出使能
void DMA_ITConfig(DMA_Channel_TypeDef* DMAy_Channelx, uint32_t DMA_IT, FunctionalState NewState);

//给传输计数器写数据的
void DMA_SetCurrDataCounter(DMA_Channel_TypeDef* DMAy_Channelx, uint16_t DataNumber); 

//返回传输计数器的值
uint16_t DMA_GetCurrDataCounter(DMA_Channel_TypeDef* DMAy_Channelx);

//获取标志位状态、清除标志位、获取中断状态、清除中断挂起位
FlagStatus DMA_GetFlagStatus(uint32_t DMAy_FLAG);
void DMA_ClearFlag(uint32_t DMAy_FLAG);
ITStatus DMA_GetITStatus(uint32_t DMAy_IT);
void DMA_ClearITPendingBit(uint32_t DMAy_IT);

DMA转运有三个条件:

第一个:传输计数器大于0

第二个:触发源有触发信号(软件触发一直都会有触发信号)

第三个:DMA使能

中断挂起:排队

中断标志:正在执行

DMA4个标志位:第一个是全局标志位,第二个是转运完成标志位,第三个是转运过半标志位,第四个是转运错误标志位

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值