cancel
Showing results for 
Search instead for 
Did you mean: 

Timer 8 of STM32F4 Discovery don't work !

naceur2311
Associate II
Posted on March 11, 2013 at 10:54

Hi,

I have problems with Timer 8 this time. I want to measure the frequency of an input signal. I have to use PB1 that's connected to TIM8_CH3

N

. The code seem correct but it doesn't give any frequency. The code is the following :

The main function :

int main(void)

{

    /* TIM8 Configuration */

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

  TIM_Cmd(TIM8, ENABLE);

  TIM_ITConfig(TIM8, TIM_IT_CC3, ENABLE);

  while (1);

}

void TIM_Config(void)

{

  GPIO_InitTypeDef GPIO_InitStructure;

  NVIC_InitTypeDef NVIC_InitStructure;

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM8, ENABLE);

  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, 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_NOPULL;

  GPIO_Init(GPIOB, &GPIO_InitStructure);

  GPIO_PinAFConfig(GPIOB, GPIO_PinSource1, GPIO_AF_TIM8);

  NVIC_InitStructure.NVIC_IRQChannel                   = TIM8_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 interrupt routine is :

 

void TIM8_CC_IRQHandler(void)

{

  if(TIM_GetITStatus(TIM8, TIM_IT_CC3) == SET)

  {

    TIM_ClearITPendingBit(TIM8, TIM_IT_CC3);

    if(CaptureNumber == 0)

    {

       IC3ReadValue1 = TIM_GetCapture3(TIM8);

      CaptureNumber = 1;

    }

    else if(CaptureNumber == 1)

    {

      IC3ReadValue2 = TIM_GetCapture3(TIM8);

      if (IC3ReadValue2 > IC3ReadValue1)

      {

        Capture = (IC3ReadValue2 - IC3ReadValue1);

      }

      else if (IC3ReadValue2 < IC3ReadValue1)

      {

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

      }

      else

      {

        Capture = 0;

      }

      

      TIM8Freq = (uint32_t) SystemCoreClock / Capture;

      CaptureNumber = 0;

    }

  }

}

Any help to resolve this problem.

Thanks.
12 REPLIES 12
Posted on March 11, 2013 at 14:41

You'd do better using TIM3_CH4, and defining a time base which is usable for measurement range you expect.

Capture = ((0xFFFF - IC3ReadValue1) + IC3ReadValue2); // The math here is wrong
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 12, 2013 at 09:39

Thank you clive1. My goal here is to make a Timer working with an inverted channel. I choose Channel 3N of Timer 8. I tested Channel 4 of Timer 3 and it worked.

How can i define a time base (i want to measure a signal with maximum frequency 40 Mhz )??? 
Posted on March 12, 2013 at 12:35

I honestly don't think TIM8_CH3N is a usable source here, but I'm sure interrupting the core every 4 cycles isn't at all viable. Viability there is going to top out at a few hundred KHz when the core becomes saturated.

What you need to do is use the external input of the timer to clock it, and then sample it at defined intervals, perhaps with a DMA initiated read of TIMx->CNT, or gated via another timer.

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 12, 2013 at 12:57

I will try to connect an external oscillator to the Timer to allow it capture higth frequencies. 

johny600
Associate
Posted on March 26, 2013 at 13:36

Dear Clive1

I'm using TIM5 timer to measure the LSI frequency as the LSI is internally connected to TIM5 CH4. The TIM5 Input Capture interrupt is enabled after one cycle of LSI clock (rising edge),

Would you mind explaining this equation in interrupt service function:

...

else

if

(IC4ReadValue2 < IC4ReadValue1)

{

Capture = ((0xFFFF - ICReadValue1) + ICReadValue2);

}...

Condition:

 

if

(IC4ReadValue2 > IC4ReadValue1)

{

Capture = (IC4ReadValue2 - IC4ReadValue1);

}

is clear. But,why (0xFFFF - ICReadValue1) + ICReadValue2 ???

Function:

void

TIM5_IRQHandler(

void

)

{

    if

(TIM_GetITStatus(TIM5, TIM_IT_CC4) ==

SET

)

    {

      

/* Clear TIM5 Capture compare interrupt pending bit */

       

TIM_ClearITPendingBit(TIM5, TIM_IT_CC4);

      

if

(CaptureNumber == 0)

       {

        

/* Get the Input Capture value1 */

      

IC4ReadValue1 = TIM_GetCapture4(TIM5);

       CaptureNumber = 1;

        }

      

else

if

(CaptureNumber == 1)

       {

       

/* Get the Input Capture value2 */

        

IC4ReadValue2 = TIM_GetCapture4(TIM5);

      

/* Capture computation */

         

if

(IC4ReadValue2 > IC4ReadValue1)

          {

              Capture = (IC4ReadValue2 - IC4ReadValue1);

           }

          else

if

(IC4ReadValue2 < IC4ReadValue1)

          {

              Capture = ((0xFFFF - ICReadValue1) + ICReadValue2);

           }

          

else

 

          {

              Capture = 0;

          }

/* Frequency computation */

TIM5Freq = (

uint32_t

)SystemCoreClock / Capture;

Capture = 0;

      }

   }

}

Thank you in advance,

joe

Posted on March 26, 2013 at 15:03

Would you mind explaining this equation in interrupt service function:

It was written by someone who doesn't fully understand wrapping issues with 16-bit unsigned numbers.

It attempts to measure the delta of two timer readings where the counter wrapped between measurements, and it FAILS to do it properly.

The purpose of the interrupt routine is to count the number of ticks from the faster clocks that occur during the period of the slower clock.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
johny600
Associate
Posted on March 26, 2013 at 21:46

Thanks Clive1, I wasn't sure about wrapping this counter. The rest is clear.

Regards,

joe

ppatel
Associate
Posted on July 10, 2015 at 21:01

Hi, 

I am using input capture function of timer for frequency measurement. When I connect the frequency up to 1MHz on the timer pin it shows right frequency. But when i set 4 MHz frequency, it is showing 8MHz. My configuration is as below.

void MX_TIM8_Init(void)

{

  TIM_MasterConfigTypeDef sMasterConfig;

  TIM_IC_InitTypeDef sConfigIC;

  htim8.Instance = TIM8;

  htim8.Init.Prescaler = 0;

  htim8.Init.CounterMode = TIM_COUNTERMODE_UP;

  htim8.Init.Period = 65535;

  htim8.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;

  htim8.Init.RepetitionCounter = 0;

  HAL_TIM_IC_Init(&htim8);

  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;

  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;

  HAL_TIMEx_MasterConfigSynchronization(&htim8, &sMasterConfig);

  sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING;

  sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI;

  sConfigIC.ICPrescaler = TIM_ICPSC_DIV1;

  sConfigIC.ICFilter = 0;

  HAL_TIM_IC_ConfigChannel(&htim8, &sConfigIC, TIM_CHANNEL_2);

}

void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)

{

  if(Capturenumber == 0)

      {

        counter = HAL_TIM_ReadCapturedValue(&htim8,TIM_CHANNEL_2);

        Capturenumber =1;

        

      }

    else if(Capturenumber == 1)  //Treatment of second capture

      {

time = HAL_TIM_ReadCapturedValue(&htim8,TIM_CHANNEL_2);

if(time>counter)

        {

        time = time - counter;

        }

        else if(time<counter)

        {

          time = ((0xffff - counter)+time);

        }

        else

        {

time = 0;

        }

freq= (uint32_t)sysclk/time;  //Calculation of frequency

        Capturenumber=0;

      }

}

Can you please suggest me where I am doing mistak??

Thanks,

Pankil

Posted on July 10, 2015 at 21:19

Can you please suggest me where I am doing mistake??

I guess it starts by believing you can interrupt at a 4 MHz rate?

At rates that would saturate the processor a more realistic approach would be to count the cycles over an integration period. ie use external count mode.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..