AnsweredAssumed Answered

Frequency Capture Issue - missing pulses

Question asked by lee.paul.003 on Dec 11, 2014
Latest reply on Dec 12, 2014 by lee.paul.003
Hi,

I ma currently trying to use the timer capture to measure a burst pulse but it always seems to miss a couple of signals. I have measured it on an oscilloscope and I can see 10 pulses but from my frequency measurement using the timer capture, I only can measure 7 to 8 pulses. The timer capture code is shown below and stores the capture value into a ringbuffer (from kargs.net). In the main code, it checks if the ring buffer has any data and transmit to a serial terminal via usart dma.

Any ideas why the pulses are missing? Have I set this up correctly?

Cheers
Paul

unsigned char FreqCounter::IC2Value = 0;
RingBufAdaptor *FreqCounter::p_buffer;
 
FreqCounter::FreqCounter()
{
    RCC_Configuration();
    GPIO_Configuration();
    NVIC_Configuration();
 
    p_buffer = &ring_buffer;
 
    /* TIM2 configuration: PWM Input mode ------------------------
     The external signal is connected to TIM2 CH2 pin (PA.01),
     The Rising edge is used as active edge,
     The TIM2 CCR2 is used to compute the frequency value
    ------------------------------------------------------------ */
    TIM_ICInitTypeDef  TIM_ICInitStructure;
 
    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_ICInitStructure.TIM_ICFilter = 0x0;
 
    TIM_ICInit(TIM2, &TIM_ICInitStructure);
 
    // /* Select the TIM2 Input Trigger: TI2FP2 */
    TIM_SelectInputTrigger(TIM2, TIM_TS_TI2FP2);
 
    /* Select the slave Mode: Reset Mode */
    TIM_SelectSlaveMode(TIM2, TIM_SlaveMode_Reset);
 
    /* Enable the Master/Slave Mode */
    TIM_SelectMasterSlaveMode(TIM2, TIM_MasterSlaveMode_Enable);
 
    /* TIM enable counter */
    TIM_Cmd(TIM2, ENABLE);
 
    /* Enable the CC2 Interrupt Request */
    TIM_ITConfig(TIM2, TIM_IT_CC2, ENABLE);
}
 
unsigned int FreqCounter::get_last_frequency()
{
    if (ring_buffer.is_empty())
        return 0;
 
    return system_clock / ring_buffer.pop_front();
}
 
void FreqCounter::RCC_Configuration()
{
    /* TIM2 clock enable */
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
 
    /* GPIOA clock enable */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
}
 
void FreqCounter::GPIO_Configuration()
{
    GPIO_InitTypeDef GPIO_InitStructure;
 
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 
    GPIO_Init(GPIOA, &GPIO_InitStructure);
}
 
void FreqCounter::NVIC_Configuration()
{
    NVIC_InitTypeDef NVIC_InitStructure;
 
    /* Enable the TIM2 global Interrupt */
    NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
}
 
void FreqCounter::TIM2_IRQHandler()
{
    if (TIM_GetITStatus(TIM2, TIM_IT_CC2) == SET)
    {
        /* Clear TIM2 Capture compare interrupt pending bit */
        TIM_ClearITPendingBit(TIM2, TIM_IT_CC2);
 
        // /* Get the Input Capture value */
        IC2Value = TIM_GetCapture2(TIM2);
 
        p_buffer->put(&IC2Value);
    }
}

Outcomes