Skip to main content
TMalt
Associate II
August 15, 2019
Solved

Problem with timer and input capture, timer does not run

  • August 15, 2019
  • 4 replies
  • 2721 views

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 :)

This topic has been closed for replies.
Best answer by waclawek.jan

> htim15.Init.Period = 0;

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

JW

4 replies

waclawek.jan
waclawek.janBest answer
Super User
August 15, 2019

> htim15.Init.Period = 0;

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

JW

TMalt
TMaltAuthor
Associate II
August 15, 2019

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.

waclawek.jan
Super User
August 15, 2019

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
TMaltAuthor
Associate II
August 15, 2019

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.