STM32片上资源:DMA

1.DMA简介

(1)DMA是英文Direct Memory Access的简称,意为直接存储器存取。

(2)DMA可以提供外设和存储器或者存储器和存储器之间的高速数据传输,无须CPU干预,节省了CPU的资源。

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

(4)每个通道都支持软件触发特定的硬件触发

(5)STM32F103C8T6的DMA资源:DMA1(7个通道)。

注:

1.DMA外设可直接访问STM32内部存储器,包括运行内存SRAM,程序存储器Flash和寄存器等。

2.外设:一般是外设的数据寄存器DR。

3.DMA通道,即路径,从一个地方转运到另一个地方。

4.DMA触发:软件触发(一般用于存储器到存储器);特定的硬件触发(一般用于外设到存储器,因为外设触发都是有一定时机的),“特定”每个DMA通道的硬件触发源是不一样的。

2.存储器映像

类型起始地址存储器用途
ROM0x0800 0000程序存储器Flash存储C语言编译的程序代码
ROM0x1FFFF F000系统存储器存储Bootloader,用于串口下载
ROM0x1FFF F800选项字节存储一些独立于程序中的配置参数
RAM0x2000 0000运行内存SRAM存储运行过程中的临时变量
RAM0x4000 0000外设寄存器存储各个外设的配置参数
RAM0xE000 0000内核外设寄存器存储内核各个外设的配置参数

注:

(1)外设寄存器,实际上也是存储器,前面是的外设到存储器,存储器到存储器本质上都是存储器到存储器之间的数据转运。

(2)ROM:只读存储器,是一种非易失性,不丢失的存储器。

(3)RAM:随机存储器,是一种易失性,掉电丢失的存储器。

3.DMA框图

图解:

(1)在上角Cortex-N3内核,里面包含了CPU和内核外设NVIC和SysTick等,剩下所有东西都可看作存储器。

(2)为了让CPU高效有理访问存储器,设计总线矩阵,总线矩阵左端是主动单元,拥有存储器的访问权,右边这些是被动单元,只能被左边的自动单元读写。

(3)DMA要转运数据,所有访问权,DMA1有一条总线,DMA2也有一条,DMA1有7个通道,DMA2有5个通道,可设置它们转运数据的源地址和目的地址,这样就可以开始工作了。

(4)DMA也是AHB的从设备,也就是说DMA自身的寄存器。DMA作为一个外设,有对应寄存器,这里连接到了总线右边的AHB总线上。

总结:DMA既是总线矩阵的主动单元,可以读写各种存储器,也是AHB总线上的被动单元,CPU通过下面这条线路即可对DMA进行配置。

(5)DMA请求含义:DMA请求就是DMA的硬件触发源,比如ADC转换完成,串口接收到数据,需要触发DMA转运数据的时候,就会通过DMA请求这条路线,向DMA发出硬件触发信号,之后DMA就可以执行数据转运到其他地方的工作了。

注:

1.CPU或DMA直接访问Flash的话,是只可读不可以写的

2.SRAM是运行内存,可以任意读写没有问题。

3.外设寄存器要看参考手册里的描述,有的是只读,有的是只写,不给我们只要用的是数据寄存器,数据寄存器都是可以正常读写的。
 

3.1DMA流程

(1)开启DMA时钟。

(2)初始化DMA

        1.DMA_Mode:传输模式,可选择一次传输和循环传输,该选项决定了传输计数器是否重装

        2.DMA_BufferSize:缓冲区大小,即传输计数器的值,每次传输几个数据。

        3.DMA_M2M:选择软件触发还是硬件触发。

(3)开启外设的DMA(如ADC_DMACmd()),开启触发信号的输出。

(4)如需要,开启DMA的中断(DMA_ITConfig()),之前在NVIC里配置相应的通道,编写中断服务函数。

(5)DMA_Cmd:使能DMA开始运转。

(6)用DMA_GetFlagStatus判断是否传输完成,记得手动清除标志位。(但使用单词传输,如果传输结束后需要再次传输,需先失能DMA后再写传输计数器DMA_SetCurrDataCounter()再使能DMA)

4.DMA基本结构

注:

(1)DMA转运方向:1.外设到存储器

                                   2.存储器到外设

                                   3.存储器到存储器(Flash到SRAM;SRAM到SRAM)

        补充:因为Flash是只读的,所有不可以进行SRAM到Flash和Flash到Flash。

(2)外设和存储器要配的三个参数:1.起始地址:决定了数据从哪里来到哪里去。

                                                            2.数据宽度:指定一次转运要按多大的数据宽度来进行,

                                                                                可选择字节Byte,半字halfword和字word。

                                                            3.地址是否自增:指定一次转运完成后下一次转运,是不

                                                                                        是要把地址移到下一个位置。

(3)输出计数器:指定总只需要运行几次的,是一个自减计数器,减到0后,DMA就不会转运数据了,另外在减到0后自增的地址,也会恢复到最初的值,方便新一轮DMA转运。

(4)自动重装器:当传输计数器减到0后,是否要恢复到最初的值,即是单次模式还是循环模式。

(5)触发:M2M决定是软件触发还是硬件触发。M2M给1是软,给0是硬。(注:这里的软件触发并不是调动一次函数,触发一次,而是不断的触发DMA争取早日把计数器清0,可理解位连续触发,所有软件触发和循环模式不可同时使用)

补充:1.单次传输与循环模式的区别。单次模式:在DMA转运数据完成后,计数器不会恢复,如果要手动恢复计数器的值,需先关闭DMA。循环模式:在传输完成后自动恢复计数器并进行下一轮。2.触发选择。软件触发(连续触发):是尽快完成数据传输,适用于存储器到存储器(不可循环模式)。硬件触发适用于外设到存储器。

4.1总结:DMA转运条件

(1)开关控制:DMA_Cmd()必须使能。

(2)传输计数值必须大于零。

(2)触发源,必须有触发信号,硬件触发或软件触发。

5.DMA请求映像:不同DMA通道的触发源

图解:

(1)上图的数据选择器的EN位并不是选择哪一路数据位,而是决定这个通道(数据选择器)要不要工作,EN=0,数据选择器不工作,EN=1,数据选择器工作.

(2)软件触发:M2M给1。

(3)每个通道的硬件触发源不同,要根据对应的触发源来选择通道。

(4)DMA触发源选择是由这个外设是否开启了DMA输出来决定的,比如要使用ADCA,那会有个ADC1_DMACmd,必须使用这个库函数开启ADC这一路的输出才有效。

6.DMA相关函数

6.1 标配函数

void DMA_DeInit();

void DMA_Init();

void DMA_StructInit();

void DMA_Cmd();

6.2 void DMA_ITConfig()                               

作用:中断输出使能

6.3 传输器相关函数

void DMA_SetDataCounter()                           #DMA设置数据存储器(给传输计数器写数据)

uint16_t DMA_GetDataCounter()                    #DMA获取当前数据寄存器(返回传输计数器的值)

6.4 标志位标配函数

FlagStatus DMA_GetFlagStatus();

void DMA_ClearFlag();

ITStatus DMA_GetITStatus();

void DMA_ClearITPendingBit();

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值