OpenEdv-开源电子网

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

新手发帖 分享一个定时器捕获方式测频的程序

[复制链接]

12

主题

26

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
275
金钱
275
注册时间
2014-7-2
在线时间
41 小时
发表于 2014-11-18 10:37:09 | 显示全部楼层 |阅读模式
       新手发帖,请多关照
       程序是在原子开发板的例程的基础上修改的,例程是捕获一个高电平后再捕获低电平来计算一个高电平的脉宽,我改成捕获两个高电平,测量两个高电平的时间来算频率,
另外计数的方式也修改了下,例程中捕获一个高电平后会清零计数器,下一次捕获后直接读取CCR1的值来计算时间,这种方式确实方便了溢出处理,但我在测试中发现这种方式
精度不高,数值整体偏大,测大于10KHZ的信号(信号发生器)后误差会越来越大(10K时候有2%),按道理来说1μS计数一次的方式测试10K的信号误差不会有这大,最后我发现
从1K到50K误差值整体偏大,通过计算我发现了规律,如果换算成计数器的个数值的话就很好解释了,因为实测的计数器的个数值比实际频率对应的计数器个数值要小2-3,所以造成
了测试结果的整体偏大,找到了问题就要解决,因为是整体小2-3,所以我怀疑是清零计数器造成的,我尝试去掉清零读取两次CCR1的值算差值的方式,问题解决了,测试精度显著提高
5HZ 到 20K 误差小于 千分之1   后面的误差我就没算了因为我只需要测到10K就可以。100K内的误差还是挺小的,因为定时器设置的是1μS计数,输入未分频,所以这个测试的频率不会
太高,下面附两张测试的结果和中断部分的程序。
     新人不懂版规,如有排版,文字描述不清的地方请各位多多包含,献丑了,附件中有源代码,战舰开发板可直接运行
     中断部分的程序
[mw_shl_code=c,true]//定时器5中断服务程序 void TIM5_IRQHandler(void) { if((TIM5CH1_CAPTURE_STA&0X80)==0)//还未成功捕获 { if (TIM_GetITStatus(TIM5, TIM_IT_Update) != RESET) { if(TIM5CH1_CAPTURE_STA&0X40)//已经捕获到高电平了 { if((TIM5CH1_CAPTURE_STA&0X3F)==0X3f)//高电平太长了 { TIM5CH1_CAPTURE_STA=0X80;//标记成功捕获了一次 TIM5CH1_CAPTURE_VAL=0; } else TIM5CH1_CAPTURE_STA++; } }[/mw_shl_code] [mw_shl_code=c,true] if (TIM_GetITStatus(TIM5, TIM_IT_CC1) != RESET)//捕获1发生捕获事件 { if(TIM5CH1_CAPTURE_STA&0X40) //第二次捕获到上升沿 { ReadValue2 = TIM_GetCapture1(TIM5); if ((ReadValue2 > ReadValue1)&&(TIM5CH1_CAPTURE_STA==0x40)) //无溢出 { TIM5CH1_CAPTURE_VAL = (ReadValue2 - ReadValue1); } else //有溢出 { TIM5CH1_CAPTURE_VAL = ((0xFFFF - ReadValue1) +ReadValue2); } TIM5CH1_CAPTURE_STA|=0X80; //标记成功捕获到一次上升沿 } else //第一次捕获上升沿 { ReadValue1=TIM_GetCapture1(TIM5); //TIM5CH1_CAPTURE_STA=0; //清空 TIM5CH1_CAPTURE_VAL=0; TIM5CH1_CAPTURE_STA = 0X40; //标记捕获到了上升沿 } } } TIM_ClearITPendingBit(TIM5, TIM_IT_CC1|TIM_IT_Update); //清除中断标志位 }[/mw_shl_code]
     测试信号50K


   测试信号5 Hz




      

频率测试程序.zip

6.17 MB, 下载次数: 65436

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

12

主题

26

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
275
金钱
275
注册时间
2014-7-2
在线时间
41 小时
 楼主| 发表于 2014-11-18 10:48:29 | 显示全部楼层
回复 支持 反对

使用道具 举报

86

主题

567

帖子

0

精华

高级会员

Rank: 4

积分
823
金钱
823
注册时间
2014-9-30
在线时间
139 小时
发表于 2014-11-18 11:10:41 | 显示全部楼层
学习,学习中。。。冒失问::

STM32 的 源程序 怎么 会有 6MB 呢,

其实:俺也 很困惑 :既然是 C语言:

Keil 和 IAR 编译环境 不同,居然 不能直接 使用。
回复 支持 反对

使用道具 举报

12

主题

26

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
275
金钱
275
注册时间
2014-7-2
在线时间
41 小时
 楼主| 发表于 2014-11-18 11:23:51 | 显示全部楼层
回复【3楼】caosix:
---------------------------------
C文件肯定没这大,我这是编译后的工程文件,也没关注过大小 貌似有这大吧
回复 支持 反对

使用道具 举报

120

主题

7878

帖子

13

精华

资深版主

Rank: 8Rank: 8

积分
12012
金钱
12012
注册时间
2013-9-10
在线时间
427 小时
发表于 2014-11-18 12:43:05 | 显示全部楼层
原子哥例程里面不是有这个文件么,“keilkilll.bat”将编译过程文件删掉即可
现在,程序把烂铜烂铁变得智能化了,人呢,一旦离开了这烂铜烂铁就不知道干啥了
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165536
金钱
165536
注册时间
2010-12-1
在线时间
2117 小时
发表于 2014-11-19 00:28:43 | 显示全部楼层
谢谢分享.....
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

2

主题

16

帖子

0

精华

初级会员

Rank: 2

积分
51
金钱
51
注册时间
2015-7-24
在线时间
5 小时
发表于 2015-7-24 17:03:20 | 显示全部楼层
顶一下,正好需要来找就找到了,每一位需要用AD测频率呢
回复 支持 反对

使用道具 举报

2

主题

16

帖子

0

精华

初级会员

Rank: 2

积分
51
金钱
51
注册时间
2015-7-24
在线时间
5 小时
发表于 2015-7-28 17:31:06 | 显示全部楼层
很纳闷,到底哪里出现的误差,没看懂楼主的意思
回复 支持 反对

使用道具 举报

2

主题

16

帖子

0

精华

初级会员

Rank: 2

积分
51
金钱
51
注册时间
2015-7-24
在线时间
5 小时
发表于 2015-7-28 17:41:56 | 显示全部楼层
好像明白了
if((TIM5CH1_CAPTURE_STA&0X3F)==0X3F)
{
TIM5CH1_CAPTURE_STA|=0X80;
TIM5CH1_CAPTURE_VAL=0XFFFF;
}else TIM5CH1_CAPTURE_STA++;
这里TIM5CH1_CAPTURE_STA无论怎样是要进一的,就不能是0XFFFF,而是0;
回复 支持 反对

使用道具 举报

omgkiaka 该用户已被删除
发表于 2015-7-30 10:58:01 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复 支持 反对

使用道具 举报

12

主题

21

帖子

0

精华

初级会员

Rank: 2

积分
129
金钱
129
注册时间
2015-1-12
在线时间
14 小时
发表于 2015-8-1 16:25:26 | 显示全部楼层
回复【2楼】m114714336:
---------------------------------
修改了下程序  放到mini板上到现在还不能正常显示   什么情况啊?
回复 支持 反对

使用道具 举报

1

主题

43

帖子

0

精华

初级会员

Rank: 2

积分
131
金钱
131
注册时间
2015-8-26
在线时间
20 小时
发表于 2015-9-22 00:53:45 | 显示全部楼层
感谢楼主分享!
学以致用!
回复 支持 反对

使用道具 举报

154

主题

289

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1067
金钱
1067
注册时间
2015-4-13
在线时间
189 小时
发表于 2015-9-25 19:34:55 | 显示全部楼层
看上去不错,明天修改到我的开发板上去跑跑看
回复 支持 反对

使用道具 举报

0

主题

4

帖子

0

精华

初级会员

Rank: 2

积分
144
金钱
144
注册时间
2016-3-2
在线时间
11 小时
发表于 2016-12-3 21:40:39 | 显示全部楼层
学习了    正好要这个一个程序  
回复 支持 反对

使用道具 举报

1

主题

23

帖子

0

精华

初级会员

Rank: 2

积分
145
金钱
145
注册时间
2017-1-8
在线时间
27 小时
发表于 2017-3-31 11:07:04 | 显示全部楼层
刚好用到测速,楼主及时啊
回复 支持 反对

使用道具 举报

1

主题

5

帖子

0

精华

初级会员

Rank: 2

积分
51
金钱
51
注册时间
2017-5-8
在线时间
14 小时
发表于 2017-5-28 18:22:30 | 显示全部楼层
感谢分享
回复 支持 反对

使用道具 举报

6

主题

19

帖子

0

精华

初级会员

Rank: 2

积分
117
金钱
117
注册时间
2016-7-22
在线时间
56 小时
发表于 2017-7-6 22:05:57 | 显示全部楼层
楼主,为什么我把你的程序移植到F4里,就测不了正弦波的频率了,方波还是正确的
回复 支持 反对

使用道具 举报

14

主题

73

帖子

0

精华

初级会员

Rank: 2

积分
193
金钱
193
注册时间
2016-10-27
在线时间
48 小时
发表于 2017-7-7 10:40:22 | 显示全部楼层
你好,直接在PA.0口接信号发生器给的信号就可以吗
回复 支持 反对

使用道具 举报

14

主题

73

帖子

0

精华

初级会员

Rank: 2

积分
193
金钱
193
注册时间
2016-10-27
在线时间
48 小时
发表于 2017-7-7 13:20:19 | 显示全部楼层
行的云 发表于 2017-3-31 11:07
刚好用到测速,楼主及时啊

你的可以用了吗
回复 支持 反对

使用道具 举报

25

主题

105

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
304
金钱
304
注册时间
2016-12-6
在线时间
40 小时
发表于 2017-7-28 14:21:12 | 显示全部楼层
谢谢分享
回复 支持 反对

使用道具 举报

0

主题

3

帖子

0

精华

新手入门

积分
11
金钱
11
注册时间
2017-7-3
在线时间
4 小时
发表于 2017-7-30 15:48:19 | 显示全部楼层
谢谢分享
回复 支持 反对

使用道具 举报

12

主题

25

帖子

0

精华

初级会员

Rank: 2

积分
64
金钱
64
注册时间
2017-7-19
在线时间
10 小时
发表于 2017-8-10 08:17:58 | 显示全部楼层
感谢~~
回复 支持 反对

使用道具 举报

2

主题

12

帖子

0

精华

初级会员

Rank: 2

积分
155
金钱
155
注册时间
2017-9-28
在线时间
39 小时
发表于 2018-4-11 16:00:39 | 显示全部楼层
if(Freq_ptr2>=TempLen)
  {
    for(i=0;i<TempLen;i++)
        Dtemp += Freq[i];     
    Freq_value = 10000000.0/Dtemp;
    Freq_ptr2=TempLen;
  }
  TIM5CH1_CAPTURE_STA=0;
  Overflow_ptr=0;
}
else //&#206;′2&#182;&#187;&#241;μè′y&#199;&#229;á&#227;
{
        Overflow_ptr++;
        if(Overflow_ptr>720000)
        {
         Freq_value=Freq_value/10;
         Show_flag=1;
         Overflow_ptr=0;
        }               
}
楼主你这一段程序我没有很理解,为什么不能直接用Dtemp = Dtemp-65536+TIM5CH1_CAPTURE_VAL;得到频率值而需要上面那段程序做处理
回复 支持 反对

使用道具 举报

12

主题

26

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
275
金钱
275
注册时间
2014-7-2
在线时间
41 小时
 楼主| 发表于 2018-4-28 16:04:29 | 显示全部楼层
juzzzzzz 发表于 2018-4-11 16:00
if(Freq_ptr2>=TempLen)
  {
    for(i=0;i720000)

你直接算也没问题啊,我这里是做了软件滤波的处理啊(递推平均滤波),我应该写了注释的
回复 支持 反对

使用道具 举报

2

主题

12

帖子

0

精华

初级会员

Rank: 2

积分
155
金钱
155
注册时间
2017-9-28
在线时间
39 小时
发表于 2018-5-2 09:07:22 | 显示全部楼层
m114714336 发表于 2018-4-28 16:04
你直接算也没问题啊,我这里是做了软件滤波的处理啊(递推平均滤波),我应该写了注释的

谢谢楼主回复,已经理解这段的意思了
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-9 01:16

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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