cancel
Showing results for
Did you mean:

# Timer frequency is way off

Associate III

My STM32F303RE is running with an 8MHz crystal feeding into HSE:

Using TIM4 I want to generate 700 interrupts per second, but I only get 318.

As can be seen TIM4 runs at 64MHz and the following configuration should trigger about 318 interrupts:

Using the following formula:

(edit note - had a typo in the formula)

interrupts_per_second := clock_frequency / (prescaler + 1) / (counter_period + 1)

64 MHz / 3 / 30476 = 700

The 318 interrupts are way off the expected 700 and I just can't figure why. Any ideas are highly appreciated.

Woyzeck

1 ACCEPTED SOLUTION

Accepted Solutions
Associate III

*** me - it was a bug. Deep in my code I disabled the interrupt and restarted the timer.

Thx for your support, guys - I learned a lot !

13 REPLIES 13
Chief

64M /3 / 30476 = 700 --- seem ok.

+ How you check the rate then ?

try -> set a led toggle in timer int and look with a scope at the pin.

Guru

> Using TIM4 I want to generate 700 interrupts per second, but I only get 318.

How are you monitoring this exactly?

Try clocking from internal HSI to rule out any HSE issues.

Your math (sort of) and expectations check out.

> 64 MHz / 2 / 30475 = 700

Think you made a typo here. Should be 3 instead of 2. Result is the same.

64 MHz / 3 / 30476 = 700.0043750273439 Hz

Associate III

Thx for your support - I fixed the typo.

Replacing HSE with HSI for the whole board didn't fix the issue - now I get 320 interrupts per second (which is close to 318 and probably caused by the inaccuracy of HSI).

One thing that I observed is that the interrupt pulses are somehow irregular, meaning that the time between interrupts is varying by a single digit percentage, which is rather strange. Perhaps that's a hint to interrupt priority ?

Associate III

So I'm still not making any progress here.

What I tried so far:

• used MCO to output the HSI and HSE clock on pin PA8 - the measured frequency is 8MHz which is exactly what it should be, so the hardware setup is correct
• used MCO to output LSI with a measured result of 37,9 kHz - everything ok here

Interestingly I was unable to output PLLCLK and SYSCLK using MCO. Once I use HSE as the clock source for SYSCLK I measure 8MHz which is ok. In my clock setup SYSCLK is generated from PLLCLK so I wonder if there's something wrong with my setup of PLLCLK, but I can't see what it is.

Associate III

Some progress here - the issue with the lacking MCO signal for SYSCLK and PLLCLK was caused by the default speed setting of the MCO output pin PA8 as GPIO_SPEED_FREQ_LOW. Once set to GPIO_SPEED_FREQ_HIGH there's a signal on that pin and I can measure the expected 64 MHz.

So now I know that all clocks are working as expected, just the timer isn't.

Guru

What else is going on in your program? Feels like there is competition for cpu resources and/or an interrupt which is blocking for too long. Change frequency to say 10 Hz, do you get all of them?

I don't recall what the preference is on the F3 for PLL comparison frequency. For the F2/F4 it was 1-2 MHz

You should be able to get PLLCLK/2 out of MCU, and SYSCLK regardless of it's source / generation method.

Unpacking the RCC PLL settings might be more instructive of what's happening internally than Cube clock charts. Perhaps also the generated code.

Assuming this is a NUCLEO board, is that correct, or is this a custom board?

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
``````/**
* @brief  PLL source HSE bypass, and select the PLL as SYSCLK
*         source.
*         The system Clock is configured as follows :
*            System Clock source            = PLL (HSE bypass)
*            SYSCLK(Hz)                     = 64000000
*            HCLK(Hz)                       = 64000000
*            AHB Prescaler                  = 1
*            APB1 Prescaler                 = 2
*            APB2 Prescaler                 = 1
*            HSE Frequency(Hz)              = 8000000
*            HSE PREDIV                     = 1
*            PLLMUL                         = 8
*            Flash Latency(WS)              = 2
* @PAram  None
* @retval None
*/
static void SystemClockConfig(void)
{
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_OscInitTypeDef RCC_OscInitStruct = {0};

/* Enable HSE bypass Oscillator, select it as PLL source and finally activate the PLL */
RCC_OscInitStruct.OscillatorType        = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState              = RCC_HSE_BYPASS; // ST-LINK CMOS CLOCK
RCC_OscInitStruct.PLL.PREDIV            = RCC_PREDIV_DIV1;

RCC_OscInitStruct.PLL.PLLSource         = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLState          = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLMUL            = RCC_PLL_MUL8;

if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
/* Initialization Error */
Error_Handler();
}

/* Select the PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers */
RCC_ClkInitStruct.ClockType       = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
RCC_ClkInitStruct.SYSCLKSource    = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider   = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider  = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB2CLKDivider  = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
{
/* Initialization Error */
Error_Handler();
}

/* Optional: Disable HSI Oscillator (if the HSI is no more needed by the application)*/
RCC_OscInitStruct.OscillatorType  = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState        = RCC_HSI_OFF;
RCC_OscInitStruct.PLL.PLLState    = RCC_PLL_NONE;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
/* Initialization Error */
Error_Handler();
}
}``````
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Associate III

I changed the timer config to get 100 Hz, but only measure 44.3 Hz. The factor between the expected and the actual frequency is constant over a wide range of timer settings - it stays around 2.2, so the expected frequency is 2.2 times the actual frequency.