cancel
Showing results for 
Search instead for 
Did you mean: 

Periodic Interrupt Timer with dynamic period set (programmatically) not being generated

BCano.1
Associate III

Im in the process of configuring a STM32L432KC to talk with an AFBR-S50 sensor. This sensor needs a periodic interrupt to trigger measurements periodically.

In the example they are using a timer with down counting direction to generate the interrupt when it reaches 0.

I dont have any more counters capable of doing down direction counting so i have to change the config and code a little bit.

In the timer config they are setting the "Internal Clock" tick for the timer but i dont have that on my free timers. So i only changed the prescaler to "SystemCoreClock / 1000000 -1", counter mode: "down" and Trigger event selection: "Enable (CNT_EN)".

The rest is configured in code. This is their code for setting the Timer:

status_t Timer_SetInterval(uint32_t dt_microseconds, void * param)
{
   assert(dt_microseconds == 0 || dt_microseconds > 100);
   /* Disable interrupt and timer */
   callback_param_ = 0;
   HAL_TIM_Base_Stop(&htim4);
   __HAL_TIM_DISABLE_IT(&htim4, TIM_IT_UPDATE);
   __HAL_TIM_CLEAR_IT(&htim4, TIM_IT_UPDATE);
   if (dt_microseconds)
  {
      uint32_t prescaler = SystemCoreClock / 1000000U;
      while (dt_microseconds > 0xFFFF)
      {
         dt_microseconds >>= 1U;
         prescaler <<= 1U;
      }
      assert(prescaler <= 0x10000U);
      /* Set prescaler and period values */
      __HAL_TIM_SET_PRESCALER(&htim4, prescaler - 1);
      __HAL_TIM_SET_AUTORELOAD(&htim4, dt_microseconds - 1);
      __HAL_TIM_SET_COUNTER(&htim4, dt_microseconds - 1);
      /* Enable interrupt and timer */
      callback_param_ = param;
      __HAL_TIM_ENABLE_IT(&htim4, TIM_IT_UPDATE);
      HAL_TIM_Base_Start(&htim4);
   }
   return STATUS_OK;
}

I have changed the timer identifier which in my case is TIM7 and counter register to start from 0 so counting is up direction. This is my code:

status_t Timer_SetInterval(uint32_t dt_microseconds, void * param)
{
	assert(dt_microseconds == 0 || dt_microseconds > 100);
	/* Disable interrupt and timer */
	callback_param_ = 0;
	HAL_TIM_Base_Stop(&htim7);
	__HAL_TIM_DISABLE_IT(&htim7, TIM_IT_UPDATE);
	__HAL_TIM_CLEAR_IT(&htim7, TIM_IT_UPDATE);
 
	if (dt_microseconds)
	{
		uint32_t prescaler = SystemCoreClock / 1000000U;
		while (dt_microseconds > 0xFFFF)
		{
			dt_microseconds >>= 1U;
			prescaler <<= 1U;
		}
		assert(prescaler <= 0x10000U);
		/* Set prescaler and period values */
		__HAL_TIM_SET_PRESCALER(&htim7, prescaler - 1);
		__HAL_TIM_SET_AUTORELOAD(&htim7, dt_microseconds - 1);
		__HAL_TIM_SET_COUNTER(&htim7, 0); 
		/* Enable interrupt and timer */
		callback_param_ = param;
		__HAL_TIM_ENABLE_IT(&htim7, TIM_IT_UPDATE);
		HAL_TIM_Base_Start(&htim7);
	}
	return STATUS_OK;
}

I think this should work ok. But it doesnt, the testing software they provide fails due timeout error, so interrupt is not generated. I think autoreload register is counter period for timers going UP. is that right?

Thanks

5 REPLIES 5
TDK
Guru

Do you enable the corresponding NVIC interrupt somewhere? Is the IRQ handler function correctly spelled and defined in your code?

Note that ARR is preloaded. You can generate an update event to load it immediately.

If you feel a post has answered your question, please click "Accept as Solution".
BCano.1
Associate III

Yes, i've enabled the corresponding NVIC interrupt and check with different priorities.

Read out and check/post TIM registers content.

Some ideas how to "interrupt does not fire" here.

JW

How can i check TIM registers from debugging? I was not able to solve this.

I check everything a million times.

> How can i check TIM registers from debugging?

This depends on toolchain you are using. Most IDEs have something called "peripheral registers view" or something similar.

JW