STM32 DMA 从定时器计数到内存

Kev*_*olt 3 timer 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;
Run Code Online (Sandbox Code Playgroud)

但我不确定这是否可行。

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

Hel*_*and 5

免责声明

我必须承认,我在 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 计时器相关: