cancel
Showing results for 
Search instead for 
Did you mean: 

Measuring pulses on different pins

dstanton
Associate
Posted on June 13, 2013 at 11:43

Hello,

I am trying to measure the time between the falling edge of a pulse on one pin and the falling edge of another pulse on another pin. I am trying to do it on TIM2 channel 2 and channel 3 on an STM32F0 discovery. I can affect the time between the pulses using an external transducer, and I can see this happening on a scope, however the STM32 doesnt notice any changes, it just gives me a constant value. Im a relative newbie, and I imagine ive done/not done something really obvious thats causing this. I couldnt find any similar examples, so I modified the PWM input capture example (it was unsuitable, as each pulse width is constant, its just the distance between the two pulses that changes.)  Can anyone please advise where im going wrong? Thanks.

Here is the input capture section of my code:

 // TIM2 config: channel 1 and channel 2

  TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;

  TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Falling;

  TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;

  TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;

  TIM_ICInitStructure.TIM_ICFilter = 0;

  TIM_ICInit(TIM2, &TIM_ICInitStructure);

  TIM_ICInitStructure.TIM_Channel = TIM_Channel_3;

  TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Falling;

  TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_IndirectTI;

  TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;

  TIM_ICInitStructure.TIM_ICFilter = 0;

  TIM_ICInit(TIM2, &TIM_ICInitStructure);

  /* select the input trigger*/

  TIM_SelectInputTrigger(TIM2, TIM_TS_TI2FP2);

  /* select the slave mode: Reset Mode*/

  TIM_SelectSlaveMode(TIM2, TIM_SlaveMode_Reset);

  TIM_SelectMasterSlaveMode(TIM2, TIM_MasterSlaveMode_Enable);

  /* TIM2 Enable*/

  TIM_Cmd(TIM2, ENABLE);

  /* Enable the CC2 Interrupt Request */

  TIM_ITConfig(TIM2, TIM_IT_CC2, ENABLE);

void TIM2_IRQHandler(void)

{

  RCC_ClocksTypeDef RCC_Clocks;

  RCC_GetClocksFreq(&RCC_Clocks);

  /* Clear TIM2 Capture compare interrupt pending bit */

  TIM_ClearITPendingBit(TIM2, TIM_IT_CC2);

  /* Get the Input Capture value */

  IC2Value = TIM_GetCapture2(TIM2);

  Pulse_m = TIM_GetCounter(TIM2);

  if (IC2Value != 0)

  {

    /* Duty cycle computation */

    DutyCycle = (TIM_GetCapture1(TIM2) * 100) / IC2Value;

    /* Frequency computation*/

    Frequency = RCC_Clocks.HCLK_Frequency / IC2Value;

  }

  else

  {

    DutyCycle = 0;

    Frequency = 0;

  }

}

void TIM2_config (void){

  GPIO_InitTypeDef GPIO_InitStructure;

  NVIC_InitTypeDef NVIC_InitStructure;

  /* TIM2 clock enable */

  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

  /* GPIOA Clocks enable */

  RCC_AHBPeriphClockCmd( RCC_AHBPeriph_GPIOA, ENABLE);

  /* TIM2 channel 2 configuration : PA.00 */

  GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_1;

  GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF;

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;

  GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP ;

  GPIO_Init(GPIOA, &GPIO_InitStructure);

  /* Connect TIM pin to AF2 */

  GPIO_PinAFConfig(GPIOA, GPIO_PinSource1, GPIO_AF_2);

  /* TIM2 channel 3 configuration : PA.01 */

  GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_2;

  GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF;

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;

  GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP ;

  GPIO_Init(GPIOA, &GPIO_InitStructure);

  /* Connect TIM pin to AF2 */

  GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_2);

  /* Enable the TIM2 global Interrupt */

  NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;

  NVIC_InitStructure.NVIC_IRQChannelPriority = 0;

  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

  NVIC_Init(&NVIC_InitStructure);

}

where Pulse_m is the measurement of the time between the pulses.

1 REPLY 1
Posted on June 13, 2013 at 12:14

Yeah, I'd probably want to do a delta measurement between subsequent interrupts where CCRx had latched the current value of CNT at the input event, rather than be looking at the absolute value in CNT.

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