cancel
Showing results for 
Search instead for 
Did you mean: 

Illogical Prescaler Behavior

vindicator
Associate II

I wanted to see what would happen when I set the prescaler for an interrupt lower and lower.

My expectation was that the main loop would lose out on it's share of processing time, but I was surprised when the results of my test were mixed.

Essentially, I figured something along the lines of a prescaler of 84-30 would all be fine, other than the main loop increasingly taking longer to process. Then everything below 30 would take so long, it would appear to hang.

Instead of my expectation being reality, the illogical came to be, where prescalers from 84-72 would be good, then suddenly 69-67 "hangs". Then 66-47 is good, but again it switches back to bad at 46 and 45.

It gets this back and forth mix that I just don't understand the reasoning.

I just used the STM32F4-Discovery main.c template with minor adjustments:

  BSP_LED_Init(LED3);
  TIM_Handle7.Instance = TIM7;
  TIM_Handle7.Init.Period = 1;
  TIM_Handle7.Init.ClockDivision = 0;
  TIM_Handle7.Init.CounterMode = TIM_COUNTERMODE_UP;
  TIM_Handle7.Init.RepetitionCounter = 0;
  TIM_Handle7.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
 
  uint32_t tickVal, lastTickVal = 0;
  uint32_t lastLedToggleTick = 0;
  uint32_t result = 0;
  float calc = 0;
  /* Infinite loop */
  while (1)
  {
    tickVal = HAL_GetTick();
    if (lastTickVal != tickVal)
    {
      if ((lastLedToggleTick + 500) >= tickVal)
      {
        BSP_LED_Toggle(LED3);
        lastLedToggleTick = tickVal;
      }
 
      for (uint32_t prescaler = 44; prescaler > 0; prescaler--)
      {//bad:71,69-67,46-45,35-34,31-26
      //good:84-72,66-47,44-36,33-32
        TIM_Handle7.Init.Prescaler = prescaler - 1;
        result = HAL_TIM_Base_Init(&TIM_Handle7);
        timerCounter = 0;
        result = HAL_TIM_Base_Start_IT(&TIM_Handle7);
        for (uint32_t y = 906; y > 0; y--) //Just some math I'll be experimenting with, but irrelevant except only for the work load.
        {
          if ((907 % y) == 0)
          {
            result = HAL_TIM_Base_Stop_IT(&TIM_Handle7);
            calc = ((1 / (float)((uint32_t) 84000000 / (uint32_t) prescaler)) * (uint32_t) timerCounter);
            result = HAL_TIM_Base_DeInit(&TIM_Handle7);
            break;
          }
        }
      }
 
      lastTickVal = tickVal;
    }
  }

The IRQ Handler's only job was to increment the timerCounter.

Can someone explain the effect that I'm seeing?

2 REPLIES 2

Don't tie the LED toggle on the systick, toggle it simply upon each nth pass of the loop. Make sure the bulk of the loop is not optimized out by the compiler. Observe it with a scope or LA if it blinks too fast. Make several pass/blinks per timer prescaler setting.

JW

I'll add that I use "-O0".

I have no idea why you're mentioning the LED toggle. This isn't about optimizing my test.

The test is simply existing to see why the prescaler is behaving the way it is.

I know time/ticks elapse during the work done by the for loop. I can actually leave out the HAL_GetTicks and LED_Toggle, but that won't change the behavior I'm seeing from the prescaler for loop, which is what this post is about.

My only guess for your reply being the way it is, is that you saw the code and "Can someone explain the effect that I'm seeing?" and didn't read anything else.