cancel
Showing results for 
Search instead for 
Did you mean: 

Timer setup to measure the time between 2 events using Input Capture

Grozea.Ion
Associate II

Hello all,

On and STM32F722 I am measuring the speed of an object that is passing between 2 photogates using external interrupts.

I would like to automate the time measure using Input Capture direct mode on channel 3 and 4 of timer 4, however I do not know how to setup TIM4 in order to start the timer when CH3 is triggered and to stop it when CH4 is triggered.

Can anyone guide me?

Thank you.

5 REPLIES 5

You can't.

Only CH1 and CH2 are inputs to slave-mode controller, and that can only stay the time, not stop it (it can gate, but that's not what you want anyway).

Use DMA to store captured values to memory, for to be processed later.

JW

Hello Jan,

Thank you for your quick reply.

On my board I can also use TIM2 or 5 CH1/2.

Can you offer more details (step by step) on how to use your solution?

With CH1/CH2, you can use a similar trick than what's described in "PWM input" in RM: use CH1 as input to slave-mode controller set to Reset mode, and then CH2 captures the difference between the two channels, so that you'll find the result in TIMx_CCR2. Note, that there's an undocumented small (couple of cycles) delay between CH1 capture event and the reset, so the result will be a bit smaller than the actual time difference.

What I was mentioning above was to trigger DMA transfer by CH2 (or CH4 in the previous case), which would use the DMAR/DCR mechanism to transfer both CCR3 and CCR4 into memory, and that would be then processed any time later. This is more complicated than the above mentioned method.

JW

Thank you for your reply Jan.

I have looked in to RM0431 chapter 19.3.6 and unfortunately i am not able to figure this out.

Is it possible to provide me the configuration code for TIM2?

I know I am asking too much, but this set up is above my skills.

Hi,

I came up with the code below

#include "stm32f7xx_hal.h"
 
// Global variables
TIM_HandleTypeDef htim2;
uint32_t time_interval = 0;
 
// TIM2 Initialization Function
void TIM2_Init(void)
{
  TIM_MasterConfigTypeDef sMasterConfig = {0};
  TIM_IC_InitTypeDef sConfigIC = {0};
 
  htim2.Instance = TIM2;
  htim2.Init.Prescaler = 0;
  htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim2.Init.Period = 0xFFFFFFFF;
  htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  HAL_TIM_IC_Init(&htim2);
 
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig);
 
  sConfigIC.ICPolarity = TIM_ICPOLARITY_FALLING;
  sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI;
  sConfigIC.ICPrescaler = TIM_ICPSC_DIV1;
  sConfigIC.ICFilter = 0;
  HAL_TIM_IC_ConfigChannel(&htim2, &sConfigIC, TIM_CHANNEL_1);
 
  sConfigIC.ICPolarity = TIM_ICPOLARITY_FALLING;
  sConfigIC.ICSelection = TIM_ICSELECTION_INDIRECTTI;
  sConfigIC.ICPrescaler = TIM_ICPSC_DIV1;
  sConfigIC.ICFilter = 0;
  HAL_TIM_IC_ConfigChannel(&htim2, &sConfigIC, TIM_CHANNEL_2);
}
 
// Function to get the time interval
uint32_t get_time_interval(void)
{
  // Wait for both capture events to occur
  // A free falling water droplet takes about 0.11s to pass through photogates
  // from stand still - the slowest situation
  // The Timer will overflow after 19.2s
  // To Do
  // If nothing is detected in 1s exit the loops
  while ((TIM2->SR & TIM_SR_CC1IF) == 0) {}
  while ((TIM2->SR & TIM_SR_CC2IF) == 0) {}
 
  // Calculate time interval and return
  time_interval = TIM2->CCR2 - TIM2->CCR1;
  return time_interval;
}
 
int main(void)
{
  
  // Initialize TIM2
  TIM2_Init();
 
  // Start the timer and disable all interrupts
  __disable_irq();
  HAL_TIM_IC_Start(&htim2, TIM_CHANNEL_1);
 
  // Wait for user input or some other event to occur
  // ...
 
  // Get the time interval and enable interrupts
  uint32_t interval = get_time_interval();
  __enable_irq();	
  // Do something with the interval
  // ...
 
  while (1)
  {
    // ...
  }
}