OpenEdv-开源电子网

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

定时器4同时测量4路频率信号,串口显示采集不正确

[复制链接]

3

主题

12

帖子

0

精华

新手上路

积分
44
金钱
44
注册时间
2012-5-14
在线时间
0 小时
发表于 2012-10-12 22:46:24 | 显示全部楼层 |阅读模式

各路高手:大家好,我想用一个定时器采集四路频率信号,频率较低大概几十HZ,
现在我用定时器3产生待测信号10HZ,定时器4用来测试,结果用串口调试助手显示采集
数据不正确,时而为1HZ,时而为10HZ,帮忙看下是不是我配置问题了,谢谢!

定时器配置如下:

void TIM_Configuration(void)
{   
 //定义结构体
    GPIO_InitTypeDef GPIO_InitStructure;

 TIM_OCInitTypeDef  TIM_OCInitStructure;
 TIM_ICInitTypeDef  TIM_ICInitStructure;
 TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;


 // 使能时钟
 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);  
 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
 // GPIOA and GPIOB clock enable
 //  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
 //端口配置
 
 //TIM3 channel 1 pin (PA.06)channel 2 pin (PA.07) configuration
// GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_6|GPIO_Pin_7;
// GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
// GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
// 
// GPIO_Init(GPIOA, &GPIO_InitStructure);
 
 GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9;
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 
 GPIO_Init(GPIOB, &GPIO_InitStructure);
 
 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 GPIO_Init(GPIOA , &GPIO_InitStructure);


 TIM_DeInit(TIM4); //将TIM3设为缺省值

 TIM_TimeBaseStructure.TIM_Period = 0xffff;                                 
 //自动重装值
    TIM_TimeBaseStructure.TIM_Prescaler = 719;                                  
 //预分频值, 使TIMx_CLK=1MHz
 TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;                    
 //输入时钟不分频
 TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;                
 //向上计数
    TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);
 //根据指定的参数初始化 TIM3的时间基数单位

 //通道1
    TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;
    TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
    TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
    TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; //TIM捕获在捕获输入上每探测到一个边沿执行一次
    TIM_ICInitStructure.TIM_ICFilter = 0x0;
    TIM_ICInit(TIM4, &TIM_ICInitStructure);

 //通道2
    TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;
    TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
    TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
    TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; //TIM捕获在捕获输入上每探测到一个边沿执行一次
    TIM_ICInitStructure.TIM_ICFilter = 0x0;
    TIM_ICInit(TIM4, &TIM_ICInitStructure);

 //通道3
    TIM_ICInitStructure.TIM_Channel = TIM_Channel_3;
    TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
    TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
    TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; //TIM捕获在捕获输入上每探测到一个边沿执行一次
    TIM_ICInitStructure.TIM_ICFilter = 0x0;
    TIM_ICInit(TIM4, &TIM_ICInitStructure);

 //通道4
    TIM_ICInitStructure.TIM_Channel = TIM_Channel_4;
    TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
    TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
    TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; //TIM捕获在捕获输入上每探测到一个边沿执行一次
    TIM_ICInitStructure.TIM_ICFilter = 0x0;
    TIM_ICInit(TIM4, &TIM_ICInitStructure);
 
   

    // 使能中断
    TIM_ITConfig(TIM4, TIM_IT_CC1, ENABLE);
    TIM_ITConfig(TIM4, TIM_IT_CC2, ENABLE);
    TIM_ITConfig(TIM4, TIM_IT_CC3, ENABLE);
    TIM_ITConfig(TIM4, TIM_IT_CC4, ENABLE);
 // 清除中断标志位
 TIM_ClearITPendingBit(TIM4, TIM_IT_CC1);
 TIM_ClearITPendingBit(TIM4, TIM_IT_CC2);
 TIM_ClearITPendingBit(TIM4, TIM_IT_CC3);
 TIM_ClearITPendingBit(TIM4, TIM_IT_CC4);

 // 使能定时器
    TIM_Cmd(TIM4, ENABLE);

    //定时器3产生PWM用于测试
 TIM_TimeBaseStructure.TIM_Period = 999;
 TIM_TimeBaseStructure.TIM_Prescaler = 7199;
 TIM_TimeBaseStructure.TIM_ClockDivision = 0;
 TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; 
 TIM_TimeBaseInit(TIM3 , &TIM_TimeBaseStructure);
 
 TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
 TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
 TIM_OCInitStructure.TIM_Pulse = 500;  
 TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
 TIM_OC1Init(TIM3, &TIM_OCInitStructure);
 
 TIM_OC1PreloadConfig(TIM3 , TIM_OCPreload_Enable);
 TIM_ARRPreloadConfig(TIM3, ENABLE);
 
 // 使能 TIM 计数器
    TIM_Cmd(TIM3, ENABLE);
 
 }
中断函数:
void TIM4_IRQHandler(void)
{

  //通道1
  if(TIM_GetITStatus(TIM4, TIM_IT_CC1) == SET)
  {
     // Clear TIM3 Capture compare interrupt pending bit
    TIM_ClearITPendingBit(TIM4, TIM_IT_CC1);
    if(CC1CaptureNumber == 0)
    {
      // Get the Input Capture value
      CC1ReadValue1 = TIM_GetCapture2(TIM4);
      CC1CaptureNumber = 1;
    }
    else if(CC1CaptureNumber == 1)
    {
      // Get the Input Capture value
      CC1ReadValue2 = TIM_GetCapture2(TIM4);
     
      // Capture computation
      if (CC1ReadValue2 > CC1ReadValue1)
      {
        CC1Capture = (CC1ReadValue2 - CC1ReadValue1);
      }     
      else
      {
        CC1Capture = ((0xFFFF - CC1ReadValue1) + CC1ReadValue2);
      }
      // Frequency computation
     CC1TIM3Freq = TIM3BaseClock / CC1Capture;
  CC1CaptureNumber = 0;
  
    }
  }
  //通道2
  if(TIM_GetITStatus(TIM4, TIM_IT_CC2) == SET)
  {
     // Clear TIM3 Capture compare interrupt pending bit
    TIM_ClearITPendingBit(TIM4, TIM_IT_CC2);
    if(CC2CaptureNumber == 0)
    {
      // Get the Input Capture value
      CC2ReadValue1 = TIM_GetCapture2(TIM4);
      CC2CaptureNumber = 1;
    }
    else if(CC2CaptureNumber == 1)
    {
      // Get the Input Capture value
      CC2ReadValue2 = TIM_GetCapture2(TIM4);
     
      // Capture computation
      if (CC2ReadValue2 > CC2ReadValue1)
      {
        CC2Capture = (CC2ReadValue2 - CC2ReadValue1);
      }     
      else
      {
        CC2Capture = ((0xFFFF - CC2ReadValue1) + CC2ReadValue2);
      }
      // Frequency computation
     CC2TIM3Freq = TIM3BaseClock / CC2Capture;
  CC2CaptureNumber = 0;
  
    }
  }

 //通道3
  if(TIM_GetITStatus(TIM4, TIM_IT_CC3) == SET)
  {
     // Clear TIM3 Capture compare interrupt pending bit
    TIM_ClearITPendingBit(TIM4, TIM_IT_CC3);
    if(CC3CaptureNumber == 0)
    {
      // Get the Input Capture value
      CC3ReadValue1 = TIM_GetCapture2(TIM4);
      CC3CaptureNumber = 1;
    }
    else if(CC3CaptureNumber == 1)
    {
      // Get the Input Capture value
      CC3ReadValue2 = TIM_GetCapture2(TIM4);
     
      // Capture computation
      if (CC3ReadValue2 > CC3ReadValue1)
      {
        CC3Capture = (CC3ReadValue2 - CC3ReadValue1);
      }     
      else
      {
        CC3Capture = ((0xFFFF - CC3ReadValue1) + CC3ReadValue2);
      }
      // Frequency computation
     CC3TIM3Freq = TIM3BaseClock / CC3Capture;
  CC3CaptureNumber = 0;
  
    }
  }
 //通道4
  if(TIM_GetITStatus(TIM4, TIM_IT_CC4) == SET)
  {
     // Clear TIM3 Capture compare interrupt pending bit
    TIM_ClearITPendingBit(TIM4, TIM_IT_CC4);
    if(CC4CaptureNumber == 0)
    {
      // Get the Input Capture value
      CC4ReadValue1 = TIM_GetCapture2(TIM4);
      CC4CaptureNumber = 1;
    }
    else if(CC4CaptureNumber == 1)
    {
      // Get the Input Capture value
      CC4ReadValue2 = TIM_GetCapture2(TIM4);
     
      // Capture computation
      if (CC4ReadValue2 > CC4ReadValue1)
      {
        CC4Capture = (CC4ReadValue2 - CC4ReadValue1);
      }     
      else
      {
        CC4Capture = ((0xFFFF - CC4ReadValue1) + CC4ReadValue2);
      }
      // Frequency computation
     CC4TIM3Freq = TIM3BaseClock / CC4Capture;
  CC4CaptureNumber = 0;
  
    }
  }

}

主程序显示部分:

while (1)
  { 
      i++;
   switch(i)
   {
   case 1:
       printf("\r\n The TIM4CC1 Frequency  of input pulse is %.2fHz\r\n" , (CC1TIM3Freq));
      break;
   case 2500:
     printf("\r\n The TIM4CC2 Frequency  of input pulse is %.2fHz\r\n" , (CC2TIM3Freq));
      break;
   case 5000:
   printf("\r\n The TIM4CC3 Frequency  of input pulse is %.2fHz\r\n" , (CC3TIM3Freq));
      break;
   case 7500:
   printf("\r\n The TIM4CC4 Frequency  of input pulse is %.2fHz\r\n" , (CC4TIM3Freq));
       break;
   }
   if(i==10000)
   {
    i=0;
   }
 
  }

        

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

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

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

使用道具 举报

3

主题

12

帖子

0

精华

新手上路

积分
44
金钱
44
注册时间
2012-5-14
在线时间
0 小时
 楼主| 发表于 2012-10-15 11:25:03 | 显示全部楼层
回复【2楼】正点原子:
---------------------------------
谢谢原子大哥的提示,但我单路测试发现,CC1和CC2这两路显示正确,CC3和CC4显示不对,有时显示1,有时显示9,在测试的过程我还发现一个问题,串口显示数据更新一会儿就不动了,好像程序停下了一样,重新启动又行了,麻烦大家帮忙分析下是哪里出问题了。
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2012-10-15 12:16:19 | 显示全部楼层
貌似没看到你做溢出处理。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

3

主题

12

帖子

0

精华

新手上路

积分
44
金钱
44
注册时间
2012-5-14
在线时间
0 小时
 楼主| 发表于 2012-10-15 14:30:37 | 显示全部楼层

经过仔细检查,我发现自己犯了一个低级错误:在用捕获函数时,居然没有修改数字,四个通道都是用的TIM_GetCapture2(),还是对库函数没有理解到位呀!同时原子大哥说的溢出确实没有弄(由于我要测试的频率不高,所以没有弄,嘿嘿……),但最后我发现第三道还是不正确,而且我换用TIM3来测试时通道1好像也不正确,这会是怎么回事呀?

回复 支持 反对

使用道具 举报

8

主题

23

帖子

0

精华

初级会员

Rank: 2

积分
105
金钱
105
注册时间
2013-7-9
在线时间
5 小时
发表于 2014-7-31 11:07:39 | 显示全部楼层
楼主的4路测频率问题是否已经解决?我也在这里遇到了瓶颈,请求指导一下。

背景:
1、我同时测量4路频率信号,频率范围50~250Hz范围;
2、为了减轻单个定时器输入捕获的压力,以及减小输入捕获中断函数中不同通道之间的采集干扰,我使用定时器4的通道1和通道2,和定时器2的通道3和通道4来采集四路频率信号。

试验发现:
1、单独采集每一路频率,误差为1Hz;
2、同时采集其中的任意两路,测量频率显示一直在变化,而且变化还比较大。
请问这是什么原因造成的?
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-7-4 15:46

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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