【STM32学习】直接存储器访问——DMA

零、参考

一个严谨的STM32串口DMA发送&接收(1.5Mbps波特率)机制
【组件】通用环形缓冲区模块

上述是我的参考链接,对理解DMA发送与接受,以及缓冲区的使用非常有帮助。
建议将代码通读,而不仅仅是使用。

一、对DMA的理解

这里用大白话,描述一下个人对DMA的理解。
即不用在CPU干预的情况下 ,DMA能将外设与内存之间的数据进行直接交换,也就是DMA能直接将内存中的数据发送至外设接口,或者从外设接口接收数据放到内存中。
对于发送(内存到外设),我们只需要启动DMA发送(每次发送都需要启动),然后CPU就能去干别的事情了,整个发送过程由DMA处理,不占用CPU,当数据发送完毕时,会触发传输完成的终端,我们再处理即可。
对于接收(外设到内存),我们只需要配置一次DMA接收,当外设数据到来时,我们根本不会察觉到,因为CPU根本就不鸟它,数据会被直接放到我们设置的内存中。只有当接收的数据半满或者全满时,触发中断,我们才能感知到。

二、DMA通道优先级

在这里插入图片描述
在这里插入图片描述

上述是STM32F103RBT6的DMA通道接口图。
可以看到一共有7个通道,每个通道有几个请求,同一个通道在同一时间,只能相应一个请求。
这么多个通道同一时间也只能有一个通道能进行DMA传输。
这就涉及到了优先级问题。
优先级控制由仲裁器进行管理:先看软件配置的等级,谁高谁就先传输;如果软件等级相同,那就看硬件,谁的通道号小,谁就先传输。
在这里插入图片描述

三、DMA通道x传输数量寄存器(DMA_CNDTRx)

在这里插入图片描述

该寄存器只能在通道不工作的时候,才能写入。
如果该寄存器需要修改了,我们可以停止该通道,然后重新配置,再使能即可。

这个寄存器的数值到底代表了什么?
对于发送(内存到外设),我们一般会将内存的大小,放入这个寄存器中。当启动DMA发送,每传输一个数据,这个寄存器的数值就减少一;例如,假设内存大小为128,我们要将这128个数据全部发送,需要将128写入到该寄存器,然后启动DMA发送。每当内存到外设传输一个数据,该寄存器就减一。比如已经发送了20个数据,那么我们查询还有多少数据没有发送呢?就是CNDTR(剩余多少个数据没发送)。当数据发送了一半或者数据发送完毕,分别会触发DMA传输半满和全满中断。
对于接收(外设到内存),我们一般会将内存的大小,放入这个寄存器中。DMA接收时,CPU是无感知的,是直接往该内存中存放的。每当DMA接收一个数据,该寄存器中的数值就减少一;例如;假设内存大小为128,当DMA接收了100个时,CNDTR中的数据为128-100=28,表示还有多少个数据没有接收到。当数据接收了内存大小的一半或者全部,分别会触发DMA传输半满和全满终端。

DMA传输半满和全满的判断标准是以CNDTR寄存器中的数据为标准的。

在一个问题是:该寄存器中的这一句话的意思是什么?“数据传输结束后,寄存器的内容或者变为0;或者当该通道配置为自动重加载模式时,寄存器的内容将被自动重新加载为之前配置时的数值。”。
在这里插入图片描述
自动重加载模式好比就是循环工作模式

四、DMA缓冲区设计

对于接收而言,如果外设交互速度很快,DMA设置的内存中的数据,如果没有及时取出的话,就被覆盖掉。所以,需要设立缓冲区,为CPU处理数据提供空当;当然,如果CPU处理缓冲区的数据很慢的话,数据也是会被覆盖掉的。
这里常用就是利用半满和全满中断的双缓冲机制,大家可以看我参考的链接,十分值得学习。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

秋山刀名鱼丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值