2017-10-06 163 views
2

我有一个STM32F4,我想PWM一个已经或运算带着面具GPIO端口..PWM DMA到整个GPIO

所以,也许我们要在200kHz至PWM 0b00100010一段时间,但是接着,在10khz之后,我们现在想要PWM 0b00010001 ...然后,在10kHz之后,我们希望在相同的GPIO上PWM一些其他掩模。

我的问题是,你如何做到这一点与DMA?我试图触发一个DMA传输,将所有位设置在上升沿,然后再进行另一次DMA传输,以在下降沿清除所有位。

我还没有发现,因为它看起来像我只得到一个机会,做一个上升沿东西的好办法做到这一点,(至少CubeMX和我使用C & STM32的经验有限)。

我的一个主要关注点是CPU时间,因为虽然我提到数百kHz的在上面的例子中,我想使这个框架非常坚固那么远,因为它是不会浪费的CPU资源...这就是为什么我喜欢DMA的想法,因为它是专用硬件,可以在这里无意识地提取单词,并且CPU可以做其他事情,比如PID的紧缩数字或其他东西。

编辑 为清楚:我有一组6个值的,我可以写一个GPIO。这些存储在一个数组中。 我想要做的是建立一个PWM定时器,在PWM的正宽度期间设置GPIO,然后我希望GPIO在低周期宽度期间设置为0b00000000(如果pwm)。因此,我需要看到什么时候上升沿,快速写入gpio,然后看下降沿是什么时候,写0到gpio。

+0

什么是10kHz以后? Hz不是时间单位。 DMA不能做任何逻辑操作。它只是将数据从位置A传送到B. –

+0

好的... 100us后,我想将相同的200khz pwm应用于GPIO上的不同引脚。因此,我们将包含掩码的变量传送到GPIOx-> BSRR或在PWM的上升沿用DMA,然后在下降沿将GPIO设置回零... 100us层,不同的定时器溢出或比较什么的,然后唯一改变的就是现在我们在上升沿加载一个不同的值的DMA。 – testname123

+0

我已经给你答案了。我的例子是1位。它也可以是16。否则使用定时器生成的PWM –

回答

1

限定溶液没有DMA

STM32F4控制器有12个定时器,每个定时器最多4个PWM通道,总共32个。它们中的一些可以被同步以一起开始,例如,你可以同时有TIM1开始TIM2,TIM3,TIM4TIM8。这是20个同步PWM输出。如果这还不够,你可以在奴隶计时器成为另一个主人的时候形成链子,但保持所有人完全同步是相当棘手的。如果几个时钟周期的偏移量是可接受的,则不那么棘手。

在STM32CubeF4库示例项目部分中有几个示例,您可以从中拼出您的设置,查看Projects/*_EVAL/Examples/TIM/*Synchro*

通用的解决方案

当计数器达到重载值(更新事件)当通用或高级定时器(这是所有的人除了TIM6TIM7)都能触发DMA传输计数器等于任何比较值(捕获/比较事件)。

这个想法是让DMA在比较事件时将所需的位模式写入BSRR的低位(设置)一半,并在更新事件中将相同的位写入BSRR的高位(复位)部分。

尽管如此,DMA1根本无法访问AHB总线(参见参考手册中的图1或2),GPIO寄存器连接到该总线。因此我们必须使用DMA2,这使我们留下了先进的计时器TIM1TIM8。事情变得更加复杂,因为来自这些定时器的更新和比较事件导致DMA请求以不同的DMA流结束(参见RM中的表43)。为了使它变得更简单,我们可以使用DMA 2,流6或流2,通道0,它们结合来自3个定时器通道的事件。代替使用更新事件的,我们可以设置比较在一个计时器通道寄存器为0

设置所选择的定时器的DMA流中,以

  • 通道0
  • 单个传输(不爆裂)
  • 存储器数据大小16位
  • 外围数据大小16位
  • 没有存储器增量
  • 外设地址增量
  • 圆形模式
  • 存储器到外围
  • 周流量控制器:数据项2
  • 外围地址GPIOx->BSRR
  • 存储器地址指向的我不知道,实验
  • 数到输出位模式
  • 直接模式
  • 最后,启用通道。

现在,设置定时器

  • 设置的分频器,如果需要
  • 设置自动重载值,以达到所需频率
  • 一套比较通道的值产生一个更新事件1到0
  • 将通道2的比较值设置为所需的占空比
  • 启用两个通道的DMA请求
  • 使两个通道上比较输出
  • 如果在主从模式下使用它们两者使能计数器

这种方式可以控制16个引脚,每个计时器,32。

要一次控制更多的引脚(最多64个)时,配置附加的DMA流为信道4比较和定时器更新事件,设置数据项的数目为1,并使用((uint32_t)&GPIOx->BSRR)+2作为外围地址更新流。

通道2和通道4可用作常规PWM输出,为您提供4个以上的引脚。也许是第3频道。

可以仍然使用TIM2TIM3TIM4TIM5如在我的支柱的所述第一部分中所描述(每一个都可以从属于TIM1TIM8)为16个以上的PWM输出。也许还有TIM9TIM12,如果你能找到合适的主从设置,还有4个。

这是90针同时切换。注意总电流限制。

+0

就是这样!谢谢! – testname123

0

PWM 0b00100010是什么意思? PWM是具有一定占空比的方波。使用DMA进行归档将非常困难,但您需要使用已计算值的表格。例如,要有10%比例的2kHz PWM,您需要有10个采样位,其中一个采样位置1,另外9个采样位置零。您将定时器配置为20k/sec触发mem-to-mem(GPIO必须以此方式完成)以循环模式传输DMA。在引脚上你将有2kHz 10%的波形。 PWM分辨率将为10%。如果你想使它达到0.5%,你将需要200个采样表和DMA触发每秒400k次。

IMO最好是使用计时器和DMA加载新值到它(读取有关突发DMA模式定时器文档中的参考手册)

+0

不好意思,但我似乎歪曲了这个问题。请允许我澄清: – testname123