cancel
Showing results for 
Search instead for 
Did you mean: 

Using TIM5 for function call timing and not getting expected results

SGome.1
Associate II

STM32F777

__HAL_RCC_TIM5_CLK_ENABLE();
TIM5->PSC = HAL_RCC_GetPCLK1Freq()/1000000 - 1;
TIM5->CR1 = TIM_CR1_CEN;
 
cyclecountstart = TIM5->CNT;
HAL_Delay(1);
cyclecountend = TIM5->CNT;
cyclecount = cyclecountend - cyclecountstart;

I expect to see cyclecount to be somewhere in the neighborhood of 1000. Yes I know it could be as high as 2000. However, I consistently get around 168,000. I have verified prescaler is getting set how I expect (53 since PCLK1 is 54 MHz). If I remove the delay completely I see around 14 counts which I guess is believable but seems high.

What am I missing?

1 ACCEPTED SOLUTION

Accepted Solutions

TIM_PSC is unconditionally preloaded, which means, that value written to it gets taken into account only after Update event, which usually means the nearest overflow/underflow. In your latter case with changing to downcounting you've effectively caused underflow just as the timer starts to run. As TIM5 is a 32-bit timer, even at the default no prescaler it takes considerable time until it overflows for the first time, when counting up.

The usual trick is to set TIM_EGR.UG to force an Update just after writing to TIM_PSC, but note that should you enable the Update interrupt, it would fire immediately.

JW

View solution in original post

5 REPLIES 5
SGome.1
Associate II

Just want to add. Based on a search in these forums I changed the setting of CR1 to flip the DIR bit:

TIM5->CR1 = TIM_CR1_CEN | TIM_CR1_DIR;

Changing to subtract end from start because we are down-counting now, I get a "somewhat" reasonable 3100 counts. Why would it be any different at all?

Oh and to also add I've tried this running on the jlink and stand alone and the numbers don't change.

TIM_PSC is unconditionally preloaded, which means, that value written to it gets taken into account only after Update event, which usually means the nearest overflow/underflow. In your latter case with changing to downcounting you've effectively caused underflow just as the timer starts to run. As TIM5 is a 32-bit timer, even at the default no prescaler it takes considerable time until it overflows for the first time, when counting up.

The usual trick is to set TIM_EGR.UG to force an Update just after writing to TIM_PSC, but note that should you enable the Update interrupt, it would fire immediately.

JW

SGome.1
Associate II

That was the magic bullet. Thank you for your help. The working code:

  __HAL_RCC_TIM5_CLK_ENABLE();
  TIM5->PSC = HAL_RCC_GetPCLK1Freq()/1000000 - 1;
  TIM5->EGR = TIM_EGR_UG;
  TIM5->CR1 |= TIM_CR1_CEN;

I might search for the other thread I found I this issue and update that one too. As so often happens there was no resolution to the thread.

SGome.1
Associate II

I have to update this thread.

The above code MIGHT work for other STM32 MCUs but it does NOT work for the STM32F7 in all cases:

0693W000007ZQCpQAO.png 

In my case:

0693W000007ZQBhQAO.pngSince the APB1 Prescaler is not "/1" then the timers are actually running at 2x the PCKL1 frequency returned by the HAL_RCC_GetPCLK1Freq() function.

There's probably a dedicated incantation in Cube/HAL to determine the timers' clock. I don't Cube.

JW