AnsweredAssumed Answered

STM32F407 timer output compare for timeout

Question asked by andy b on Mar 14, 2017

Hi

 

I've been trying to use the TIM3 in my stm32f407 in output compare mode to generate a timeout delay.
What I've been struggling with is that there is little documentation on using a timer with HAL for such application.I have read all timer documentation that I could find and still havent found a clear answer to my question .I find it weird since it's something that is simple.

 

Basically I have a function that is waiting on either a USART interrupt or a timer interrupt which ever comes first.
When the USART is completely disabled the function works fine ,getting triggerd by the timer overflow.But when I enable the USART.When the function gets triggered by the USART first .I need to stop and reset the compare value of the timer so that I don't trigger my function twice.Stopping the timer is an easy task but I haven't found a way to reset the compare value.So when the timer is restarted it resumes where it was stopped.Making the next Timeout way shorter than it actually should be.

 

Here is my timer config:

static void MX_TIM3_Init(void)
{

TIM_ClockConfigTypeDef sClockSourceConfig;
TIM_MasterConfigTypeDef sMasterConfig;
TIM_OC_InitTypeDef sConfigOC;

htim3.Instance = TIM3;
htim3.Init.Prescaler = 0;
htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
htim3.Init.Period = 5200;
htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
if (HAL_TIM_Base_Init(&htim3) != HAL_OK)
{
Error_Handler();
}

sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
if (HAL_TIM_ConfigClockSource(&htim3, &sClockSourceConfig) != HAL_OK)
{
Error_Handler();
}

if (HAL_TIM_OC_Init(&htim3) != HAL_OK)
{
Error_Handler();
}

sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK)
{
Error_Handler();
}

sConfigOC.OCMode = TIM_OCMODE_TIMING;
sConfigOC.Pulse = 0;
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
if (HAL_TIM_OC_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
{
Error_Handler();
}

HAL_TIM_Base_Start(&htim3);
}

 

 

For a weird reason changing sConfigOC.Pulse does nothing ( checked on a logic analyser).This may be that I am not in the right mode or don't have the right settings.


Here is my IRQ callback:

 

void HAL_TIM_OC_DelayElapsedCallback(TIM_HandleTypeDef *htim)
{
 if(htim->Instance == TIM3)
 { 
 HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_10);
 uint16_t CCR1_Current = htim3.Instance->CCR1;
 htim3.Instance->CCR1 = (CCR1_Current + 5200);

 HAL_TIM_OC_Start_IT(&htim3,TIM_CHANNEL_1);
 }
}

IRQ handler is all configured correctly same for the timer interrupt config for TIM3.

I would prefer a solution that uses HAL , even tho I tried to bypass it and direcly change the registers,since I want to stay away from the hardware as most as I can , for possible MCU porting reasons.

Thanks

-Andy

Outcomes