OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 6463|回复: 10

STM32两个定时器,一个用来做计数,一个用来做计时。怎么做?

[复制链接]

10

主题

39

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
312
金钱
312
注册时间
2015-12-22
在线时间
47 小时
发表于 2016-5-5 14:28:49 | 显示全部楼层 |阅读模式
15金钱
测量一段方波的频率,用定时器5来做输入捕获,当捕获到上升沿时定时器3开始计时。捕获到第50个上升沿的时候,定时器3停止计时。通过计算可以算出这段方波的频率和周期。我用两个定时器中断做,可以吗?具体应该怎么做?

最佳答案

查看完整内容[请看2#楼]

如果已经确定测量50个周期的时间,用一个定时器就可以完成了,而且可以做到很高的精度。 假设用TIM5的CH1的输入捕获功能,步骤如下。 1.事先定义变量,cp_cnt用于记录捕获次数,over_cnt用于记录溢出中断次数,cp_start,cp_end分别用于记录第一次捕获值和最后一次捕获值。 2.配置TIM5的周期参数为0xFFFF,配置CH1为输入捕获功能,使能捕获中断和溢出中断。 3.cp_cnt = 0; over_cnt = 0; 4.启动定时器TIM5。 5.while(51 != ...
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

12

主题

228

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1730
金钱
1730
注册时间
2016-3-8
在线时间
678 小时
发表于 2016-5-5 14:28:50 | 显示全部楼层
本帖最后由 adlu 于 2016-5-5 18:58 编辑

如果已经确定测量50个周期的时间,用一个定时器就可以完成了,而且可以做到很高的精度。

假设用TIM5的CH1的输入捕获功能,步骤如下。
1.事先定义变量,cp_cnt用于记录捕获次数,over_cnt用于记录溢出中断次数,cp_start,cp_end分别用于记录第一次捕获值和最后一次捕获值。
2.配置TIM5的周期参数为0xFFFF,配置CH1为输入捕获功能,使能捕获中断和溢出中断。
3.cp_cnt = 0; over_cnt = 0;
4.启动定时器TIM5。
5.while(51 != cp_cnt);//等待捕获第51次。
6.if (over_cnt < 2) 50个信号周期=(cp_end - cp_start)*TIM5的计数周期 ;
  else 50个信号周期=(cp_end - cp_start)*TIM5的计数周期 +  (over_cnt - 1) * 65536 *TIM5的计数周期 ;

在捕获中断中,
{
  cp_cnt++;
  if(1 == cp_cnt) cp_start = TIM5->CCR1;
  if(51 == cp_cnt) {
    cp_end = TIM5->CCR1;
    关闭TIM5;
  }
}
在溢出中断中,
{
  over_cnt++;
}
有两点需要注意:
1.cp_end,cp_start都是U16型数据,且(cp_end - cp_start)在上述计算中,不需要考虑溢出问题。
2.over_cnt>=2,才需要把溢出的时间计算在内。

标准100kHz的信号,其周期是10us,50个周期是500us。
用上述方法测量,如果TIM5的计数时钟是1MHz,则绝对误差是1us,精度就是0.2%;
如果TIM5的计数时钟是10MHz,绝对误差是0.1us,精度就提高到0.02%了。

如果要再提高测量精度,则将50个周期改为100个或者更多即可。
回复

使用道具 举报

8

主题

51

帖子

0

精华

初级会员

Rank: 2

积分
134
金钱
134
注册时间
2016-3-11
在线时间
47 小时
发表于 2016-5-5 14:51:42 来自手机 | 显示全部楼层
这个因该比较难吧,我教你一种方法,用定时器二计数,定时器三做一个一秒定时器,一秒产生中断,读出定时器二的值就是频率
回复

使用道具 举报

10

主题

39

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
312
金钱
312
注册时间
2015-12-22
在线时间
47 小时
 楼主| 发表于 2016-5-5 14:58:56 | 显示全部楼层
031441229 发表于 2016-5-5 14:51
这个因该比较难吧,我教你一种方法,用定时器二计数,定时器三做一个一秒定时器,一秒产生中断,读出定时器 ...

我就是这样做的!可是老板说这样测量精度不够高,如果出现频率有小数的情况结果误差就很明显。所以让我用读取50个脉冲来看用时多长时间,这样做就可以提高精度了。
回复

使用道具 举报

10

主题

39

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
312
金钱
312
注册时间
2015-12-22
在线时间
47 小时
 楼主| 发表于 2016-5-5 15:42:08 | 显示全部楼层
yklstudent 发表于 2016-5-5 15:38
频率不高为什么不用CPP捕捉方式呢?

没用过啊!完全不了解!
回复

使用道具 举报

12

主题

228

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1730
金钱
1730
注册时间
2016-3-8
在线时间
678 小时
发表于 2016-5-5 17:59:03 | 显示全部楼层
果断使用定时器输入捕获功能。

可以看看这个帖,应该可以给你点启发。
http://www.openedv.com/thread-72311-1-1.html
回复

使用道具 举报

10

主题

39

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
312
金钱
312
注册时间
2015-12-22
在线时间
47 小时
 楼主| 发表于 2016-5-9 09:10:52 | 显示全部楼层
本帖最后由 1428562873 于 2016-5-9 10:31 编辑
adlu 发表于 2016-5-5 14:28
如果已经确定测量50个周期的时间,用一个定时器就可以完成了,而且可以做到很高的精度。

假设用TIM5的CH ...

这么做确实可以得出精确的频率。我算了一下精度很高误差不到千分之一。不过我的预装载值不是65536,而是换成了1000.如果是用65536的话好像误差很大,而且在接收到50个上升沿就关毕中断5这样做会使得只能测量一次频率,如果频率变化的话就需要手动重启一次才能测量,不是很方便啊。这个可以改进吗?
回复

使用道具 举报

12

主题

228

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1730
金钱
1730
注册时间
2016-3-8
在线时间
678 小时
发表于 2016-5-9 11:42:29 | 显示全部楼层
本帖最后由 adlu 于 2016-5-9 11:44 编辑
1428562873 发表于 2016-5-9 09:10
这么做确实可以得出精确的频率。我算了一下精度很高误差不到千分之一。不过我的预装载值不是65536,而是 ...

预装载值是0xFFFF,即65535,不是65536。对于16bit寄存器,65536等于0。
如果你用的把预装载值改为1000,那么出现溢出的时候,测量值的计算就不是步骤6那样了。把预装载值设置成0xFFFF是有用意的,请LZ慢慢分析出现一次溢出和多次溢出时的处理方法。

我上面提供的是一次测量的基本思路,要改成循环测量,把步骤3~6放到while(1)中就OK了。
回复

使用道具 举报

10

主题

39

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
312
金钱
312
注册时间
2015-12-22
在线时间
47 小时
 楼主| 发表于 2016-5-11 14:21:24 | 显示全部楼层
adlu 发表于 2016-5-9 11:42
预装载值是0xFFFF,即65535,不是65536。对于16bit寄存器,65536等于0。
如果你用的把预装载值改为1000 ...

是65535,我发错了。我把预装载值改成10000,精度比较高,用65535的话误差有8%左右。
你说的“启动定时器TIM5”具体是什么意思,我按照你说的试了一下,结果串口接收不到数据了。
回复

使用道具 举报

12

主题

228

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1730
金钱
1730
注册时间
2016-3-8
在线时间
678 小时
发表于 2016-5-11 18:24:33 | 显示全部楼层
1428562873 发表于 2016-5-11 14:21
是65535,我发错了。我把预装载值改成10000,精度比较高,用65535的话误差有8%左右。
你说的“启动定时 ...

我只能把思路告诉你,具体的细节操作得自己完成。

启动定时器就是让它运行,CNT能自增。
定时器TIM5可以一直运行,只需要控制测量通道的捕获中断就可以了。

TIM5和串口没有任何关系。
回复

使用道具 举报

10

主题

39

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
312
金钱
312
注册时间
2015-12-22
在线时间
47 小时
 楼主| 发表于 2016-5-12 13:33:59 | 显示全部楼层
本帖最后由 1428562873 于 2016-5-12 13:35 编辑
adlu 发表于 2016-5-11 18:24
我只能把思路告诉你,具体的细节操作得自己完成。

启动定时器就是让它运行,CNT能自增。

结果已经出来了!虽然不知道之前问题出在哪,但是现在问题都解决了。还有第五步应该是
if(51==cp_cnt);最后还是要非常感谢你的帮助。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-7 22:35

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表