2019-08-21 09:58 AM
Hello,
i want to measure time between high and low pulse from a ultrasonic sensor. The time is set to 1ms. It works until i reach the end of the time ARR.
To differentitat betwenn a distance like 1cm and 11cm (10cm end of the counter) i have to counte the timer reloads. In CubeMX is checked all the interrupts on but in eigther don't found the right interrupt or i don't activate all interrupts for Capture control timer (TIM1).
Did anyone know how to get the ARR Interrupt of the capture control?
Thanks.
Gendo
2019-08-21 12:21 PM
The "update" interrupt is what you need here (TIM_IT_UPDATE if you are using HAL, which I presume you are since you are using CubeMX). Whether this specific interrupt gets enabled by default by the HAL code depends on which TIM_***_Start_***() function you call. It sounds like you are calling HAL_TIM_IC_Start_IT(), correct? You can always manually enable that interrupt using the __HAL_TIM_ENABLE_IT(). Then make sure you have a HAL_TIM_PeriodElapsedCallback() function defined.
2019-08-22 11:52 PM
Hello Bob,
year that's wath you do but it doesn't work. Thaht's the problem.
int main()
{
.....
HAL_TIM_IC_Start_IT(&htim1, TIM_CHANNEL_1);
HAL_TIM_IC_Start_IT(&htim1, TIM_CHANNEL_2);
....
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim->Instance == TIM1 ) // CH1 von Input Capter Compaire abfragen
{
__NOP();
Capture_status=1;
}
}
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
if(htim -> Channel == HAL_TIM_ACTIVE_CHANNEL_1 )
{
CaptureCompaireValue[0]=HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1);
}
if(htim -> Channel == HAL_TIM_ACTIVE_CHANNEL_2 )
{
CaptureCompaireValue[1]=HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_2);
}
}
2019-08-22 11:56 PM
2019-08-23 12:05 AM
You'd never need to ask this question if you'd avoid Cube/CubeMX, and read the RM and program the timer accordingly.
You'd simply set up the timer to run and to perform the input capture, then enable the two interrupts by setting TIMx_DIER.UIE and TIMx_DIER.CCxIW, locate the interrupt vectors - for TIM1 they may be separate, see the Interrupt chapter in RM and/or the startup code - and write the ISRs.
Cube/CubeMX inevitably support only a limited subset of the much wider possibilities, covering the "usual usage cases", so you have to apply kludges to work around its limitations. Bob's expertize in this field is far from being trivial and reaches far beyond mere clicking in CubeMX.
JW
2019-08-23 02:16 AM
Hello Jan,
good to know. This why i don't found all the things from the ADC Datasheet of the STM32 in CubeMX...
So i have to change the timer pre-settings below by my self?
static void MX_TIM1_Init(void)
{
/* USER CODE BEGIN TIM1_Init 0 */
/* USER CODE END TIM1_Init 0 */
TIM_ClockConfigTypeDef sClockSourceConfig = {0};
TIM_SlaveConfigTypeDef sSlaveConfig = {0};
TIM_MasterConfigTypeDef sMasterConfig = {0};
TIM_IC_InitTypeDef sConfigIC = {0};
/* USER CODE BEGIN TIM1_Init 1 */
/* USER CODE END TIM1_Init 1 */
htim1.Instance = TIM1;
htim1.Init.Prescaler = 0;
htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
htim1.Init.Period = 0xffff;
htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim1.Init.RepetitionCounter = 0;
htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_Base_Init(&htim1) != HAL_OK)
{
Error_Handler();
}
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
if (HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig) != HAL_OK)
{
Error_Handler();
}
if (HAL_TIM_IC_Init(&htim1) != HAL_OK)
{
Error_Handler();
}
sSlaveConfig.SlaveMode = TIM_SLAVEMODE_TRIGGER;
sSlaveConfig.InputTrigger = TIM_TS_TI1FP1;
sSlaveConfig.TriggerPolarity = TIM_TRIGGERPOLARITY_BOTHEDGE;
sSlaveConfig.TriggerFilter = 0;
if (HAL_TIM_SlaveConfigSynchro(&htim1, &sSlaveConfig) != HAL_OK)
{
Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK)
{
Error_Handler();
}
sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING;
sConfigIC.ICSelection = TIM_ICSELECTION_INDIRECTTI;
sConfigIC.ICPrescaler = TIM_ICPSC_DIV1;
sConfigIC.ICFilter = 0;
if (HAL_TIM_IC_ConfigChannel(&htim1, &sConfigIC, TIM_CHANNEL_1) != HAL_OK)
{
Error_Handler();
}
sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_FALLING;
sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI;
if (HAL_TIM_IC_ConfigChannel(&htim1, &sConfigIC, TIM_CHANNEL_2) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN TIM1_Init 2 */
//__HAL_TIM_GET_FLAG(&htim1, TIM_FLAG_UPDATE);
/* USER CODE END TIM1_Init 2 */
}
2019-08-23 02:57 AM
I found the code in the timer interrupt that i want.
/* TIM Update event */
if (__HAL_TIM_GET_FLAG(htim, TIM_FLAG_UPDATE) != RESET)
{
if (__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_UPDATE) != RESET)
{
__HAL_TIM_CLEAR_IT(htim, TIM_IT_UPDATE);
#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
htim->PeriodElapsedCallback(htim);
#else
HAL_TIM_PeriodElapsedCallback(htim);
#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
}
}
But how can i set the "TIM_FLAG_UPDATE" for TIM1?
TIM1->TIM_FLAG_UPDATE =1; ?
2019-08-23 03:04 AM
This function is what i need but my IDE don't knot it:
void TIM_ITConfig(TIM_TypeDef * TIMx,uint16_t TIM_IT,FunctionalState NewState )
Enables or disables the specified TIM interrupts.
Parameters:
2019-08-23 06:45 AM
int main()
{
.....
HAL_TIM_IC_Start_IT(&htim1, TIM_CHANNEL_1);
HAL_TIM_IC_Start_IT(&htim1, TIM_CHANNEL_2);
No, that will not work (as you discovered). That code is starting the timer in input capture mode, enabling channel 1 interrupt only. The 2nd line attempts to RE-START the timer in input capture mode enabling channel 2 interrupt only. The 2nd call will fail, and if you had checked the return status it would have been HAL_BUSY, not HAL_OK. Lesson #1 - always check the return code from HAL "start" functions!!!!!!!!!!!
You should be able to call HAL_TIM_IC_Start_IT() one time, then use the __HAL_TIM_ENABLE_IT() macro just to enable the channel 2 interrupt. Like this:
int main()
{
.....
HAL_StatusTypeDef halsts;
halsts = HAL_TIM_IC_Start_IT(&htim1, TIM_CHANNEL_1);
if ( halsts != HAL_OK ) {
// Report the error here, somehow
// printf( "Timer init failed, sts %d\n", halsts );
}
__HAL_TIM_ENABLE_IT(&htim1, TIM_CHANNEL_2);
2021-03-03 02:59 PM
__HAL_TIM_ENABLE_IT(&htim1, TIM_IT_UPDATE);