硬汉嵌入式论坛

 找回密码
 立即注册
查看: 719|回复: 4
收起左侧

[DMA] V7-010,V7-011DMA产生PWM波实验发现的奇怪现象

[复制链接]

20

主题

94

回帖

154

积分

初级会员

积分
154
发表于 2023-2-14 19:20:30 | 显示全部楼层 |阅读模式
今天学习了V7-010,V7-011用DMA定时触发往GPIO->BSRRL发数据的实验,实验通过修改定时器的触发时间就可以修改产生的PWM波的频率。

不断提高定时器的触发频率,看看这个方法生成的PWM波频率可以到多少。理论上DMA或GPIO性能足够的话,定时器以最高溢出率工作,可以产生100M的触发频率,DMA搬运数据到GPIO,应该可以产生50M的PWM波,但我发现定时器触发频率高于20M以后,无论再怎样提高触发频率都不能将PWM波频率提高了,说明达到了DMA或GPIO的性能上限。

出于好奇,我将这个方法移植到了240M主频工作的AT32F403A、AIR32F103这两个芯片上,奇怪的是,居然这两个芯片输出的PWM波也都是止步于10MHz。

这是否说明,芯片的DMA是否以一个约大约20M的时钟在工作的呢?
回复

使用道具 举报

20

主题

94

回帖

154

积分

初级会员

积分
154
 楼主| 发表于 2023-2-14 20:40:06 | 显示全部楼层
比如HCLK的频率是240MHz,实际上DMA是用HCLK的比如8分频来工作的,DMA只能在8个时钟完成一次传输,再加上一些可能的总线竞争等待,速度是低于240M/8=30M 的,这样以20M的频率来触发DMA,就已经达到了DMA传输能力的极限了?
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106649
QQ
发表于 2023-2-15 02:11:16 | 显示全部楼层
准确的说,应该是H7的普通DMA是不支持单时钟周期搬运,需要多个周期才可以完成一次。

而其他的像MDMA, DMA2D比CPU搬运都快(TCM以外的测试项),是不是可以认为他运行的主频比CPU还高,显然不能。

image.png



回复

使用道具 举报

20

主题

94

回帖

154

积分

初级会员

积分
154
 楼主| 发表于 2023-2-15 08:10:26 | 显示全部楼层
我前面的理解有一定的偏差,想当然的认为在定时器触发下,应该每个触发时钟下,DMA可以完成一次数据搬运。
但是无论是DMA、还是CPU在数据搬运这一块,总是离不开做以下几个步骤的。

1、在AHB总线上送出源数据的地址
2、读AHB总线上的源数据
3、在AHB总线上送出目的数据地址
4、将数据送到AHB总线
5、源数据地址、目的数据地址加1
6、重复第1步

以上步骤,如果每一个步骤需要1个时钟,每次DMA数据搬运也是需要多个时钟的。这也解释了为什么不同的DMA在
数据搬运上效率的不同,可能不同的DMA在设计中,对以上几个步骤的处理、优化不一样,导致了性能的差异。
DMA比CPU快,可能是因为CPU需要执行循环,DMA却可以优化掉循环等过程。

在DMA的性能测试中,我再重新粗略测试了Air32F103, 他的DMA1其实可以用定时器以30MHz的速度稳定搬运数据到GPIO,
得到15MHz的PWM波,而STM32H750的DMA1最高只能得到11M左右的PWM波,这应该说明这个5元的国产单片机DMA1性能其实
还优于H750。本来想测一下MDMA搬运数据到GPIO,可以得到多高的PWM波的,但硬汉哥的例程里用了DMAMUX,怎么配置还需研究一番,遂作罢。


另外,也引起了另一个疑问。以D2域的SRAM1为例,他的带宽到底可以达到多少?这决定了可以有多个主控同时
并行的从SRAM1中读取数据。
假如,1个周期可以完成一次数据读取,SRAM1的总线宽带为32,是否意味着SRAM1可以达到的理论带宽是200M*32/8=800MB/s
从上面的测试中,CPU在D2域SRAM1中互传,速度达到336MB,考虑一读一写,是否可以*2,接近理论上800MB?
回复

使用道具 举报

20

主题

94

回帖

154

积分

初级会员

积分
154
 楼主| 发表于 2023-2-16 22:04:39 | 显示全部楼层
经过测试STM32H750的DMA1、DMA2可以在如下配置下,实现无SRAM总线竞争的条件下,6个AHB总线时钟一次的SRAM到GPIO的数据搬运。
[C] 纯文本查看 复制代码
    __HAL_RCC_DMA1_CLK_ENABLE();
    DMA_Handle.Instance                 = DMA1_Stream1;           
    DMA_Handle.Init.Request             = DMA_REQUEST_GENERATOR0;
    DMA_Handle.Init.Direction           = DMA_MEMORY_TO_PERIPH;   
    DMA_Handle.Init.PeriphInc           = DMA_PINC_DISABLE;      
    DMA_Handle.Init.MemInc              = DMA_MINC_ENABLE;        
    DMA_Handle.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;    
    DMA_Handle.Init.MemDataAlignment    = DMA_MDATAALIGN_WORD;     
    DMA_Handle.Init.Mode                = DMA_CIRCULAR;          
    DMA_Handle.Init.Priority            = DMA_PRIORITY_LOW;      
    DMA_Handle.Init.FIFOMode            = DMA_FIFOMODE_ENABLE;   
    DMA_Handle.Init.FIFOThreshold       = DMA_FIFO_THRESHOLD_HALFFULL; // DMA_FIFO_THRESHOLD_1QUARTERFULL;
    DMA_Handle.Init.MemBurst            = DMA_MBURST_SINGLE;    
    DMA_Handle.Init.PeriphBurst         = DMA_PBURST_SINGLE;      


做到6个周期完成一次传输的关键在于DMA的FIFO设置,使用FIFO后,应该是降低了DMA对SRAM总线的需求,缩短了一次传输的时钟需求。
在禁止FIFO时,需要9个时钟才能稳定触发一次传输。
而且对FIFO的触发阈值不能设置为FULL
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-4-27 21:31 , Processed in 0.177578 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表