2024-01-16 11:59 AM - edited 2024-01-16 12:36 PM
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.
Thx in advance !
Woyzeck
Solved! Go to Solution.
2024-01-19 04:18 PM
*** 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 !
2024-01-16 12:13 PM
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.
2024-01-16 12:16 PM
> 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
2024-01-16 01:10 PM
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 ?
2024-01-18 12:42 PM
So I'm still not making any progress here.
What I tried so far:
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.
2024-01-18 12:52 PM
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.
2024-01-18 01:01 PM
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?
2024-01-18 01:14 PM
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?
2024-01-18 01:20 PM
/**
* @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();
}
}
2024-01-19 01:37 PM
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.