首页 > 解决方案 > STM32 DMA从定时器计数到内存

问题描述

我正在使用STM32H743。我在 GPIO 引脚上有一个外部时钟信号,我想非常准确地测量外部时钟信号中每个上升(或下降)沿之间经过的时间。所以我设置了 TIM4 由外部时钟触发,TIM5 由内部振荡器触发。

我写了一个 IRQ,这样每当 TIM4 触发时,就会运行一个中断来捕获 TIM5 的值。它似乎工作正常,但我想知道是否可以通过 DMA 来避免所有上下文切换并释放 CPU。基本上我想设置一个 DMA,以便每个 TIM4 事件启动一个 DMA 传输,将 TIM5 计数器值复制到某个地方的循环缓冲区。

我已经搜索了论坛和 DMA 文档,但我对定时器寄存器是否可以是有效的 DMA 源感到模糊。我在想也许我可以做这样的事情:

hDma->PAR = (uint32_t) &htim5.Instance->CNT;
hDma->M0AR = (uint32_t) myBufferPtr;
hDma->NDTR = myBufferSize;
hDma->CR |= (uint32_t)DMA_SxCR_EN;

但我不确定这是否可行。

简短版:我可以使用定时器的 CNT 寄存器作为 DMA 传输源吗?它会是外围设备到内存的传输吗?还是内存到内存的传输?我需要其他标志来完成这项工作吗?还是不可能?或者是否有另一个 STM32 功能可以更轻松地计算脉冲之间的时间?

标签: timerstm32dma

解决方案


免责声明

我必须承认,到目前为止,我在 STM32 方面的长期实践经验与 STM32F0、STM32F3、STM32F4 和 STM32L4 等主流控制器系列保持一致。因此,我会根据这些控制器在您的情况下为您提供什么来回答。STM32H7 系列更强大,更不用说它提供了一些额外的 DMA 技术,如 DMA2D、MDMA 和许多其他我不确定的东西。但我认为一个简化的答案现在也可能对你有所帮助,所以我敢于写它。


我可以使用定时器的 CNT 寄存器作为 DMA 传输源吗?它会是外围设备到内存的传输吗?还是内存到内存的传输?我需要其他标志来完成这项工作吗?还是不可能?

我希望这能奏效。我看不出有理由不在 DMA 传输中读取 TIMx_CNT 寄存器。

CNT 寄存器绝对是外设地址,因此您必须将其配置为外设到内存的传输。我相信外设/内存分离是指 DMA 控制器在每个 STM32 中实现的总线矩阵中从中获取数据的总线(或将数据传递到哪个总线)。

或者是否有另一个 STM32 功能可以更轻松地计算脉冲之间的时间?

是的,有:许多 TIM 外设(并非全部相同)为您提供称为“输入捕获”的功能,该功能将 TIM 实例的通道(子)外设连接到输入,并具有(同样!) TIM 外设执行内部时钟。这样做的先决条件是,您要测量的引脚具有 TIMx_CHy 备用功能,而不仅仅是“TIMx_ETR”。

TIM 外围设备提供了丰富的不同配置选项 - 只要您不习惯它,就会变得一团糟。作为介绍和很好的概述,我推荐 ST 的两个应用笔记:

查找这两个,我发现了与 HRTIM 计时器相关的第三个您可能想要检查以获得更好的精度:


推荐阅读