cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F7xx is a 216 MHz ARM MCU But I Can Not Generate Even 0.5 microsecond Timer Interrupt?

MSERT
Associate II

Hi,

//In my project i want to use 0.5 us (500 nanosecond) timer interrupt counter. 

//The MCUs max speed is 216 MHz. To get 200 MHz clock frequency, My OSC and CLOCK Settings are 

void SystemClock_Config(void)

{

RCC_OscInitTypeDef RCC_OscInitStruct;

RCC_ClkInitTypeDef RCC_ClkInitStruct;

HAL_StatusTypeDef ret = HAL_OK;

RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;

RCC_OscInitStruct.HSEState = RCC_HSE_ON;

RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;

RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;

RCC_OscInitStruct.PLL.PLLM = 4;

RCC_OscInitStruct.PLL.PLLN = 192;

RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;

RCC_OscInitStruct.PLL.PLLQ = 8;

ret = HAL_RCC_OscConfig(&RCC_OscInitStruct);

if(ret != HAL_OK)

{

while(1){;}

}

ret = HAL_PWREx_EnableOverDrive();

if(ret != HAL_OK)

{

while(1){;}

}

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_DIV4;

RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;

ret = HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_7);

if(ret != HAL_OK)

{

while(1){;}

}

}

//and 

//TIMER Settings for 5 us interrupt output 

 TIM_HandleTypeDef htim2 = {

.Instance = TIM2};

__HAL_RCC_TIM2_CLK_ENABLE();

htim9.Init.Prescaler = 99;

htim9.Init.CounterMode = TIM_COUNTERMODE_UP;

htim9.Init.Period = 9;

htim9.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;

htim9.Init.RepetitionCounter = 0x00;

HAL_TIM_Base_Init(&htim2);

HAL_TIM_Base_Start_IT(&htim2);

HAL_NVIC_SetPriority(TIM2_IRQn, 0x00, 0x00);

HAL_NVIC_EnableIRQ(TIM2_IRQn);

//then for 1 second LED blink using 100.000 counter variable in following function;

void TIM2_IRQHandler()

{

second++;

HAL_TIM_IRQHandler(&htim2);

}

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)

{

if(second == 90.000)

{

HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_SET);

}

if(second == 100.000)

{

HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_RESET);

second = 0;

}

}

Led blinks 1 time in one second. Ok. 

//***But if I decrease the division factor to get 0.5 us -500 nanosecond- changing counter variable = 1.000.000 to get 1 second LED blink***

htim9.Init.Prescaler = 9;

htim9.Init.CounterMode = TIM_COUNTERMODE_UP;

htim9.Init.Period = 9;

//It slows down that around 2 sec/blink!!! and even if i continue to decrease Prescaler = under 9 or Period = under 9 the speed of LED blinking doesnt chance!!!

//I wisited hundreds of web pages and i read toushands of pages of documents but couldnt find any useful description or solution! I just found a trick in a document DM00224583 (RCC dedicated clocks configuration register (RCC_DCKCFGRx)) about APB1 and APB2 that their division must be 1 to conduct high speed frequency, but my setings are already same with that division 1!!! Since we will never be able to use it, why it is so fast this much 216 MHz?

//Could you help me how to generate 0.5 us interrupt with 216 MHz High speed MCU STM32F7xx????

17 REPLIES 17
Piranha
Chief II
  1. Clock configuration is completely wrong. To get 200 MHz with that configuration, PLL would have to run at 4 MHz input and 800 MHz VCO output frequency, neither of which is possible. RM0410 5.3.2 .
  2. APB1 and APB2 configuration is also wrong. Those buses can't run at 200 MHz. Datasheet, "General operating conditions".
  3. You are handling TIM9 from TIM2 interrupt handler.
  4. Learn basic math, so that You can calculate the needed prescaler value not try "many various values".
  5. Start using hardware, which You have - timer output channels.
  6. HAL drivers are bloatware and are not an indicator of MCU capabilities. To get top performance, one must use LL drivers or better write his own.

You clearly haven't read those "toushands of pages of documents" and even played with CubeMX clock configuration. So, before s***ing on MCU, look at Your own pants...

This is totally wrong. CPU, SRAM and AHB peripherals are actually running at 216 MHz. Cortex-M7 is even able to execute up to two instructions at once. These MCUs are very fast when used properly. Almost all performance problems people have are because of badly designed software (including HAL drivers) and totally unusable CubeMX generated bloatware.

> But your answer doesnt help me unfortinately!

To quote Morpheus here:

"I can only show you the door. You're the one that has to walk through it."

Piranha
Chief II
  1. Clock configuration is totally wrong. To get 200 MHz SYSCLK with those settings, PLL would have to run at 4 MHz input and 800 MHz VCO output frequencies, neither of which is possible. RM0410 5.3.2 .
  2. APB buses configuration is also wrong. Those buses can't run at 200 MHz. Datasheet, "General operating conditions".
  3. You are handling TIM9 interrupt from TIM2 interrupt handler function.
  4. Start using hardware You have by it's purpose - timer output channels.
  5. Learn basic math, so that You can calculate needed prescaler value not try "many various values".
  6. HAL drivers are badly designed and bloated, and therefore are not an indicator of MCU performance. To reach top performance, one must use LL drivers or better write their own.

You clearly haven't read those "toushands of pages of documents" and not even played with CubeMX clock configuration. Before starting to criticize the MCU, learn how it works and look at Yourself (Your solution)!

It is like complaining that your Formula I race car doesn't do 250mph on offroad tracks.

If you do not want to engage with the STM32F7 and it's complex peripherals, go back to the PIC and do bit-banging.

Hi,

I reviewed my settings and code.and restructured some parts of it.

I corrected;

Oscillator, Clock, AHB, APBx and TIM2 Handler function that you indicated sections 1. 2. 3. ... 5. ...

Thus: Osc 8 MHz HSE - SYS Clock 192 MHz - AHB/HCLK 192 MHz - APB1 Timer Clock 96 MHz (for my TIM2)

However I couldnt understand;

4.Start using hardware You have by it's purpose - timer output channels.

You mean: *HAL_TIM_PeriodeElapsedCallback()*; or

*HAL_TIM_OC_DelayElapsedCallback()*; functions?

and

6.HAL drivers are badly designed and bloated, and therefore are not an

indicator of MCU performance. To reach top performance, *one must use LL

drivers or better write their own. *what do you mean?

Final form of my whole code is below:

If APB1 bus is 96 MHz so: 96 MHz / (Prescaler * Periode) = 0.96 MHz = 1 /

0.96 MHz ~= 1 microsecond

the LED must blink approximately 10 times in second. But it is around 3

times again!

I'm trying to move from pic to ST-ARM Mcus and it is really very difficult

for any engineer that who worked with 8/16 bit PICs for many years in

industry! So I need really help at this point to generate at least correct

1 or 0.5 microsecond Timer speed before I give it up!!! Then I'll work on

ADC and PWM that which will not be able to force me this much as far as I

understand...

could you help me to fix my work below?

thanks

*

#include

"stm32f7xx.h" // Device header*

*

#include

"stm32f7xx_hal.h"*

*/*-----SYSTEM OSCILLATOR & CLOCK CONFIGURATIONS-----*/*

*void SystemClock_Config(void)*

* {*

* RCC_OscInitTypeDef RCC_OscInitStruct;*

* RCC_ClkInitTypeDef RCC_ClkInitStruct;*

* //RCC_PLLInitTypeDef RCC_PLLInitStruct;*

* HAL_StatusTypeDef ret = HAL_OK; //HAL_OK = 0x00*

* RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; //Oscillator

is HSE (High Speed External) - 8MHz on Nucleo Board*

* RCC_OscInitStruct.HSEState = RCC_HSE_ON; //HSE is ON*

* RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; //PLL (Phase Locked Loop) is

ON*

* RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; //PLL Source is HSE

Oscillator*

* RCC_OscInitStruct.PLL.PLLM = 4; //Main Division Factor for PLL VCO Input

Clock : 2 - 63*

* RCC_OscInitStruct.PLL.PLLN = 192; //Main Multiplication Factor for PLL

VCO Output Clock : 50 - 432*

* RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; //Main Division Factor for

Main System Clock : 2,4,6,8*

* RCC_OscInitStruct.PLL.PLLQ = 8; *

* ret = HAL_RCC_OscConfig(&RCC_OscInitStruct);*

* if(ret != HAL_OK)*

* {*

* while(1){;}*

* }*

* ret = HAL_PWREx_EnableOverDrive();*

* if(ret != HAL_OK)*

* {*

* while(1){;}*

* }*

* 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_DIV4;*

* RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;*

* ret = HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_7);*

* if(ret != HAL_OK)*

* {*

* while(1){;}*

* }*

* }*

*//----------GLOBAL VARIABLES----------//*

* uint32_t second;*

*//----------TIMER TYPEDEF----------//*

* TIM_HandleTypeDef htim2 = {*

*.Instance = TIM2};*

*/*----------THE MAIN FUNCTION----------*/*

*int main()*

*{*

* HAL_Init();*

* SystemClock_Config();*

* //RCC_PeriphCLKInitTypeDef RCC_PeriphCLKInitStruct;*

* //TIM_ClockConfigTypeDef TIM_ClockConfigStruct;*

* TIM_Base_InitTypeDef TIM_Base_InitStruct;*

* GPIO_InitTypeDef GPIO_InitStruct;*

* __HAL_RCC_GPIOB_CLK_ENABLE();*

* GPIO_InitStruct.Pin = GPIO_PIN_7 | GPIO_PIN_14;*

* GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;*

* GPIO_InitStruct.Pull = GPIO_NOPULL;*

* GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;*

* HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);*

* __HAL_RCC_GPIOC_CLK_ENABLE();*

* GPIO_InitStruct.Pin = GPIO_PIN_13;*

* GPIO_InitStruct.Mode = GPIO_MODE_INPUT;*

* GPIO_InitStruct.Pull = GPIO_PULLDOWN;*

* GPIO_InitStruct.Speed = GPIO_SPEED_MEDIUM;*

* HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);*

* __HAL_RCC_TIM2_CLK_ENABLE();*

* htim2.Init.Prescaler = 9;//Between 0x0000 - 0xFFFF*

* htim2.Init.CounterMode = TIM_COUNTERMODE_UP;//UP: From 0 to Set Prescaler

Value*

* htim2.Init.Period = 9;//Between 0x0000 - 0xFFFF*

* htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;*

* htim2.Init.RepetitionCounter = 0x00;*

* HAL_TIM_Base_Init(&htim2);*

* HAL_TIM_Base_Start_IT(&htim2);*

* HAL_NVIC_SetPriority(TIM2_IRQn, 0x00, 0x00);*

* HAL_NVIC_EnableIRQ(TIM2_IRQn);*

* while(1) {}*

*}*

*/*--------------------USER PROGRAM--------------------*/*

*void TIM2_IRQHandler()*

* {*

* HAL_TIM_IRQHandler(&htim2);*

* second++;*

* if(second == 99000)*

* { *

* HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_SET);*

* }*

* if(second == 100000)*

* {*

* HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_RESET);*

* second = 0;*

* }*

* }*

ST Community 19 Şub 2019 Sal, 10:26 tarihinde şunu

yazdı:

bit-banging!!! oh my god!!!

Okay..

I will ask my question to an experienced adult!

no info available here!

thanks.!!!!!!!!!!

Piranha
Chief II

When posting code, use "Code Snippet" button to insert code.

//Oscillator is HSE (High Speed External) - 8MHz on Nucleo Board
RCC_OscInitStruct.HSEState = RCC_HSE_ON;

RCC_HSE_ON means that HSE oscillator is on, but on Nucleo boards by default HSE is fed by 8 MHz external clock from ST-Link. Therefore HSEState must be RCC_HSE_BYPASS.

About my previous points:

4.Read the RM0410 section 26. Look for phrase "output compare". Also AN4776

is very useful. I don't know much HAL functions because I dropped usage of HAL for my projects in favor of my own drivers.

6.I mean exactly what I said. What exactly isn't clear there?

And as was said before - You can count microseconds or even clock ticks with a timer itself, but set up an interrupt only on reaching target time, not on every microsecond. It can be done with ARR register and in more complex cases also an output compare channel. TIM2 is a 32-bit timer. For example, at 96 MHz timer clock set prescaler to 96/2-1 and You've got Your 0.5 us timer increments.