(学习笔记)stm32f429——DMA控制器

DMA(Direct Memory Access,直接存储器访问)。什么提高cpu效率,什么工作原理都不管,高速传输也不说。

只说两个案例,存储器到存储器的模式 + 存储器到外设的模式 。

从DMA框图上来说,DMA由以下组成:首先是数据流,f429有0~7这8条数据流;接着是通道选择,每条数据流对应0~7这8个通道,数据流与通道选择形成一个表格,具体外设对应固定的流和通道,由查参考手册中的表可得;然后是仲裁器,当外设DMA请求冲突时,由仲裁器规则决定执行对象,这个仲裁器好比分两个层次,先是软件设置优先级(有4个优先级),当两个请求优先级相同时,由硬件决定——编号低的数据流优先于编号高的数据流;最后是FIFO(First In First Out,(这不就是队嘛)。。。),这是32位先进先出的存储器缓冲区。

说下FIFO的模式:直接模式和FIFO模式。直接模式是禁止FIFO模式下的默认模式,在这种模式下,初始化DMA之后,源的数据直接进入FIFO缓冲区,DMA请求一来就开始传输数据。在这种模式下,源与目标数据宽度必须相同,而且数据流只能生成单次传输,手册中说由硬件强制配置。(这边得提一下一个问题,中文参考手册在存储器到存储器的模式下有一个注意点:使用存储器到存储器的模式时,不允许循环模式和直接模式。但是,在Flash到SRAM的实例中,直接模式是行得通的,FIFO模式倒是没有尝试。)

FIFO模式,源与目标的数据宽度可以不同,通过设置FIFO阈值来限制或者是扩展数据宽度,实现突发。FIFO我是真的不是很清楚,在下面的存储器到外设的实例有所尝试。

DMA的初始化就简单点说:1、打开时钟,两个DMA都挂载到AHB1上       2、调用DMA_DeInit()复位数据流寄存器 ,通过DMA_GetCmdStatus()判断复位是否完成

3、初始化结构体,配置各种参数 4、DMA_Cmd()使能DMA,并通过DMA_GetCmdStatus()等待数据里有效               5、发送DMA请求

在存储器到存储器的实例中,在Flash中定义一段数组const uint32_t aSRC_Const_Buffer[BUFFER_SIZE],因为在DMA中发送数据项数是一定得知道的,除了SDIO外设。定义一个相同大小的变量数组,存放在SRAM内。存储器到存储器的模式中不需要DMA请求,在使能DMA之后开始传输数据。这边的初始化结构体应该不需要说明。地址都是数组名,数据项数是BUFFER_SIZE,得使能外设和存储器的地址自增功能。最后需要写一个校验函数来检验传输是否正确,即比较两个数组是否相等。

在存储器到外设的实例中,定义一个存储器中的数组,将这段数据通过USART1,再通过USB传输显示到PC上的串口调试工具。

先是用了直接模式,定义了一个8位的数组,只需要在初始化中关闭外设地址自增功能(外设数据寄存器地址唯一),在main函数中请求DMA发送就可以接收。这边有一点小猫腻,以为USART是8位串口传输的,正好数组是8位的,所以传输结果正确。我也没去试试16位的直接模式,明天试试吧。

然后因为对FIFO模式的不理解,尝试了下。说下菜鸟的尝试过程:决定还是定义8位数组,但是目的数据宽度设置为半字,使能FIFO,设置阈值为1/4满,1/4满是1个字,我定义数组为{‘A’,'B','C','D'};(在FIFO模式下如果设置目标数据宽度为字节,结果正确。)

结果显示为AC,16位进制显示结果为41 43 00 00;

之后数组定义为{‘A’,'0','B','0','C','0','D','0'};,这回显示结果为ABCD,16进制显示结果为41 42 43 44 00 00 00 00。

然后大概明白是因为USART是8位传输的原因,但是后面的4个00 是什么原因也是不明白。

有没有大神给我讲讲突发模式中的节拍增量是什么意思?手册看不懂勒。

你可能感兴趣的:(stm32,串口通信)