有限的解决方案无 DMA
STM32F4 控制器有 12 个定时器,每个定时器最多有 4 个 PWM 通道,总共 32 个。其中一些可以同步启动,例如你可以有TIM1
开始TIM2
, TIM3
, TIM4
and TIM8
同时地。这是 20 个同步 PWM 输出。如果这还不够,您可以形成一个从属计时器是另一个计时器的主计时器的链,但要保持所有计时器完全同步是相当棘手的。如果几个时钟周期的偏移是可以接受的,那么就不那么棘手了。
STM32CubeF4 库示例项目部分中有几个示例,您可以从中拼凑您的设置,请查看Projects/*_EVAL/Examples/TIM/*Synchro*
.
通用解决方案
通用或高级定时器(除了TIM6
and TIM7
) 当计数器达到重载值(更新事件)时可以触发DMA传输and当计数器等于任何比较值时(捕获/比较事件)。
这个想法是让 DMA 将所需的位模式写入到低(设置)一半BSRR
在比较事件上,以及相同的位到高(复位)一半BSRR
在更新事件上。
不过有一个问题,那就是DMA1
根本无法访问 GPIO 寄存器所连接的 AHB 总线(参见参考手册中的图 1 或图 2)。因此我们必须使用DMA2
,这给我们留下了高级计时器TIM1
or TIM8
。事情变得更加复杂,因为这些定时器的更新和比较事件引起的 DMA 请求最终会出现在不同的 DMA 流上(请参见 RM 中的表 43)。为了使其更简单,我们可以使用 DMA 2、Stream 6 或 Stream 2、Channel 0,它们组合了来自 3 个定时器通道的事件。我们可以将一个定时器通道上的比较寄存器设置为 0,而不是使用更新事件。
设置所选定时器的 DMA 流
- 频道0
- 单次传输(无突发)
- 内存数据大小 16 位
- 外设数据大小 16 位
-
no内存增量
- 外设地址增量
- 循环模式
- 内存到外设
- 外围流量控制器:我不知道,实验
- 数据项数量 2
- 外设地址
GPIOx->BSRR
- 内存地址指向输出位模式
- 直接模式
- 最后,启用通道。
现在,设置计时器
- 设置预分频器并根据需要生成更新事件
- 设置自动重载值以达到所需的频率
- 将通道1的比较值设置为0
- 将通道2的比较值设置为所需的占空比
- 启用两个通道的 DMA 请求
- 在两个通道上启用比较输出
- 启用计数器
这样,每个定时器可以控制 16 个引脚,如果在主从模式下使用它们,则可以控制 32 个引脚。
要同时控制更多引脚(最多 64 个),请为通道 4 比较和定时器更新事件配置附加 DMA 流,将数据项数量设置为 1,然后使用((uint32_t)&GPIOx->BSRR)+2
作为更新流的外设地址。
通道 2 和 4 可用作常规 PWM 输出,从而为您提供了 4 个以上的引脚。也许第三频道也是如此。
您仍然可以使用TIM2
, TIM3
, TIM4
, and TIM5
(每个人都可以被奴役TIM1
or TIM8
)用于另外 16 个 PWM 输出,如我的文章第一部分所述。或许TIM9
and TIM12
如果您能找到合适的主从设置,也可以再添加 4 个。
即有 90 个引脚同时切换。注意总电流限制。