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;
但我不确定这是否可行。
简短版:我可以使用定时器的 CNT 寄存器作为 DMA 传输源吗?它会是外围设备到内存的传输吗?还是内存到内存的传输?我需要其他标志来完成这项工作吗?还是不可能?或者是否有另一个 STM32 功能可以更轻松地计算脉冲之间的时间?
解决方案
免责声明
我必须承认,到目前为止,我在 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 的两个应用笔记:
AN4013 应用笔记。《STM32 跨系列定时器概述》,Rev.8
您的 µC 上有哪些计时器,以及哪个计时器提供了哪些功能。
AN4776 应用笔记。“用于 STM32 微控制器的通用定时器食谱”,Rev.3
如何使用您拥有的计时器。查看第 2.6 节,输入捕获在第 27 页。
查找这两个,我发现了与 HRTIM 计时器相关的第三个您可能想要检查以获得更好的精度:
推荐阅读
- javascript - 如何在谷歌脚本中获取非空白单元格的范围
- sql - 对相同值使用 SQL case 语句时结果的不同行
- mongodb - 最适合实时存储时间序列数据的解决方案
- oracle - INNER JOIN 两个表得到错误 SQL 语句没有正确结束
- asp.net - 我可以更改我的逻辑应用程序的 Aspnet 版本吗?
- scala - Akka - 如何检索对分片区域中实体的子角色的引用?
- linux - 使用 shell 脚本获取多行 XML 中的标记值
- php - 如何提供基于 2 个数组的文本框列表和文件输入文本框
- python - 如何从弹性搜索查询中获得准确的搜索结果
- r - 编写一个函数返回一个对应的值