目的:我们希望在 STM32H723 平台上以 DMA 模式实现定时器输入捕获,而不中断 当前问题:使用 Cube MX 配置相关参数,只使用 TIM4 的 CH2 作为输入采集直接模式,Slave Mode 选择 Reset Mode,选择 TI2FP2 作为触发源,然后生成相应的代码。 频率测量已经可以了,但只会测量一次,如果外部输入频率从 1000Hz 降低到 500Hz,它只能重置程序再次全速运行以再次测量 500Hz,否则它将永远是 1000Hz。不知道问题出在哪里?我怀疑触发器源可能配置不正确?或者您是否必须同时打开 CH1 和 CH2 通道,一个直接打开,一个间接打开?相关配置请参考附件 希望能指导一下,非常感谢 |
STM32H7,0x00000000地址的内容引发hardfault
HAL库SPI DMA批量传输数据量最大为2^16,有没有办法改成上限为2^32
关于意法半导体BLE AOA测向定位的问题
关于外部事件(EXTI0)触发SPI读取数据
H7S-DK使能RTC之后,TOUCHGFX无法正常显示?
STM32H750 FDCAN发送异常
STM32H745 的 FreeRTOS 是单核工作,还是双核工作(新手题)
STM32H7A3VGT6 FLASH写不进去,用cubeprogrammer烧写程序也烧不进去
STM32H743用cubemx生成的代码无法挂载SD,帮忙看下,急!
STM32H7打开DCache后,串口1DMA接受数据位空
以上是测试内容
这个时候我们往往将测量用的TIMER配置在复位模式,被测信号通过CH1或CH2进来,
TIMER针对被测信号的上沿和下沿分别捕获,以测量周期和占空比。
实际上你这里似乎又不是,只测量信号频率,也就是说基于某个方向的边沿进行捕获就可以了。
这样的话,你可以拿定时器的任一通道做输入捕获就可以,无须使用复位从模式和采样2个通道。
让DMA工作在Normal模式,连续捕获几次,当然至少是两次。
捕获N次,可以得到N-1个数据,然后在DMA完成中断里做相应数据处理。注意,如果后面捕获的数据
比前面的数据小的话,计算的时间宽度应该是Tw=Cap2+ARR+1-CAP1.
假设计数器工作单向向上计数模式,且被测信号频率不会低于定时器计数周期的频率。否则得考虑溢出次数的统计。
在DMA完成中断里建议先停止捕获功能,调用下面函数即可。
TIM_CCxChannelCmd(TIM_TypeDef *TIMx, uint32_t Channel, TIM_CCx_DISABLE);
另外,我们可以每次在启动基于DMA方式输入捕获功能前,清理下相应捕获相关标志。比方你使用tim1-ch2做捕获。
__HAL_TIM_CLEAR_FLAG(&htim1, TIM_FLAG_CC2);
__HAL_TIM_CLEAR_FLAG(&htim1, TIM_FLAG_CC2OF);
用从模式复位也没问题吧 我是这样理解的不知道对不对:定时器的CNT一直向上计数,然后外界频率上升沿可以将CNT的值锁存值CCR2(用的CH2通道)且此时会产生输入捕获中断,我只需要在输入捕获回调函数进行计算频率即可
我今天为了简化问题尝试将DMA取消,采用定时器捕获中断进行测频
也是打开CH2,效果也是一样的,复位后只会进入一段时间输入捕获的回调函数,后面就不进入了。大佬这是为什么呢 看起来SR的状态寄存器的bit2一直是0。
TIM4 CH2做输入捕获,捕获事件触发DMA,每得到2个数据就可以计数被测试信号的频率了。
当然,我这里只是简单演示下,你要是想多取几个数据再处理也可以。
我这里配置的TIMER4工作时钟为200MHz.
开启基于ch2捕获事件的DMA传输功能。
主用户代码很简单:
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);//用来产生被测信号。
HAL_TIM_IC_Start_DMA(&htim4, TIM_CHANNEL_2, (uint32_t *)&DataBuffer0], 2);
在DMA完成中断里进行信号频率的计算:
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
uint32_t Tcircle;
uint32_t data0 = DataBuffer0];
uint32_t data1 = DataBuffer1];
uint32_t period = TIM4->ARR+1;
TIM_CCxChannelCmd(TIM4, TIM_CHANNEL_2, TIM_CCx_DISABLE);//暂时关闭CH2的捕获功能
if (data1 > data0)
{
Tcircle = data1 - data0;
}
else
{
Tcircle = data1 + period - data0;
}
Frequency = (TIM4_KER_CLK/(TIM4->PSC +1) )/ Tcircle; //计算信号频率
__HAL_TIM_CLEAR_FLAG(&htim1, TIM_FLAG_CC2);
__HAL_TIM_CLEAR_FLAG(&htim1, TIM_FLAG_CC2OF);
HAL_TIM_IC_Start_DMA(&htim4, TIM_CHANNEL_2, (uint32_t *)&DataBuffer0], 2); //重新开启捕获
}
经过验证测试,这样做是没有啥问题的,能够进行实时测量。你可以参考验证。
提醒,这里的被测信号频率不会高于用于测量的TIMER的溢出频率,否则还要考虑对溢出事件次数的统计。
是的,我已经找到了我的问题出在哪里,是因为我这个GPIO被同时初始化为输入捕获和普通IO导致
目前TIM4是16位对于低频测试给我带来了麻烦,因为本身我并不想开启定时器更新中断和输入捕获中断这样会浪费CPU资源,特别是当输入脉冲比较高时,一般我们行业应用能到100khz的