STM32 DMA 循环模式DMA_Mode_Circular详解

系列文章目录

目前在网上还没看到详细讲解DMA循环模式的文章,参考手册中只有简单的一段话:
在这里插入图片描述
仅仅这么一段话,不一定对DMA的模式有深入的了解,通过阅读这篇文章,相信可以加深你对DMA的理解。



前言

DMA循环模式可用于循环队列,可通过DMA+空闲中断+循环队列,实现高效接收数据,然后对数据进行处理。
本文将讲解DMA循环模式与普通模式在实现效果上的区别,及为何循环模式要如此配置才能实现循环队列。


一、循环模式与普通模式

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;

第一步:DMA接收5个字节的数据
接收前,CNDTR=7。接收完数据后如下图所示:
在这里插入图片描述
接收数据后,CNDTR自动清0,需要先关闭DMA,重置CNDTR,然后再开启DMA。此时CNDTR=7。
第二步:DMA接收6个字节的数据
接收前,CNDTR=7,接收6个字节的数据后如下图所示:
在这里插入图片描述
此时CNDTR=0。观察图可发现缓存数组中只收到5个字节的数据(蓝色部分),丢失了1个字节。
在某些场景下,需要接收较多数据,但读取比较慢的情况下,就会导致数据的丢失,需要通过循环队列加以解决。(本文只讲如何用循环队列接收数据,循环队列数据的读取暂不讲解)

2、循环模式:
接收完一次数据后,CNDTR不清0,可继续接收下一次的数据。具体的实现看后面讲解。

二、循环模式的配置及实现效果

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;

第一步:DMA接收5个字节的数据
接收前,CNDTR=10。接收完数据后如下图所示:
在这里插入图片描述
接收数据后,CNDTR=5。

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

2.循环模式的配置解读

配置一

DMA_InitStructure.DMA_MemoryBaseAddr =&RxBuff[0];   //RxBuff一共有10个字节

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

DMA_InitStructure.DMA_BufferSize = 10;

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

为何必须要做这两项配置:
只有如此才能在数据存储到缓存末尾时,让CNDTR=0,然后DMA自动重置CNDTR,并将存储地址重置为缓存的第一个字节。

总结

本文详细讲解了DMA的循环模式和普通模式的实现效果及其区别。

版权声明:本文为CSDN博主「Brave515」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_45362275/article/details/119544121

生成海报
点赞 0

Brave515

我还没有学会写个人说明!

暂无评论

发表评论

相关推荐

基于STM32的指纹密码锁

设计简介: 本设计是基于单片机的指纹密码锁,主要实现以下功能: 矩阵按键输入密码,并通过按键显示*号可通过按键或手机开门密码可通过按键进行开门可通过蓝牙模块连接手机进行开门可通过指纹进

定时器触发STM32 ADC的采样转换示例

开发板:STM32F446 Nucleo开发板IDE:  keil MDK初始化配置工具:stm32cubeMx例程内容:通过定时器触发ADC规则通道及注入通道的模数转换工作。下面基于STM32CubeMx进行些必要

STM32串口发送接收数据

1.串口通信 我用的32是stm32f10x最小系统没有UART4和UART5 USART : 通用同步异步收发器 UART : 通用异步收发器 nRTS : 请求发送 nCTS : 请求接收 区别:USART指单片机的一个IO端

TCRT5000循迹模块原理及应用

前言 本文将讲述TCRT5000循迹模块的原理及应用。本文应用于STM32,对于使用循迹模块的你有一定的帮助。 以下是本篇文章的正文内容 一、TCRT5000循迹模块介绍 TCRT5000就是一个红外发射和接收器&#xff0