我用的是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特性可以使计算脉冲之间的时间更容易呢?
发布于 2020-04-15 10:40:48
免责声明
我必须承认,到目前为止,我在STM32方面的长期实践经验一直停留在主流控制器家庭,如STM32F0、STM32F3、STM32F4和STM32L4。因此,我是根据那些控制器在你的情况下会给你提供什么来回答的。STM32H7系列要强大得多,更不用说它还提供了一些附加的DMA技术,如DMA2D、MDMA和许多我不确定的东西。但我认为一个简化的答案也可能对你有帮助,所以我敢写它。
我可以使用计时器的CNT寄存器作为DMA传输源吗?会是外设到内存的传输吗?还是从记忆到记忆的转移?我还需要其他旗帜才能让这件事成功吗?还是说不可能?
我希望这能奏效。我看不出有什么理由不在DMA传输中读取TIMx_CNT寄存器。
CNT寄存器绝对是一个外围地址,所以您必须将它配置为外设到内存的传输。我认为,外设/内存分离是指DMA控制器从每一个STM32中实现的总线矩阵中获取数据(或从它传递数据的总线)的总线。
还是有另一个STM32特性可以使计算脉冲之间的时间更容易呢?
是的,有:许多TIM外围设备(并不都是相同的)为您提供了一个名为“输入捕获”的功能,它将TIM实例的通道(子)外围设备连接到输入端,并具有(相同的!)蒂姆外围做内部时钟。前提是,您想要测量的引脚有一个TIMx_CHy备用函数,而不是“仅”一个TIMx_ETR函数。
TIM外围设备提供了丰富的各种不同配置选项--只要您还不习惯,就会有复杂的混乱。作为一个介绍和一个很好的概述,我推荐来自ST的两个申请说明:
查找这两个,我找到了第三个您可能需要检查的更好的精度,与HRTIM计时器相关:
发布于 2021-08-17 02:14:43
使用STM32CubeIDE配置器很容易做到:
下面是一个示例:
#define TIM_BUFFER_SIZE 128
uint32_t timerCaptureBuffer[TIM_BUFFER_SIZE];
uint32_t timerCaptureBufferSafe[TIM_BUFFER_SIZE];
// ...
HAL_DMA_RegisterCallback(&hdma_memtomem_dma2_stream2,
HAL_DMA_XFER_CPLT_CB_ID,
myDMA_Callback22);
// ...
HAL_TIM_IC_Start_DMA(&htim2, TIM_CHANNEL_1, uint32_t*)timerCaptureBuffer,TIM_BUFFER_SIZE);
// ...
void HAL_TIM_IC_CaptureHalfCpltCallback(TIM_HandleTypeDef *htim)
{
HAL_DMA_Start_IT(&hdma_memtomem_dma2_stream2,
(uint32_t)&timerCaptureBuffer[0],
(uint32_t)&timerCaptureBufferSafe[0],
sizeof(timerCaptureBuffer)/2/4);
// ...
}
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
HAL_DMA_Start_IT(&hdma_memtomem_dma2_stream2,
(uint32_t)&timerCaptureBuffer[TIM_BUFFER_SIZE/2],
(uint32_t)&timerCaptureBufferSafe[TIM_BUFFER_SIZE/2],
sizeof(timerCaptureBuffer)/2/4);
// ...
}
void myDMA_Callback22(DMA_HandleTypeDef *_hdma)
{
//...
}
https://stackoverflow.com/questions/61177322
复制相似问题