cancel
Showing results for 
Search instead for 
Did you mean: 

Problem with timer and input capture, timer does not run

TMalt
Associate II

Does anyone have experience with getting the timer to run with input capture, I am unable to make the input capture function.

I have a working system with STM32F03 (M0) devices initialization generated by CubeMX. Now I am testing an identical system with STM32G07 instead also initialization from CubeMX.

Same setup of timers but I am unable to make input capture work.

I am using TIM15 and PA2 input.

What I need is the timer to interrupt on both edges when input changes and I want to read out the time between edges. (Again functionallity was fine in STM32F03).

I configure counter mode as UP.

Prescale 10 and no internal clock division

Repetiotion counter is 0 and auto reload is disabled.

Polarity selection as both edges.

IC selection direct

No input filter (0)

To me it seems that the timer is not running, I can see from registers that edge signal is triggered and also I get an interrupt. But the timer value is always 0.

 htim15.Instance = TIM15;

 htim15.Init.Prescaler = 10;

 htim15.Init.CounterMode = TIM_COUNTERMODE_UP;

 htim15.Init.Period = 0;

 htim15.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;

 htim15.Init.RepetitionCounter = 0;

 htim15.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;

 if (HAL_TIM_Base_Init(&htim15) != HAL_OK)

 {

  Error_Handler();

 }

 sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;

 if (HAL_TIM_ConfigClockSource(&htim15, &sClockSourceConfig) != HAL_OK)

 {

  Error_Handler();

 }

 if (HAL_TIM_IC_Init(&htim15) != HAL_OK)

 {

  Error_Handler();

 }

 sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;

 sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;

 if (HAL_TIMEx_MasterConfigSynchronization(&htim15, &sMasterConfig) != HAL_OK)

 {

  Error_Handler();

 }

 sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_BOTHEDGE;

 sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI;

 sConfigIC.ICPrescaler = TIM_ICPSC_DIV1;

 sConfigIC.ICFilter = 0;

 if (HAL_TIM_IC_ConfigChannel(&htim15, &sConfigIC, TIM_CHANNEL_1) != HAL_OK)

 {

  Error_Handler();

 }

And in MSP i have:

  __HAL_RCC_TIM15_CLK_ENABLE();

  __HAL_RCC_GPIOA_CLK_ENABLE();

  /**TIM15 GPIO Configuration   

  PA2   ------> TIM15_CH1

  PA3   ------> TIM15_CH2 

  */

  GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_3;

  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;

  GPIO_InitStruct.Pull = GPIO_NOPULL;

  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;

  GPIO_InitStruct.Alternate = GPIO_AF5_TIM15;

  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  /* TIM15 interrupt Init */

  HAL_NVIC_SetPriority(TIM15_IRQn, 0, 0);

  HAL_NVIC_EnableIRQ(TIM15_IRQn);

Anyone able to spot why the timer does not seem to run???

Please help 🙂

1 ACCEPTED SOLUTION

Accepted Solutions

> htim15.Init.Period = 0;

This means the timer's counter won't run.

JW

View solution in original post

4 REPLIES 4

> htim15.Init.Period = 0;

This means the timer's counter won't run.

JW

TMalt
Associate II

Great thanks - it works. I do not fully understand why I need a period.

I need the timer to start again from zero every time there is an edge detected (and generate an interrupt)

So initially I was thinking autoreload the value zero and count up.... but it was working with auto-reload preload disabled.

The counter period says (AutoReload Register - 16-bits value), but I have auto-reload preload disabled so why does it influence.

I don't understand your question. The counter counts up from zero to whatever value is in ARR (or, if ARPE is set, in the "really used for next update (*)" register after update event). If ARR=0, it will count from 0 to 0, i.e. not count. The "library" initialization function makes sure that there's an update event (by setting EGR.UG) which loads whatever value you set into the "real (*)" register.

The reset value of ARR is the maximum value (i.e. 0xFFFF or 0xFFFFFFFF depending on whether the given timer is 16- or 32-bit), and if you set ARPE and make sure that update never occurs, then you can write 0 to ARR it will never get to the "real (*)" value. But why would you want to rely on that? Isn't it easier to write the same maximum value? Then it does not matter whether preload is enabled or not.

JW

(*) I don't like the "shadow" name for it, but don't have something less ambiguous either

TMalt
Associate II

Thanks again

Some misunderstande on my side (of my old code), I was under the impression that the counter was reset to zero on every edge..... (it was not, the delta was calculated on the next layer).

So basically I now have the timer running 0..0xFFFF and whenever I have an edge detection I get an interrupt and the timer value is transferred to CCR1 where I read it and calculate difference to last.

I have set ARR to 0xFFFF.