Ich bin verwirrt, wenn es darum geht, den Taktbaum eines STM32F103 Cortex M3 zur Laufzeit zu ändern, und ich hoffe, dass mir jemand dabei helfen kann.
Ich verwende ein Entwicklungsboard, das ein 8-MHz-HSE an Bord hat. Gemäß der Standardkonfiguration der STM-SPL-Datei stm32f10x_system.c wird PLL (abgeleitet von HSE) beim Booten als SYSCLK-Quelle ausgewählt.
Ich möchte PLL als Quelle verwenden (abgeleitet von HSI). Nach dem, was ich verstanden habe, sind die wichtigsten Schritte
Wie oben beschrieben habe ich meine Routine geschrieben, die aufgerufen wird, wenn main() startet
//TURN ON HSI AND SET IT AS SYSCLK SRC
RCC_HSICmd(ENABLE);
while(RCC_GetFlagStatus(RCC_FLAG_HSIRDY) == RESET){};
//SET HSI AS SYSCLK SRC. CONFIGURE HCLK, PCLK1 & PCLK2
RCC_SYSCLKConfig(RCC_SYSCLKSource_HSI);
RCC_HCLKConfig(RCC_SYSCLK_Div1);
RCC_PCLK1Config(RCC_HCLK_Div1);
RCC_PCLK2Config(RCC_HCLK_Div1);
//DISABLE PLL
RCC_PLLCmd(DISABLE);
//CHANGE PLL SRC AND MULTIPLIER
RCC_PLLConfig(RCC_PLLSource_HSI_Div2, RCC_PLLMul_16);
//ENABLE PLL
//WAIT FOR IT TO BE READY
//SET SYSCLK SRC AS PLLCLK
RCC_PLLCmd(ENABLE);
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET){};
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
//SET HCLK = SYSCLK = 64MHZ
RCC_HCLKConfig(RCC_SYSCLK_Div1);
//SET PCLK2 = HCLK = 64MHZ
RCC_PCLK2Config(RCC_HCLK_Div1);
//SET PCLK1 = HCLK/2 = 32MHZ
RCC_PCLK1Config(RCC_HCLK_Div2);
Das funktioniert gut. Dann wurde mir klar, dass ich die FLASH-Latenz sowie meine Uhr ändern müsste
Also habe ich das gemacht
//SETUP THE SYSTEM CLOCK AS BELOW
//CLOCK SRC = 8MHZ HSI + PLL
//SYSCLK = 64MHZ
//HCLK = SYSCLK = 64MHZ
//PCLK2 = HCLK = 64MHZ
//PCLK1 = HCLK = 32MHZ
//TURN ON HSI AND SET IT AS SYSCLK SRC
RCC_HSICmd(ENABLE);
while(RCC_GetFlagStatus(RCC_FLAG_HSIRDY) == RESET){};
//SET HSI AS SYSCLK SRC. CONFIGURE HCLK, PCLK1 & PCLK2
RCC_SYSCLKConfig(RCC_SYSCLKSource_HSI);
RCC_HCLKConfig(RCC_SYSCLK_Div1);
RCC_PCLK1Config(RCC_HCLK_Div1);
RCC_PCLK2Config(RCC_HCLK_Div1);
//SET THE FLASH LATENCY AS PER OUR CLOCK
//FASTER THE CLOCK, MORE LATENCY THE FLASH NEEDS
//000 Zero wait state, if 0 MHz < SYSCLK <= 24 MHz
//001 One wait state, if 24 MHz < SYSCLK <= 48 MHz
//010 Two wait states, if 48 MHz < SYSCLK <= 72 MHz */
FLASH_SetLatency(FLASH_Latency_0);
//DISABLE PLL
RCC_PLLCmd(DISABLE);
//CHANGE PLL SRC AND MULTIPLIER
RCC_PLLConfig(RCC_PLLSource_HSI_Div2, RCC_PLLMul_16);
//ENABLE PLL
//WAIT FOR IT TO BE READY
//SET SYSCLK SRC AS PLLCLK
RCC_PLLCmd(ENABLE);
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET){};
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
FLASH_SetLatency(FLASH_Latency_2);
//SET HCLK = SYSCLK = 64MHZ
RCC_HCLKConfig(RCC_SYSCLK_Div1);
//SET PCLK2 = HCLK = 64MHZ
RCC_PCLK2Config(RCC_HCLK_Div1);
//SET PCLK1 = HCLK/2 = 32MHZ
RCC_PCLK1Config(RCC_HCLK_Div2);
Das funktioniert auch. Also meine Fragen sind
Ist die Einstellung der Flash-Latenz optional? da es bei mir auch ohne funktioniert hat.
Nein. Wenn Sie die Flash-Latenzzeit nicht korrekt einstellen, liest Ihr Programm möglicherweise manchmal falsche Daten aus dem Flash-Speicher.
Wann genau rufen Sie die Funktion FLASH_SetLatency mit dem neuen Wartezustand auf? Vor dem Einstellen der neuen Uhr oder gleich danach?
Vor dem Erhöhen der Systemtaktfrequenz oder nach dem Verringern.
Eine zu hohe Latenz für den Systemtakt ist meistens harmlos – es wird das System etwas verlangsamen, aber das war’s – aber eine zu niedrige Latenz kann zu Fehlfunktionen führen.
Sie sollten auch diese Zeile hinzufügen: SystemCoreClock = 64000000;
Oder noch besser statt:
SystemCoreClock = 64000000;
Forderung:
SystemCoreClockUpdate();
und es berechnet die SystemCoreClock-Variable.
Ankit
having latency too high is mostly harmless..
. Kannst du mehr zumBefore increasing the system clock frequency, or after decreasing it..
Teil erklären?Benutzer39382
Bence Kaulics