OpenEdv-开源电子网

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

定时器输入捕获,频率测试不稳定

[复制链接]

9

主题

25

帖子

0

精华

初级会员

Rank: 2

积分
81
金钱
81
注册时间
2013-8-15
在线时间
0 小时
发表于 2013-9-16 18:17:24 | 显示全部楼层 |阅读模式
 


用了定时器的输入捕获功能来测得频率,有两个中断,一个是上升沿信号中断,一个是计数器溢出中断,我现在不懂那个500 是咋回事,测着测着突然出来这么一个,每次都是实际值的一半
代码,上升沿中断和溢出中断,SystemCoreClock 24MHZ :

typedef struct StructFreqChVar{
  UINT8 _ui8mark; // 上升沿标记 0 或 1
  UINT16 _ui16overflow_counter; // 两次上升沿之间的计数器溢出数
  UINT16 _ui16overflow_old; // 第一次上升沿时计数器溢出数
  UINT32 _ui32capture_wert1; // 上一次捕获值  
UINT32 _ui32capture_wert2; // 最新一次捕获值
  UINT32 _ui32captuer_diff; // 两次捕获值差
 }StFreqCh;
 static StFreqCh timer4_Ch3;

 {
 if(TIM_GetITStatus(TIM4, TIM_IT_CC3) != RESET)
 {
  /* Clear TIM4 Capture compare interrupt pending bit */
  TIM_ClearITPendingBit(TIM4, TIM_IT_CC3);
  /* 第一个上升沿*/
  if(timer4_Ch3._ui8mark == 0)
  {
   timer4_Ch3._ui8mark =1; 
    // 第一次捕获值
   timer4_Ch3._ui32capture_wert1 = TIM_GetCapture3(TIM4) + timer4.ui16Counter_Overflow * 0x10000;
   // 记录第一次捕获时的计数器的溢出
   timer4_Ch3._ui16overflow_old = timer4.ui16Counter_Overflow;
  }
  /* 第二次捕获,之后变量_ui8mark 一直等于1,每次上升沿只在这里循环,只有当信号无效(小于0,5 Hz)时变量_ui8mark 才重新置0 */
  else if ((timer4_Ch3._ui8mark == 1) /*&& (timer4_Ch3._ui16overflow_counter < 733)*/) // 对于小于0.5 Hz的信号,两次上升沿之间的计数器溢出次数大于等于733
  {
   // 第二次捕获值
   timer4_Ch3._ui32capture_wert2 = TIM_GetCapture3(TIM4) + timer4.ui16Counter_Overflow * 0x10000;
   // 记录当下次捕获时的计数器的溢出,
   timer4_Ch3._ui16overflow_old = timer4.ui16Counter_Overflow;
   if (timer4_Ch3._ui32capture_wert2 > timer4_Ch3._ui32capture_wert1)
   {
    /* 计算两次上升沿之间的TAKT差*/
    timer4_Ch3._ui32captuer_diff = timer4_Ch3._ui32capture_wert2 - timer4_Ch3._ui32capture_wert1;
    /*小于0.5 的频率该值大于48000000,置0*/
    if (timer4_Ch3._ui32captuer_diff > 48000200)
    {
     timer4.ui32Freq_Ch3_0_01Hz = 0;
    }
    else
    {
    /* 计算频率*/
     timer4.ui32Freq_Ch3_0_01Hz = (UINT32)((uint64_t)SystemCoreClock  / (uint64_t)timer4_Ch3._ui32captuer_diff);
    }
    timer4_Ch3._ui32capture_wert1 = timer4_Ch3._ui32capture_wert2; //   新值赋给旧值,等待下一个上升沿
    timer4_Ch3._ui16overflow_old = timer4.ui16Counter_Overflow; // 记录当下计数器溢出次数
   }
   } 
 /* 溢出中断*/
 if (TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET)
 {
     /* Clear TIM4 overflow interrupt pending bit */
  TIM_ClearITPendingBit(TIM4, TIM_IT_Update);
      /*有了上升沿后上升沿标记为1,在下一个上升沿每道来之前,如果计数器溢出次数超过或等于733,那么该信号为无效信号,直接置0*/
     if (1 == timer4_Ch3._ui8mark)
   {
        /*计数器溢出次数没超过65536*/
       if ((timer4_Ch3._ui16overflow_old <= timer4.ui16Counter_Overflow) )
   {
    /*计算上次上升沿和当下的计数器溢出次数的差"*/
    timer4_Ch3._ui16overflow_counter = timer4.ui16Counter_Overflow - timer4_Ch3._ui16overflow_old;
        if (timer4_Ch3._ui16overflow_counter >= 733)
    {
     timer4.ui32Freq_Ch3_0_01Hz = 0;
     timer4_Ch3._ui8mark = 0;
    }
   }
   else
   {
    /*计数器溢出次数超过65536*/
    timer4_Ch3._ui16overflow_counter = 0xFFFFFFFF - timer4_Ch3._ui16overflow_old + timer4.ui16Counter_Overflow + 1;
    /*Wenn der Counter mehr als oder gleich 733 mals ueberlaeuft, wird der zweite Impuls nicht mehr gewartet*/
    /*同上*/
    if (timer4_Ch3._ui16overflow_counter >= 733)
    {
     timer4.ui32Freq_Ch3_0_01Hz = 0;
     timer4_Ch3._ui8mark = 0;
    }
   }
  }
     timer4.ui16Counter_Overflow++; // 计数器每次溢出自加1
 }

我知道中断里写的太多了,肿么办???

钟声咣咣响,乌鸦嘎嘎叫
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

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

使用道具 举报

10

主题

25

帖子

0

精华

初级会员

Rank: 2

积分
104
金钱
104
注册时间
2012-11-22
在线时间
5 小时
发表于 2013-9-17 09:38:38 | 显示全部楼层
你看看PWM捕获,那块在上升沿初始化计数器,ICC1上升沿捕获这不就有频率,如还要占空比可以设置ICC2就可以了我写过这个程序
感觉不错
回复 支持 反对

使用道具 举报

9

主题

25

帖子

0

精华

初级会员

Rank: 2

积分
81
金钱
81
注册时间
2013-8-15
在线时间
0 小时
 楼主| 发表于 2013-9-17 18:23:43 | 显示全部楼层

 

钟声咣咣响,乌鸦嘎嘎叫
回复 支持 反对

使用道具 举报

9

主题

25

帖子

0

精华

初级会员

Rank: 2

积分
81
金钱
81
注册时间
2013-8-15
在线时间
0 小时
 楼主| 发表于 2013-9-17 18:25:11 | 显示全部楼层
回复【3楼】hnjylijunz:
---------------------------------
谢谢回复,我试试去
钟声咣咣响,乌鸦嘎嘎叫
回复 支持 反对

使用道具 举报

9

主题

25

帖子

0

精华

初级会员

Rank: 2

积分
81
金钱
81
注册时间
2013-8-15
在线时间
0 小时
 楼主| 发表于 2013-9-17 19:48:10 | 显示全部楼层
回复【2楼】正点原子:
---------------------------------
代码有点儿长,就是设置定时期4的四个通道同时测频率,频率范围0.5到2500 Hz, 中断函数有点儿麻烦,我知道中断最好简洁些比较好,但是有些貌似不能省,譬如如果一个脉冲时间过长(大于2S)就直接置0 等等。后来改了,不用4路,只用1路,这个问题就没了,再加一路变两路,又出现这个问题了,我觉得是如果通道多了,中断要处理很多变量,CPU 就忙不过来了,造成了数据传输错误?(我猜的)
原子哥如果想测多通路,可不可以考虑DMA呢?这个想法行的通么?DMA还不太懂
钟声咣咣响,乌鸦嘎嘎叫
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165537
金钱
165537
注册时间
2010-12-1
在线时间
2117 小时
发表于 2013-9-17 21:15:43 | 显示全部楼层
回复【6楼】周小猫:
---------------------------------
有可能,你如果多路的话,很可能出现这个情况,最好的办法,就是用多个定时器了。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

1

主题

4

帖子

0

精华

新手上路

积分
32
金钱
32
注册时间
2016-8-2
在线时间
11 小时
发表于 2020-9-5 17:18:45 | 显示全部楼层
楼主问题解决了嘛?我也是遇到了这个问题
回复 支持 反对

使用道具 举报

1

主题

4

帖子

0

精华

新手上路

积分
32
金钱
32
注册时间
2016-8-2
在线时间
11 小时
发表于 2020-9-5 17:19:58 | 显示全部楼层
频率减半这个问题楼主解决了嘛?我也遇到了
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-14 13:52

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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