cancel
Showing results for 
Search instead for 
Did you mean: 

Input capture timer - measure the correct frequency

mfcprog
Associate II
Posted on April 17, 2012 at 15:01

Hi,

I want to capture a signal with 30Hz frequency by a timer input capture. The timer is already working but the measured frequency is not 30Hz. I always measure a frequency of 29.85Hz or 30.3Hz. Are there any mistakes according to may selected period or prescaler values? By the way I`m using the STM32F103XC processor.

void TIMER_InitInputCaptureTimer(TIM_TypeDef* TIMx, unsigned short tmrchannel, unsigned short period)

{

  TIM_ICInitTypeDef  TIM_ICInitStructure;

 TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;

 unsigned short PrescalerValue = (unsigned short) (SYSTEM_TIMERCLOCK / TIMER_TAKT) - 1;

 TIM_TimeBaseStructure.TIM_Period       = period -1; //65535;

   TIM_TimeBaseStructure.TIM_Prescaler     = (TIMER_TAKT - 1); //0;

   TIM_TimeBaseStructure.TIM_ClockDivision    = 0;

   TIM_TimeBaseStructure.TIM_CounterMode     = TIM_CounterMode_Up;

   TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;

    TIM_TimeBaseInit(TIMx, &TIM_TimeBaseStructure);

 TIM_PrescalerConfig(TIMx, PrescalerValue, TIM_PSCReloadMode_Immediate);

 TIM_ICInitStructure.TIM_Channel = tmrchannel; //TIM_Channel_3;

   TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;

   TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;

   TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;      // Div:1, every edge

   TIM_ICInitStructure.TIM_ICFilter = 0x3;

   TIM_ICInit(TIMx, &TIM_ICInitStructure);

 /* Enable the CC3 Interrupt Request */

   TIM_ClearITPendingBit(TIM1, tmrchannel); //TIM_IT_CC3);

 TIM_ITConfig(TIMx, tmrchannel, ENABLE);

}

void TIMER_Init(TIM_TypeDef* TIMx, unsigned char mode, unsigned short tmrchannel, unsigned char irqchannel,

 unsigned short period, unsigned short fps)

{

 NVIC_InitTypeDef NVIC_InitStructure;

 switch(mode)

 {

 case TMR_MODE_UPD:

  TIMER_InitUpdTimer(TIMx, tmrchannel, fps);

  break;

 case TMR_MODE_INPUTCAPTURE:

  TIMER_InitInputCaptureTimer(TIMx, tmrchannel, period);

  break;

 default:

  return;

 }

 

 

 NVIC_InitStructure.NVIC_IRQChannel = irqchannel; //TIM1_CC_IRQChannel;

   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;

   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

   NVIC_Init(&NVIC_InitStructure);

}

And that`s my call of the timer function:

volatile unsigned short IC3ReadValue1 = 0, IC3ReadValue2 = 0;

volatile unsigned short CaptureNumber = 0;

volatile unsigned int Capture = 0;

volatile unsigned int TIM1Freq = 0; 

int d2i(float d)

{

 float value;

 value = d;

 value /= 10;

 value += 0.5;

 return value;

}

TIMER_Init(TIM1, TMR_MODE_INPUTCAPTURE, TIM_Channel_3, TIM1_CC_IRQChannel, 64800, 0);

TIM_Cmd(TIM1, ENABLE);

My Interrupt ISR:

void TIM1_CC_IRQHandler (void)

{

   TIM1->SR & TIM_IT_CC3)

 {  /* capture timer */

    

  //clear pending bit

  TIM1->SR = (unsigned short)~TIM_FLAG_CC3;

  if(CaptureNumber == 0)

     {

       /* Get the Input Capture value */

       IC3ReadValue1 = TIM1->CCR3;

       CaptureNumber = 1;

     }

  else if(CaptureNumber == 1)

     {

       /* Get the Input Capture value */

       IC3ReadValue2 = TIM1->CCR3;

       /* Capture computation */

       if (IC3ReadValue2 > IC3ReadValue1)

       {

         Capture = (IC3ReadValue2 - IC3ReadValue1);

       }

       else

       {

         Capture = ((0xFFFF - IC3ReadValue1) + IC3ReadValue2);

       }

       /* Frequency computation */

    TIM1Freq =  d2i ((float)(2 * TIMER_TAKT * 10 / Capture));

          CaptureNumber = 0;

   }

  /* flag: new rising edge interrupt INTR received */

  captureFlag++;

 /* clear all flags */   

 TIM1->SR = ~0xFF;  

 }

}

I hope someone of you could give me some hints to measure the exact frequency of the input signal.

best regards

Hans
10 REPLIES 10
Cesar cfg
Associate II
Posted on February 28, 2013 at 08:09

Hi Clive: 

After searching in the NET i found this example but also we have a problem the results are not Ok .

the code:

  TIM_DeInit(TIM3 );

 /* TIM3 clock enable */

 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);

 /* GPIOC clock enable */

 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOD, ENABLE);

 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9;

 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;

 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;

 GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;

 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;

 GPIO_Init(GPIOC, &GPIO_InitStructure);

GPIO_PinAFConfig(GPIOC, GPIO_PinSource6, GPIO_AF_0 );

GPIO_PinAFConfig(GPIOC, GPIO_PinSource7, GPIO_AF_0 );

 GPIO_PinAFConfig(GPIOC, GPIO_PinSource8, GPIO_AF_0 );

 GPIO_PinAFConfig(GPIOC, GPIO_PinSource9, GPIO_AF_0 );

 /* Enable capture*/

 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_ICInitStructure.TIM_ICFilter = 0;

 TIM_ICInit(TIM3, &TIM_ICInitStructure);

 TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;

 TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Falling;

 TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;

 TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;

 TIM_ICInitStructure.TIM_ICFilter = 0;

 TIM_ICInit(TIM3, &TIM_ICInitStructure);

 TIM_ICInitStructure.TIM_Channel = TIM_Channel_3;

  TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;

 TIM_ICInit(TIM3, &TIM_ICInitStructure);

 TIM_ICInitStructure.TIM_Channel = TIM_Channel_4;

  TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Falling;

 TIM_ICInit(TIM3, &TIM_ICInitStructure);

 /* Enable TIM3 */

 TIM_Cmd(TIM3, ENABLE);

 /* Enable CC1-4 interrupt */

 TIM_ITConfig(TIM3, TIM_IT_CC1 | TIM_IT_CC2 | TIM_IT_CC3 | TIM_IT_CC4, ENABLE);

 /* Clear CC1 Flag*/

 TIM_ClearFlag(TIM3, TIM_FLAG_CC1 | TIM_FLAG_CC2 | TIM_FLAG_CC3 | TIM_FLAG_CC4 );

    

   NVIC_InitStructure.NVIC_IRQChannel =  TIM3_IRQn;

   NVIC_InitStructure.NVIC_IRQChannelPriority=2;

   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

   NVIC_Init(&NVIC_InitStructure);

}

 void TIM3_IRQHandler() 

{

  TIM_ICInitTypeDef                       TIM_ICInitStructure;

 if (TIM3 ->SR & TIM_IT_CC1 ) {

  TIM3 ->SR &= (~TIM_IT_CC1 );

  if (pulseState == 0) {

   TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Falling;

   // Any time we get a rising edge on CH1, we reset the counter. All channels are

   // phase aligned, so they all use this as a reference.

   TIM_SetCounter(TIM3,0);

  } 

  else 

  {

   TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;

   // Pull the value on the falling edge.

   ccr[0] = TIM_GetCapture1(TIM3 );

  }

  pulseState = !pulseState;

  // Reverse polarity.

  TIM_ICInit(TIM3, &TIM_ICInitStructure);

 }

 if (TIM3 ->SR & TIM_IT_CC2 )

 {

  TIM3 ->SR &= (~TIM_IT_CC2 );

  ccr[1] = TIM_GetCapture2(TIM3 );

 }

 if (TIM3 ->SR & TIM_IT_CC3 )

 {

  TIM3 ->SR &= (~TIM_IT_CC3 );

  ccr[2] = TIM_GetCapture3(TIM3 );

 }

 if (TIM3 ->SR & TIM_IT_CC4 ) 

 {

  TIM3 ->SR &= (~TIM_IT_CC4 ); 

  ccr[3] = TIM_GetCapture4(TIM3 );

 }

}