2019-08-15 06:33 AM
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 :)
Solved! Go to Solution.
2019-08-15 07:33 AM
2019-08-15 07:33 AM
> htim15.Init.Period = 0;
This means the timer's counter won't run.
JW
2019-08-15 07:49 AM
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.
2019-08-15 07:54 AM
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
2019-08-15 08:19 AM
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.