AnsweredAssumed Answered

Help with Timer Capture Issues

Question asked by asl.sean on Nov 23, 2012
Latest reply on Nov 26, 2012 by asl.sean
Hi fellow forum mates, 

I am a student working on a new project using stm32f4 eval board. My task is to measure the frequency from 3 different sources ranging from 1000hz to 725khz. I have been trying for days using a function generator to simulate the source. 

I have no problem measuring the lower frequency however when i am measuring at higher frequency . I notice sometimes the frequency i measure is almost actually half of the input.

Any idea or solution as i am very lost.

InitTimer2(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;
 
    /* TIM2 clock enable */
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
 
    /* GPIOA clock enable */
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
 
    GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_0 ;
    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_NOPULL;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
 
    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_NOPULL;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
 
    GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_2 ;
    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_NOPULL;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
 
    GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_3 ;
    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_NOPULL;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
 
    /* Connect TIM pins to AF */
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource1, GPIO_AF_TIM2);
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource0, GPIO_AF_TIM2);
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_TIM2);
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_TIM2);
 
    /* Enable the TIM1 global Interrupt */
    NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
 
    /* Time Base configuration */
    TIM_TimeBaseStructure.TIM_Prescaler = PRESCALER;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseStructure.TIM_Period = 65535;
    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
 
    TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
 
    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 = 0x02;
 
    TIM_ICInit(TIM2, &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 = 0x02;
 
    TIM_ICInit(TIM2, &TIM_ICInitStructure);
 
    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_ICInitStructure.TIM_ICFilter = 0x02;
 
    TIM_ICInit(TIM2, &TIM_ICInitStructure);
 
    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_ICInitStructure.TIM_ICFilter = 0x02;
 
    TIM_ICInit(TIM2, &TIM_ICInitStructure);
 
    /* TIM enable counter */
    TIM_Cmd(TIM2, ENABLE);
 
}


void TIM2_IRQHandler(void) {
    GPIO_ToggleBits(GPIOD, GPIO_Pin_12);
    if(TIM_GetITStatus(TIM2, TIM_IT_CC1) == SET)
    {
 
        TIM_ClearITPendingBit(TIM2, TIM_IT_CC1);
 
        if(CaptureNumber2 == 0)
        {
            /* Get the Input Capture value */
            Timer2Read1 = TIM_GetCapture1(TIM2);
            CaptureNumber2 = 1;
        }
        else if(CaptureNumber2 == 1)
        {
            /* Get the Input Capture value */
            Timer2Read2 = TIM_GetCapture1(TIM2);
 
            /* Capture computation */
            if (Timer2Read2 > Timer2Read1)
            {
                Timer2Diff = (Timer2Read2 - Timer2Read1);
            }
            else if (Timer2Read2 < Timer2Read1)
            {
                Timer2Diff = ((0xFFFF - Timer2Read1) + Timer2Read2);
            }
            else
            {
                Timer2Diff = 0;
            }
            CaptureNumber2 = 0;//cc2
            /* Frequency computation */
            Timer2FREQ = (uint32_t) SystemCoreClock/2/ (1+PRESCALER) /Timer2Diff;
                      //save result into array
            setSensorResult(Timer2FREQ);
        }
    }
    else if(TIM_GetITStatus(TIM2, TIM_IT_CC2) == SET)
    {
 
        TIM_ClearITPendingBit(TIM2, TIM_IT_CC2);
 
        if(CaptureNumber2 == 0)
        {
            /* Get the Input Capture value */
            Timer2Read1 = TIM_GetCapture2(TIM2);
            CaptureNumber2 = 1;
        }
        else if(CaptureNumber2 == 1)
        {
            /* Get the Input Capture value */
            Timer2Read2 = TIM_GetCapture2(TIM2);
 
            /* Capture computation */
            if (Timer2Read2 > Timer2Read1)
            {
                Timer2Diff = (Timer2Read2 - Timer2Read1);
            }
            else if (Timer2Read2 < Timer2Read1)
            {
                Timer2Diff = ((0xFFFF - Timer2Read1) + Timer2Read2);
            }
            else
            {
                Timer2Diff = 0;
            }
            CaptureNumber2 = 0;//cc2
 
            /* Frequency computation */
            Timer2FREQ = (uint32_t) SystemCoreClock/2/ (1+PRESCALER) /Timer2Diff;
                       //save result into array
            Sensor::setSensorResult(Timer2FREQ);
        }
    }
    else if(TIM_GetITStatus(TIM2, TIM_IT_CC3) == SET)
    {
 
        TIM_ClearITPendingBit(TIM2, TIM_IT_CC3);
 
        if(CaptureNumber2 == 0)
        {
            /* Get the Input Capture value */
            Timer2Read1 = TIM_GetCapture3(TIM2);
            CaptureNumber2 = 1;
        }
        else if(CaptureNumber2 == 1)
        {
            /* Get the Input Capture value */
            Timer2Read2 = TIM_GetCapture3(TIM2);
 
            /* Capture computation */
            if (Timer2Read2 > Timer2Read1)
            {
                Timer2Diff = (Timer2Read2 - Timer2Read1);
            }
            else if (Timer2Read2 < Timer2Read1)
            {
                Timer2Diff = ((0xFFFF - Timer2Read1) + Timer2Read2);
            }
            else
            {
                Timer2Diff = 0;
            }
            CaptureNumber2 = 0;
 
            Timer2FREQ = (uint32_t) SystemCoreClock/2/ (1+PRESCALER) /Timer2Diff;
                       //save result into array
            Sensor::setSensorResult(Timer2FREQ);
        }
    }
 
    GPIO_ToggleBits(GPIOD, GPIO_Pin_12);
}
Appreciate all your help .

Outcomes