cancel
Showing results for 
Search instead for 
Did you mean: 

Timer 2 of STM32F4 Discovery don't work !

naceur2311
Associate II
Posted on March 02, 2013 at 22:52

Hello,

In my project i need to measure the frequency of 8 external signals with the STM32F4 Discovery Board. So i begin with the first signal by using Timer 1 in Input Capture mode and it works. Now i'm trying to do this with Timer 2 by applying the same configuration but it don't work.  

The code of Timer 1 is the following:

&sharpinclude ''stm32f4xx.h''

&sharpinclude ''stm32f4_discovery.h''

TIM_ICInitTypeDef  TIM_ICInitStructure;

void TIM_Config(void);

int main(void)

{  

  TIM_Config();

  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(TIM1, &TIM_ICInitStructure);

  TIM_Cmd(TIM1, ENABLE);

  TIM_ITConfig(TIM1, TIM_IT_CC2, ENABLE);

  while (1);

}

void TIM_Config(void)

{

  GPIO_InitTypeDef GPIO_InitStructure;

  NVIC_InitTypeDef NVIC_InitStructure;

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);

  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);

  GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_11;

  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(GPIOE, &GPIO_InitStructure);

  GPIO_PinAFConfig(GPIOE, GPIO_PinSource11, GPIO_AF_TIM1);

  NVIC_InitStructure.NVIC_IRQChannel                   = TIM1_CC_IRQn;

  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

  NVIC_InitStructure.NVIC_IRQChannelSubPriority        = 1;

  NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;

  NVIC_Init(&NVIC_InitStructure);

}

The code of the IRQHandler :

void TIM1_CC_IRQHandler(void)

{

  if(TIM_GetITStatus(TIM1, TIM_IT_CC2) == SET)

  {

    /* Clear TIM1 Capture compare interrupt pending bit */

    TIM_ClearITPendingBit(TIM1, TIM_IT_CC2);

    if(CaptureNumber == 0)

    {

      /* Get the Input Capture value */

      IC3ReadValue1 = TIM_GetCapture2(TIM1);

      CaptureNumber = 1;

    }

    else if(CaptureNumber == 1)

    {

      /* Get the Input Capture value */

      IC3ReadValue2 = TIM_GetCapture2(TIM1);

      /* Capture computation */

      if (IC3ReadValue2 > IC3ReadValue1)

      {

        Capture = (IC3ReadValue2 - IC3ReadValue1);

      }

      else if (IC3ReadValue2 < IC3ReadValue1)

      {

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

      }

      else

      {

        Capture = 0;

      }

      /* Frequency computation */

      TIM1Freq = (uint32_t) SystemCoreClock / Capture;

      CaptureNumber = 0;

    }

  }

The same code with Timer 2 is:

&sharpinclude ''stm32f4xx.h''

&sharpinclude ''stm32f4_discovery.h''

TIM_ICInitTypeDef  TIM_ICInitStructure;

void TIM_Config(void);

int main(void)

{

  TIM_Config();

  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    = 0x0;  

  TIM_ICInit(TIM2, &TIM_ICInitStructure);

  TIM_Cmd(TIM2, ENABLE);

  TIM_ITConfig(TIM2, TIM_IT_CC2, ENABLE);

  while (1);

}

void TIM_Config(void)

{

  GPIO_InitTypeDef GPIO_InitStructure;

  NVIC_InitTypeDef NVIC_InitStructure;

  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);

  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_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_TIM2);

  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);

}

The IRQHandler of Timer 2 is:

 void TIM2_IRQHandler(void)

{

  if(TIM_GetITStatus(TIM2, TIM_IT_CC2) == SET)

  {

    /* Clear TIM2 Capture compare interrupt pending bit */

    TIM_ClearITPendingBit(TIM2, TIM_IT_CC2);

    if(CaptureNumber == 0)

    {

      /* Get the Input Capture value */

      IC3ReadValue1 = TIM_GetCapture2(TIM2);

      CaptureNumber = 1;

    }

    else if(CaptureNumber == 1)

    {

      /* Get the Input Capture value */

      IC3ReadValue2 = TIM_GetCapture2(TIM2);

      /* Capture computation */

      if (IC3ReadValue2 > IC3ReadValue1)

      {

        Capture = (IC3ReadValue2 - IC3ReadValue1);

      }

      else if (IC3ReadValue2 < IC3ReadValue1)

      {

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

      }

      else

      {

        Capture = 0;

      }

      /* Frequency computation */

      TIM1Freq = (uint32_t) SystemCoreClock / Capture;

      CaptureNumber = 0;

    }

  }

}

I don't know what's wrong and what i have to do to make the Timer 2 working. 

Thanks. 

#stm32f4discovery #stm32-timer #pulse-input
17 REPLIES 17
Posted on March 03, 2013 at 01:28

Channel 3 would surely need TIM_IT_CC3

, and

TIM_GetCapture3();

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

// the math here is also bogus

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
naceur2311
Associate II
Posted on March 03, 2013 at 14:11

Thank you clive1. But i don't understand what's the relation between the number of channel and the number of 

TIM_IT_CC, and the number of 

TIM_GetCapture(). 

Also can i make 8 Timers working simultaneously to capture the different frequencies of signals ???

And the last question is, in Timers 1 and 8 i found TIM1_CH1N... So what's the meaning of the letter n, and how can i select channels ending with n in programming (note that we can only select channel1, channel2, channel3 or channel4 in programming). 

Thank you.
Posted on March 03, 2013 at 14:30

CC2 is Capture/Compare Channel 2, so absolutely useless for events occuring and relating to Channel 3, which would be CC3

The CH1N output is a inverted/complementary output of Channel 1, say you were driving an H-Bridge
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
naceur2311
Associate II
Posted on March 04, 2013 at 10:35

I tested the Timer 2 program for an input signal with 42 Khz. It works but the result is 84 Khz (2 * frequency of the input signal). I changed the parameter 

TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV

2

Now the result is correct. I don't understand exactly what's the role of 

TIM_ICPrescaler ??? Also i changed this parameter for Timer 1 and the result became incorrect. So how can i configure correctly the Prescaler to measure the real value of frequency signal ???

Thank you. 

Posted on March 04, 2013 at 13:17

You should perhaps consider the clocks driving the APB1 and APB2 buses via their dividers, and consequently the TIMx units, and the adjust the period-to-frequency computation to match?

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
m_vaccaro
Associate II
Posted on September 16, 2013 at 03:09

Hi All, I'm developing a fw for read the HC SR04 Sensor. I got the distance calculating the pulse width on digital GPIO. I wrote this fw that I get from the examples .

  if(TIM_GetITStatus(TIM1, TIM_IT_CC2) == SET)

  {

    /* Clear TIM1 Capture compare interrupt pending bit */

    TIM_ClearITPendingBit(TIM1, TIM_IT_CC2);

    if(CaptureNumber == 0)

    {

      /* Get the Input Capture value */

      IC3ReadValue1 = TIM_GetCapture2(TIM1);

      CaptureNumber = 1;

    }

    else if(CaptureNumber == 1)

    {

      /* Get the Input Capture value */

      IC3ReadValue2 = TIM_GetCapture2(TIM1);

      

      /* Capture computation */

      if (IC3ReadValue2 > IC3ReadValue1)

      {

        Capture = (IC3ReadValue2 - IC3ReadValue1);

      }

      else if (IC3ReadValue2 < IC3ReadValue1)

      {

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

      }

      else

      {

        Capture = 0;

      }

      /* Frequency computation */

      TIM1Freq = (uint32_t) SystemCoreClock / Capture;

      printf( ''IC3ReadValue2 %d \n'', IC3ReadValue2 );

      CaptureNumber = 0;

    }

  }

Now I want to calculate the duration of the pulse in millisecond.  I use a discovery stm32f4 with 8Mhz HSECLK and 168Mhx SYSCLK .

Thanks

Mik
Posted on September 16, 2013 at 12:12

Capture = ((0xFFFF - IC3ReadValue1) + IC3ReadValue2);  // The math here is still broken

For pulse width you might want to look at the PWM mode which resets the time, or a CC mode which captures both edges.

The ticks of the time base clock will be whatever you have programmed into the timer prescaler, if you understand the rate at which the clock is ticking you will know the unit of measurement, and thus the time between edges.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
m_vaccaro
Associate II
Posted on September 16, 2013 at 15:04

Thanks Clive.... an ask. Wicht are the differences between Input Capture and PWM Input? I read many documents but now I'm very confused

Mik

Posted on September 16, 2013 at 15:16

Input Capture free runs CNT, values are latched into CCRx at the prescribed edge(s)

PWM Input, as I recall, latches into CCR1/2 on alternate edges, and resets CNT at one of the edges
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..