cancel
Showing results for 
Search instead for 
Did you mean: 

problem with pulse width measurement

Nickname4855_O
Associate II
Posted on October 29, 2015 at 23:06

Hi,

It seems there is a problem when I try the example project regarding using TIM input capture mode to measure pulse width. In example project, the both edge triggering mode is used. My question is how to set it up to make sure that the rising edge is triggered first and then trigger on falling edge. This way the difference of counter values will give correct pulse with of measured pulse signal. I am relatively new to STM32 device, could someone help to explain this?

Thanks,

--Ning 

int main(void)

{

  /*!< At this stage the microcontroller clock setting is already configured,

       this is done through SystemInit() function which is called from startup

       file (startup_stm32f0xx.s) before to branch to application main.

       To reconfigure the default setting of SystemInit() function, refer to

       system_stm32f0xx.c file

     */

    /* Initialize the TFT-LCD */

#ifdef USE_STM320518_EVAL

    STM320518_LCD_Init();

#else

    STM32072B_LCD_Init();

#endif /* USE_STM320518_EVAL */

   

    /* Clear the TFT-LCD */

    LCD_Clear(LCD_COLOR_WHITE);

     

    /* DAC Channel1 configuration */

    DAC_Config();

   

    /* COMP1 Configuration */

    COMP_Config();

   

    /* TIM2 Configuration in input capture mode */

    TIM_Config();

  

  /* Infinite loop */

  while (1)

  {

    if (DisplayActive != 0)

    {

      /* Compute the pulse width in us */

      MeasuredPulse = (uint32_t)(((uint64_t) Capture * 1000000) / ((uint32_t)SystemCoreClock));

     

      /* Display measured pulse width on Glass LCD and color LCD */

      DisplayOnLCD(MeasuredPulse); 

      DisplayActive = 0;

    }

  }

}

/**

  * @brief  Configures TIM2 channel 4 in input capture mode

  * @param  None

  * @retval None

  */

static void TIM_Config(void)

{

  /* Init Structure definition */

  TIM_ICInitTypeDef TIM_ICInitStructure;

  TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;

  NVIC_InitTypeDef NVIC_InitStructure;

  /* TIM2 clock enable */

  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); 

  /* TIM2 Time base configuration */

  TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);

  TIM_TimeBaseStructure.TIM_Prescaler = 0;

  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

  TIM_TimeBaseStructure.TIM_Period = 65535;

  TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;

  TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);

  TIM_ClearFlag(TIM2, TIM_FLAG_Update);

 

  /* TIM2 Channel4 Input capture Mode configuration */

  TIM_ICStructInit(&TIM_ICInitStructure);

  TIM_ICInitStructure.TIM_Channel = TIM_Channel_4;

  /* TIM2 counter is captured at each transition detection: rising or falling edges (both edges) */

  TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_BothEdge;

  TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;

  TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;

  TIM_ICInitStructure.TIM_ICFilter = 0;

  TIM_ICInit(TIM2, &TIM_ICInitStructure);

 

  /* TIM2 IRQChannel enable */ 

  NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;

  NVIC_InitStructure.NVIC_IRQChannelPriority = 0;

  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

  NVIC_Init(&NVIC_InitStructure);

 

  /* Enable capture interrupt */

  TIM_ITConfig(TIM2, TIM_IT_CC4, ENABLE);

 

  /* Enable the TIM2 counter */

  TIM_Cmd(TIM2, ENABLE);

 

  /* Reset the flags */

  TIM2->SR = 0;

}

/******************************************************************************/

/*                 STM32F0xx Peripherals Interrupt Handlers                   */

/******************************************************************************/

/**

  * @brief  This function handles TIM2 global interrupt.

  * @param  None

  * @retval None

  */

void TIM2_IRQHandler(void)

{

 

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

  {

    if (CaptureCounter == 0)

    {

      IC4Value1 = TIM_GetCapture4(TIM2);

      CaptureCounter = 1;

    }

    else if (CaptureCounter == 1)

    {

      CaptureCounter = 0;

      IC4Value2 = TIM_GetCapture4(TIM2);

      if (IC4Value2 > IC4Value1)

      {

        Capture = (IC4Value2 - IC4Value1) - 1;

      }

      else

      {

        Capture = ((0xFFFF - IC4Value1) + IC4Value2) - 1;

      }

      DisplayActive = 1;

    }

    TIM_ClearITPendingBit(TIM2, TIM_IT_CC4);

  }

}
1 REPLY 1
Posted on October 29, 2015 at 23:54

Seems to be a lot of code missing, that deals with the initialization.

The code computing the delta is wrong, probably ST's fault, but it is. Review 16-bit unsigned math.

So pair Channel 3 & 4 to capture opposite edges. Then you'll get both edges and know which one is which. CH3 would be in indirect mode.

Consider PWM Input mode on CH1 or CH2, if your design permits.

If the signal is slow enough you could read the state of the pin in the interrupt. You could also check the duty if the signal won't be 50/50

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