你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32H723使用DMA方式实现定时器输入捕获只能执行一次?

[复制链接]
XFt 提问时间:2024-11-27 20:02 / 未解决

目的:我们希望在 STM32H723 平台上以 DMA 模式实现定时器输入捕获,而不中断 当前问题:使用 Cube MX 配置相关参数,只使用 TIM4 的 CH2 作为输入采集直接模式,Slave Mode 选择 Reset Mode,选择 TI2FP2 作为触发源,然后生成相应的代码。 频率测量已经可以了,但只会测量一次,如果外部输入频率从 1000Hz 降低到 500Hz,它只能重置程序再次全速运行以再次测量 500Hz,否则它将永远是 1000Hz。不知道问题出在哪里?我怀疑触发器源可能配置不正确?或者您是否必须同时打开 CH1 和 CH2 通道,一个直接打开,一个间接打开?相关配置请参考附件 希望能指导一下,非常感谢

测试文档.pdf

收藏 评论5 发布时间:2024-11-27 20:02

举报

5个回答
XFt 回答时间:2024-11-27 20:10:19

image.png

image.png

image.png

image.png

以上是测试内容

xmshao 回答时间:2024-11-28 11:02:01
从你的设计配置来看,感觉是想要TIMER输入功能的PWM输入模式来做测量。
这个时候我们往往将测量用的TIMER配置在复位模式,被测信号通过CH1或CH2进来,
TIMER针对被测信号的上沿和下沿分别捕获,以测量周期和占空比。

rrr.png


实际上你这里似乎又不是,只测量信号频率,也就是说基于某个方向的边沿进行捕获就可以了。


这样的话,你可以拿定时器的任一通道做输入捕获就可以,无须使用复位从模式和采样2个通道。


让DMA工作在Normal模式,连续捕获几次,当然至少是两次。


捕获N次,可以得到N-1个数据,然后在DMA完成中断里做相应数据处理。注意,如果后面捕获的数据


比前面的数据小的话,计算的时间宽度应该是Tw=Cap2+ARR+1-CAP1.


假设计数器工作单向向上计数模式,且被测信号频率不会低于定时器计数周期的频率。否则得考虑溢出次数的统计。
rrr.png



在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);
XFt 回答时间:2024-11-28 20:38:55

xmshao 发表于 2024-11-28 11:02
从你的设计配置来看,感觉是想要TIMER输入功能的PWM输入模式来做测量。
这个时候我们往往将测量用的TIMER配 ...

用从模式复位也没问题吧 我是这样理解的不知道对不对:定时器的CNT一直向上计数,然后外界频率上升沿可以将CNT的值锁存值CCR2(用的CH2通道)且此时会产生输入捕获中断,我只需要在输入捕获回调函数进行计算频率即可

我今天为了简化问题尝试将DMA取消,采用定时器捕获中断进行测频

也是打开CH2,效果也是一样的,复位后只会进入一段时间输入捕获的回调函数,后面就不进入了。大佬这是为什么呢 看起来SR的状态寄存器的bit2一直是0。

12efe448cf8bb4c5e7d5a4b0b2f7ea1.jpg

xmshao 回答时间:2024-11-29 14:35:01
我这边使用STM32H743写了了测试代码,使用DMA搬运捕获数据。实现起来还是比较简单的:


TIM4 CH2做输入捕获,捕获事件触发DMA,每得到2个数据就可以计数被测试信号的频率了。
当然,我这里只是简单演示下,你要是想多取几个数据再处理也可以。

rrr.png


我这里配置的TIMER4工作时钟为200MHz.
rrr.png





开启基于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); //重新开启捕获

}

rrr.png
经过验证测试,这样做是没有啥问题的,能够进行实时测量。你可以参考验证。


提醒,这里的被测信号频率不会高于用于测量的TIMER的溢出频率,否则还要考虑对溢出事件次数的统计。
XFt 回答时间:2024-11-29 22:33:18

xmshao 发表于 2024-11-29 14:35
我这边使用STM32H743写了了测试代码,使用DMA搬运捕获数据。实现起来还是比较简单的:</p>
<p>

是的,我已经找到了我的问题出在哪里,是因为我这个GPIO被同时初始化为输入捕获和普通IO导致

目前TIM4是16位对于低频测试给我带来了麻烦,因为本身我并不想开启定时器更新中断和输入捕获中断这样会浪费CPU资源,特别是当输入脉冲比较高时,一般我们行业应用能到100khz的

所属标签

相似问题

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32Cube扩展软件包
意法半导体边缘AI套件
ST - 理想汽车豪华SUV案例
ST意法半导体智能家居案例
STM32 ARM Cortex 32位微控制器
关注我们
st-img 微信公众号
st-img 手机版