gpt4 book ai didi

arm - PWM DMA 到整个 GPIO

转载 作者:行者123 更新时间:2023-12-02 03:46:20 27 4
gpt4 key购买 nike

我有一个 STM32F4,我想对一个已与掩码进行“或”运算的 GPIO 端口进行 PWM 处理。

所以,也许我们想要以 200khz 的频率 PWM 0b00100010 一段时间,但是,10khz 后,我们现在想要 PWM 0b00010001...然后,10kHz 后,我们想要在同一个 GPIO 上对其他一些掩码进行 PWM 调制。

我的问题是,如何使用 DMA 做到这一点?我正在尝试触发一个 DMA 传输,该传输将在上升沿设置所有位,然后触发另一个 DMA 传输,该传输将在下降沿清除所有位。

我还没有找到一个好的方法来做到这一点(至少使用 CubeMX 以及我在 C 和 STM32 方面的有限经验),因为看起来我只有机会在上升沿做一些事情。

我主要关心的问题之一是 CPU 时间,因为尽管我在上面的示例中提到了数百千赫兹,但我想让这个框架非常健壮,因为它不会浪费 CPU资源...这就是为什么我喜欢 DMA 的想法,因为它是专用硬件,可以无意识地将这里的一个单词提升到那里的一个单词之类的东西,而 CPU 可以做其他事情,比如处理 PID 的数字或其他东西。 p>

编辑为了清楚起见:我有一组 6 个值,可以写入 GPIO。它们存储在一个数组中。我想要做的是设置一个 PWM 定时器来在 PWM 的正宽度期间设置 GPIO,然后我希望在低周期宽度期间将 GPIO 设置为 0b00000000(如果 pwm.因此,我需要查看上升沿何时,快速写入GPIO,然后查看下降沿何时,并向GPIO写入0。

最佳答案

没有 DMA 的有限解决方案

STM32F4 Controller 有 12 个定时器,每个定时器最多有 4 个 PWM channel ,总共 32 个。其中一些可以同步启动,例如您可以让 TIM1 同时启动 TIM2TIM3TIM4TIM8。这是 20 个同步 PWM 输出。如果这还不够,您可以形成一个从属计时器是另一个计时器的主计时器的链,但要保持所有计时器完全同步是相当棘手的。如果几个时钟周期的偏移是可以接受的,那么就不那么棘手了。

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

通用解决方案

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

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

但有一个问题,DMA1 根本无法访问 GPIO 寄存器所连接的 AHB 总线(参见引用手册中的图 1 或图 2)。因此,我们必须使用 DMA2,这样我们就可以使用高级定时器 TIM1TIM8。事情变得更加复杂,因为由这些定时器的更新和比较事件引起的 DMA 请求最终会出现在不同的 DMA 流上(请参见 RM 中的表 43)。为了使其更简单,我们可以使用 DMA 2、Stream 6 或 Stream 2、Channel 0,它们组合了来自 3 个计时器 channel 的事件。我们可以将一个定时器 channel 上的比较寄存器设置为 0,而不是使用更新事件。

设置所选定时器的DMA流

  • channel 0
  • 单次传输(无突发)
  • 内存数据大小16位
  • 外设数据大小16位
  • 内存增量
  • 外设地址增量
  • 循环模式
  • 内存到外设
  • 外设流量 Controller :我不知道,实验
  • 数据项数量 2
  • 外设地址GPIOx->BSRR
  • 内存地址指向输出位模式
  • 直接模式
  • 最后,启用 channel 。

现在,设置计时器

  • 设置预分频器并根据需要生成更新事件
  • 设置自动重新加载值以达到所需的频率
  • 将 channel 1的比较值设置为0
  • 将 channel 2 的比较值设置为所需的占空比
  • 为两个 channel 启用 DMA 请求
  • 在两个 channel 上启用比较输出
  • 启用计数器

这样,每个定时器可以控制 16 个引脚,如果在主从模式下使用它们,则可以控制 32 个引脚。

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

channel 2 和 4 可用作常规 PWM 输出,为您提供了 4 个以上的引脚。也许 channel 3 也是如此。

您仍然可以使用 TIM2TIM3TIM4TIM5(每个都可以从属于TIM1TIM8)用于另外 16 个 PWM 输出,如我的帖子第一部分所述。如果您能找到合适的主从设置,也许还有 TIM9TIM12,还有 4 个。

即同时切换 90 个引脚。注意总电流限制。

关于arm - PWM DMA 到整个 GPIO,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46613053/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com