打印

stm32的dma

[复制链接]
1131|11
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
keer_zu|  楼主 | 2022-1-12 16:56 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
沙发
keer_zu|  楼主 | 2022-1-12 16:56 | 只看该作者
一、循环模式与普通模式
1、普通模式:
在普通模式下,接收完一次数据后,CNDTR自动清0,需要先关闭DMA,重置CNDTR,然后再开启DMA。

通过接收两次数据来加以介绍:
假设部分配置如下:
DMA_InitStructure.DMA_MemoryBaseAddr =&RxBuff[0];    //RxBuff一共有10个字节
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_BufferSize = 7;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;

使用特权

评论回复
板凳
keer_zu|  楼主 | 2022-1-12 16:58 | 只看该作者
第一步:DMA接收5个字节的数据
接收前,CNDTR=7。接收完数据后如下图所示:

接收数据后,CNDTR自动清0,需要先关闭DMA,重置CNDTR,然后再开启DMA。此时CNDTR=7。

使用特权

评论回复
地板
keer_zu|  楼主 | 2022-1-12 16:59 | 只看该作者
第二步:DMA接收6个字节的数据
接收前,CNDTR=7,接收6个字节的数据后如下图所示:

此时CNDTR=0。观察图可发现缓存数组中只收到5个字节的数据(蓝色部分),丢失了1个字节。
在某些场景下,需要接收较多数据,但读取比较慢的情况下,就会导致数据的丢失,需要通过循环队列加以解决。(本文只讲如何用循环队列接收数据,循环队列数据的读取暂不讲解)

使用特权

评论回复
5
keer_zu|  楼主 | 2022-1-12 17:00 | 只看该作者
2、循环模式:
接收完一次数据后,CNDTR不清0,可继续接收下一次的数据。具体的实现看后面讲解。

使用特权

评论回复
6
keer_zu|  楼主 | 2022-1-12 17:00 | 只看该作者
二、循环模式的配置及实现效果
1.循环模式的实现效果
假设部分配置如下:

DMA_InitStructure.DMA_MemoryBaseAddr =&RxBuff[0];    //RxBuff一共有10个字节
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_BufferSize = 10;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;

使用特权

评论回复
7
keer_zu|  楼主 | 2022-1-12 17:02 | 只看该作者
第一步:DMA接收5个字节的数据
接收前,CNDTR=10。接收完数据后如下图所示:

接收数据后,CNDTR=5。

使用特权

评论回复
8
keer_zu|  楼主 | 2022-1-12 17:02 | 只看该作者
第二步:DMA接收6个字节的数据
接收前,CNDTR=5,接收6个字节的数据后如下图所示:

接收数据后,CNDTR=9。观察上图可发现,6个字节的数据都接收到了,没有丢失。
这是如何实现的?
这6个字节的接收可分成三步来讲解:
第一步:接收完5个字节的数据后,CNDTR=0;
第二步:DMA自动装载初始化时的配置,下一步接收数据时的地址指向RxBuff[0],CNDTR重置为10;
第三步:DMA在RxBuff[0]处继续接收剩下的数据。
如此,我们就完美地实现了循环队列。循环队列的实现基本是依靠DMA初始化时的配置实现的,在下面将讲解配置时的要点,及为何要如此配置。

使用特权

评论回复
9
keer_zu|  楼主 | 2022-1-12 17:04 | 只看该作者
2.循环模式的配置解读
配置一:
DMA_InitStructure.DMA_MemoryBaseAddr =&RxBuff[0];   //RxBuff一共有10个字节


DMA开始存储数据的起始地址要设置在缓存的第一个字节处。

使用特权

评论回复
10
keer_zu|  楼主 | 2022-1-12 17:05 | 只看该作者
本帖最后由 keer_zu 于 2022-1-12 17:06 编辑

配置二:
DMA_InitStructure.DMA_BufferSize = 10;

CNDTR的值要和缓存的大小相同(数字10只是这个例子中缓存的大小)。

使用特权

评论回复
11
keer_zu|  楼主 | 2022-1-12 17:06 | 只看该作者
为何必须要做这两项配置:
只有如此才能在数据存储到缓存末尾时,让CNDTR=0,然后DMA自动重置CNDTR,并将存储地址重置为缓存的第一个字节。

使用特权

评论回复
12
keer_zu|  楼主 | 2022-1-12 17:07 | 只看该作者
总结
本文详细讲解了DMA的循环模式和普通模式的实现效果及其区别。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:qq群:49734243 Email:zukeqiang@gmail.com

1352

主题

12436

帖子

53

粉丝