AnsweredAssumed Answered

input capture pwm input mode precision

Question asked by carpenter.andrew.001 on Mar 17, 2014
Latest reply on Mar 17, 2014 by carpenter.andrew.001
Hello,
    I am writing code to capture an incoming square wave frequency.  Here is my initialization code:
TIM_ICInitTypeDef  TIM_ICInitStructure;
  GPIO_InitTypeDef GPIO_InitStructure;
  NVIC_InitTypeDef NVIC_InitStructure;
 
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE);
 
  // GPIOB clock enable
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
   
  GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_1;
  GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP ;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
   
  // Connect TIM pin to AF2
  GPIO_PinAFConfig(GPIOA, GPIO_PinSource1, GPIO_AF_TIM5);
 
  NVIC_InitStructure.NVIC_IRQChannel = TIM5_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
   
  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_DIV8;
  TIM_ICInitStructure.TIM_ICFilter = 0x2;
 
  TIM_PWMIConfig(TIM5, &TIM_ICInitStructure);
 
  TIM_SelectInputTrigger(TIM5, TIM_TS_TI2FP2);
 
  /* Select the slave Mode: Reset Mode */
  TIM_SelectSlaveMode(TIM5, TIM_SlaveMode_Reset);
  TIM_SelectMasterSlaveMode(TIM5,TIM_MasterSlaveMode_Enable);
 
  /* TIM enable counter */
  TIM_Cmd(TIM5, ENABLE);
 
   
  TIM_ITConfig(TIM5, TIM_IT_CC2, ENABLE);

And here is my interrupt code:
RCC_ClocksTypeDef RCC_Clocks;
  RCC_GetClocksFreq(&RCC_Clocks);
 
  TIM_ClearITPendingBit(TIM5, TIM_IT_CC2); //perhaps changing this to cc1
 
  /* Get the Input Capture value */
  IC2Value = TIM_GetCapture2(TIM5);
 
  if (IC2Value != 0)
  {
    /* Duty cycle computation */
    DutyCycle = (TIM_GetCapture1(TIM5) * 100) / IC2Value;
 
     
 
    Frequency = (RCC_Clocks.HCLK_Frequency)/2 / IC2Value;
  }
  else
  {
    DutyCycle = 0;
    Frequency = 0;
  }

At frequencies of about 1.02 MHz, I am getting inaccurate readings, like 1.223051MHz.  Is there a way to tune this in more? or do I have to characterize it like a noisy sensor?

Thanks for your help.

Outcomes