Skip to main content
gambit
Associate
March 24, 2014
Question

STM32F103R8T6 Timer4 Input Capture problem

  • March 24, 2014
  • 13 replies
  • 2300 views
Posted on March 24, 2014 at 11:17

Hi!

There is a problem with Timer4 Input Capture use.  Initially everything was developed under the STM32L100R8T6 controler, but so happened that it was necessary to pass to STM32F103R8T6. 

This code perfectly works at STM32L100:

  RCC_APB1PeriphClockCmd (RCC_APB1Periph_TIM4, ENABLE);

  TIM_TimeBaseStructInit (& timer);

  timer.TIM_Prescaler = 72 - 1;

  timer.TIM_Period = 65535;

  TIM_TimeBaseInit (TIM4, & timer);

  TIM_ICInitTypeDef timICStruct;

  timICStruct.TIM_Channel = TIM_Channel_1;

  timICStruct.TIM_ICPolarity = TIM_ICPolarity_BothEdge;

  timICStruct.TIM_ICSelection = TIM_ICSelection_DirectTI;

  timICStruct.TIM_ICPrescaler = TIM_ICPSC_DIV1;

  timICStruct.TIM_ICFilter = 0x08;

  TIM_ICInit (TIM4, & timICStruct);

  TIM_ITConfig (TIM4, TIM_IT_CC1, ENABLE);

  TIM_Cmd(TIM4, ENABLE);

 

On STM32F103 this code doesn't catch both Edges, works similarly with RisingEdge.

Help to solve a problem, or describe how ''on the fly'' to change Edges.

Thanks in advance.
    This topic has been closed for replies.

    13 replies

    Tesla DeLorean
    Guru
    March 24, 2014
    Posted on March 24, 2014 at 13:46

    What is the speed of the input signal you are trying to measure.

    Can you provide the code that initializes/configures the pins.
    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
    gambit
    gambitAuthor
    Associate
    March 24, 2014
    Posted on March 24, 2014 at 14:07

    I tried different speeds, at present I use frequency 125kHz (4uS it is long an impulse \8uS the period)

    At this stage frequency is generated by the timer 3. I see Osciloscope 125kHz, everything is right.

    /*Enable or disable APB2 peripheral clock */

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);

    /*Configure GPIO pin */

    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6;

    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;

    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_Init(GPIOB, &GPIO_InitStruct);

        

    //Configure TIMER3 PWM 125kHz

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);

    TIM_TimeBaseStructInit(&timer);

    timer.TIM_Prescaler = 288 - 1  ;//SystemCoreClock/250000 - 1;

    timer.TIM_Period = 1;

    TIM_TimeBaseInit(TIM3, &timer);

    TIM_OCStructInit(&OCtimer);

    OCtimer.TIM_Pulse = 1;

    OCtimer.TIM_OCMode = TIM_OCMode_PWM1;

    OCtimer.TIM_OutputState = TIM_OutputState_Enable;

    TIM_OC1Init(TIM3, &OCtimer);

    TIM_Cmd(TIM3, ENABLE);

    void TIM4_IRQHandler(void)

    {

        if (TIM_GetITStatus(TIM4, TIM_IT_CC1) != RESET)

        {

            TIM_ClearITPendingBit(TIM4, TIM_IT_CC1);

        if(TIM_GetCapture1(TIM4) > oldCapt)

        {

        Capt = TIM_GetCapture1(TIM4) - oldCapt;

        }

        else

        {

        Capt = 0x10000 - oldCapt;

    }

         oldCapt = TIM_GetCapture1(TIM4);

            CurrLevel = GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_6);

    }

    }

    I use STM Studio for capture of values of variables in real time. And the Capt variable is always equal 8. And the CurrLevel variable is equal 1.

    Mysticism any.

    Tesla DeLorean
    Guru
    March 24, 2014
    Posted on March 24, 2014 at 14:27

    I think you need to get rid of the prescalers, if the period will fit in 16-bit use that. The larger factor should always go into the Period

    Also get rid of the IC_Filter (= 0), 8 cycles at 1 MHz (1 us)? That's like the whole period of the measured signal right?

    I would definitely read TIM_GetCapture1(TIM4) into a variable rather than reading the volatile value multiple times. Regular 16-bit unsigned math should automatically manage the wrap condition. delta = b - a; // always
    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
    gambit
    gambitAuthor
    Associate
    March 24, 2014
    Posted on March 24, 2014 at 14:39

    I made everything as you say..... result same. Capt = 8. CurrLevel = 1.

    The same occurs at TIM_ICPolarity_Rising.

    At TIM_ICPolarity_Falling Capt = 8. CurrLevel = 0

    Prompt please how it is possible to change in interruption the capture front to the opposite?

    Tesla DeLorean
    Guru
    March 24, 2014
    Posted on March 24, 2014 at 14:57

    If you set the timer prescaler to zero you wouldn't be getting 8, the period would be 576 ticks at 72 MHz, not 8 ticks a 1 MHz

    You could also use Channel 2 with the INDIRECT signal (TI1 rather than TI2), and counter phase of CH1. ie capture one edge in CCR1 and the other edge in CCR2

    PWM Input mode would also permit the direct measurement of period and duty.

    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
    gambit
    gambitAuthor
    Associate
    March 24, 2014
    Posted on March 24, 2014 at 15:13

    I didn't change timer dividers, I corrected a code in the handler of interruption. Now I will try to fasten to the channel 2. But the question that remains. Everything worked at stm32l100.

    Tesla DeLorean
    Guru
    March 24, 2014
    Posted on March 24, 2014 at 15:26

    I'd have to experiment, won't happen today.

    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
    gambit
    gambitAuthor
    Associate
    March 24, 2014
    Posted on March 24, 2014 at 15:33

    I'll be waiting

    gambit
    gambitAuthor
    Associate
    March 25, 2014
    Posted on March 25, 2014 at 10:40

    In general strange somehow, Timer3 and Timer4 sit on bus APB1, and datasheet says that bus 36MHz frequency at most. And judging by the given code and removal of oscillograms timers from 72MHz are clocked. 

    zzdz2
    Associate
    March 25, 2014
    Posted on March 25, 2014 at 18:10

    I think the problem is that in F1 series only advanced timer can catch both edges, in general timer it's only single polarity.