Forum: Mikrocontroller und Digitale Elektronik stm32f103 hse clock


von mikro111 (Gast)


Lesenswert?

ich möchte die hse clock nutzen (8Mhz Quarz).
ich habe dafür folgende routine geschrieben die im main aufgerufen wird.
als hsi/2 clock config funktioniert es!


void clock_init(){



  FLASH_SetLatency(FLASH_Latency_1);


   * Enable PLL, wait till it's stable, then select it as system clock*/

RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
  RCC_PLLCmd(ENABLE);
  while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET) {}
  RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

  /* Set HCLK, PCLK1, and PCLK2 to SCLK (these are default */
  RCC_HCLKConfig(RCC_SYSCLK_Div1);
  RCC_PCLK1Config(RCC_HCLK_Div2);
  RCC_PCLK2Config(RCC_HCLK_Div1);

  /* Set ADC clk to 12MHz (14MHz max, 18MHz default)*/
  RCC_ADCCLKConfig(RCC_PCLK2_Div6);

  /*To save power, use below functions to stop the clock to ceratin
   * peripherals
   * RCC_AHBPeriphClockCmd
   */
  //RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA, ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ALL, ENABLE);
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_ALL, ENABLE);

}

von mikro111 (Gast)


Lesenswert?

Also es sollen 72Mhz als sysclk genutzt werden.

ADCclock sollen 12 Mhz sein.

PCLK1 müssen 36Mhz sein


oder muss ich den controller zunächst als hsi konfigurieren????

von (prx) A. K. (prx)


Lesenswert?

mikro111 schrieb:

> Also es sollen 72Mhz als sysclk genutzt werden.

Wofür 1 Waitstate meiner Erinnerung nach zu wenig ist.

von mikro111 (Gast)


Lesenswert?

??? was muss ich ändern??

von (prx) A. K. (prx)


Lesenswert?

FLASH_SetLatency();

von (prx) A. K. (prx)


Lesenswert?

mikro111 schrieb:

> oder muss ich den controller zunächst als hsi konfigurieren????

Ja, wenn er's nicht schon ist. Vorzugsweise immer aus HSI heraus 
woanders hin schalten. Aus dem Powerup/Reset kommt er allerdings sowieso 
mit HSI.

von (prx) A. K. (prx)


Lesenswert?

Hast du den HSE überhaupt eingeschaltet?

Höflicherweise reduziert man den/die Periphieriebustakte bevor man den 
Sysclk auf Maximum stellt.

Code als Code posten, sieht sonst schrecklich aus.

von mikro111 (Gast)


Lesenswert?

1
void clock_init(){
2
3
  
4
5
6
                               
7
8
  /* Set HCLK, PCLK1, and PCLK2 to SCLK (these are default */
9
  RCC_HCLKConfig(RCC_SYSCLK_Div1);
10
  RCC_PCLK1Config(RCC_HCLK_Div2);
11
  RCC_PCLK2Config(RCC_HCLK_Div1);                                                             
12
13
  /* Set ADC clk to 12MHz (14MHz max, 18MHz default)*/
14
  RCC_ADCCLKConfig(RCC_PCLK2_Div6);                                                           
15
16
  
17
  /* First set the flash latency to work with our clock*/
18
   /*000 Zero wait state, if 0  MHz < SYSCLK <= 24 MHz
19
     001 One wait state, if  24 MHz < SYSCLK <= 48 MHz
20
     010 Two wait states, if 48 MHz < SYSCLK <= 72 MHz */
21
   FLASH_SetLatency(FLASH_Latency_2);                                                         
22
23
   /* Start with HSE clock (external 8mhz),  multiply by 9 to
24
    * get maximum allowed frequency: 72Mhz
25
    * Enable PLL, wait till it's stable, then select it as system clock*/
26
   RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);//9
27
   RCC_PLLCmd(ENABLE);
28
   while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET) {}
29
   RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);                   
30
  
31
  
32
  
33
  /*To save power, use below functions to stop the clock to ceratin
34
   * peripherals
35
   * RCC_AHBPeriphClockCmd
36
   */
37
 // RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA, ENABLE);
38
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ALL, ENABLE);
39
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_ALL, ENABLE);                                         
40
41
  
42
}





scheint immernoch nicht zu laufen

von mikro111 (Gast)


Lesenswert?

A. K. schrieb:
> Hast du den HSE überhaupt eingeschaltet?

Wie geht das???

von (prx) A. K. (prx)


Lesenswert?

Augen zu und durch ist der falsche Ansatz. Es gibt Doku. Und massenhaft 
Democode.

von Hannes S. (Gast)


Lesenswert?

Also auf jeden Fall fehlt da mal das:  RCC_HSEConfig(RCC_HSE_ON);

Die ganze Clock-Initialisierung kannst Du auch durch die ST-Lib machen 
lassen, schau Dir mal das File system_stm32f10x.c an.

von Jan H. (janiiix3)


Lesenswert?

Hey,

ich habe genau das gleiche Problem.. Wurde eine Lösung gefunden?
1
void _clockInit(void)
2
{
3
    RCC_DeInit();
4
5
    RCC_HSEConfig(RCC_HSE_ON);
6
7
    RCC_PREDIV1Config(RCC_PREDIV1_Source_HSE,RCC_PREDIV1_Div2); // RCC_PREDIV1_Div1 klappt nicht..
8
    RCC_PLLConfig(RCC_PLLSource_PREDIV1, RCC_PLLMul_9);
9
    RCC_PLLCmd(ENABLE);
10
11
    while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET) {}
12
13
    RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
14
15
    /* Set HCLK, PCLK1, and PCLK2 to SCLK (these are default */
16
    RCC_HCLKConfig (RCC_SYSCLK_Div1);
17
    RCC_PCLK1Config(RCC_HCLK_Div2);
18
    RCC_PCLK2Config(RCC_HCLK_Div2);
19
}

RCC_PREDIV1_Div1 klappt nicht..

von W.S. (Gast)


Angehängte Dateien:

Lesenswert?

Jan H. schrieb:
> ich habe genau das gleiche Problem.. Wurde eine Lösung gefunden?

Schon seit Ewigkeiten!

Wenn ich mich recht entsinne, hab ich vor ganz vielen Monaten schon 
einmal ein komplettes kleines STM32F103-Projekt hier gepostet. Die 
angehängte Datei config.c (vom 19.9.2016) stammt daraus.

W.S.

von Jan H. (janiiix3)


Lesenswert?

Das freut mich.
Woran lang es nun konkret?

von Dr. Sommer (Gast)


Lesenswert?

W.S. schrieb:
> Wenn ich mich recht entsinne, hab ich vor ganz vielen Monaten schon
> einmal ein komplettes kleines STM32F103-Projekt hier gepostet.

> /* Konfiguration für das Testboard mit STM32F302RBT6 */

> #include "StdTypes.h"
> #include "STM32F302xB.h"
Was denn jetzt, F1 oder F3?

Jan braucht es aber für den STM32F105:
Beitrag "Re: STM32F105xx keine CAN Nachrichten!"

Man kann sich den Initialisierungs-Code aus STM32CubeMX generieren 
lassen, oder mithilfe des Datenblattes selber schreiben. Man muss nicht 
alles aus dem Internet kopieren...

von Jan H. (janiiix3)


Lesenswert?

Dr. Sommer schrieb:
> W.S. schrieb:
>> Wenn ich mich recht entsinne, hab ich vor ganz vielen Monaten schon
>> einmal ein komplettes kleines STM32F103-Projekt hier gepostet.
>
>> /* Konfiguration für das Testboard mit STM32F302RBT6 */
>
>> #include "StdTypes.h"
>> #include "STM32F302xB.h"
> Was denn jetzt, F1 oder F3?
>
> Jan braucht es aber für den STM32F105:
> Beitrag "Re: STM32F105xx keine CAN Nachrichten!"
>
> Man kann sich den Initialisierungs-Code aus STM32CubeMX generieren
> lassen, oder mithilfe des Datenblattes selber schreiben. Man muss nicht
> alles aus dem Internet kopieren...

Dr. Sommer! Du scheinst ja ein Einzelkämpfer zu sein. Super!
Ich für meine Person, brauche nun mal noch externe Hilfe, im Internet 
habe ich keine Passende Erklärung gefunden.

Soweit bin ich aktuell..
1
void _clockInit(void)
2
{
3
    RCC_DeInit();
4
5
    RCC_HSEConfig(RCC_HSE_ON);
6
7
    RCC_PREDIV1Config(RCC_PREDIV1_Source_HSE,RCC_PREDIV1_Div2); // RCC_PREDIV1_Div1 klappt nicht..
8
    RCC_PLLConfig(RCC_PLLSource_PREDIV1, RCC_PLLMul_9);
9
    RCC_PLLCmd(ENABLE);
10
11
    while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET) {}
12
13
    RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
14
15
    RCC_HCLKConfig (RCC_SYSCLK_Div1);
16
    RCC_PCLK1Config(RCC_HCLK_Div1);
17
    RCC_PCLK2Config(RCC_HCLK_Div2);
18
}

von Dr. Sommer (Gast)


Lesenswert?

Jan H. schrieb:
> Ich für meine Person, brauche nun mal noch externe Hilfe, im Internet
> habe ich keine Passende Erklärung gefunden.
Dann hast du nicht genau hingeschaut.
Lies hier:
http://www.st.com/resource/en/reference_manual/cd00171190.pdf
Seiten 122-157.
Und beachte in
http://www.st.com/resource/en/datasheet/stm32f105r8.pdf
die Tabelle auf S. 37, insb. die drei Frequenzen in den ersten drei 
Zeilen.

Wenn du etwas nicht verstehst, suche oder frag nach. Ansonsten sollten 
keine Fragen übrig bleiben.

von Stefan F. (Gast)


Lesenswert?

Vielleicht kommst du besser mit einem Programmbeispiel zurecht, daß 
keine HAL Library verwendet: 
http://stefanfrings.de/stm32/index.html#takt

Ich richte mich jedenfalls lieber nach den Hinweisen im STM32F1 
Reference Manual. Dort sind die Register und Bits genannt, also greife 
ich 1:1 darauf zu. Die HAL Libraries verwirren mich nur.

von Christopher J. (christopher_j23)


Lesenswert?

Hier hast du noch eine absolut minimalistische PLL-Config für 72MHz 
Systemtakt und 48MHz USB bei 8MHz Quartz. Das hatte ich so mal für einen 
F103C8 zusammengestrickt.
1
void SystemInit(void) {
2
3
    /* Enable Power Control clock -> see section 7.3.8 in the manual */
4
    RCC->APB1ENR |= RCC_APB1ENR_PWREN;
5
6
    /* Enable HSE */
7
    RCC->CR |= RCC_CR_HSEON;
8
9
    /* Wait for HSE to become ready */
10
    while ((RCC->CR & RCC_CR_HSERDY) == 0);
11
12
    /*
13
     * Configure Main PLL
14
     * HSE as clock input
15
     * HSE = 8MHz
16
     * fpllout = 72MHz
17
     * PLLMUL = 9
18
     * fusb = 48MHz
19
     * 
20
     * PLL configuration is really straight forward. Setting the PLLMULL bits in the
21
     * RCC->CFGR to 0b0111 results in a multiplication factor of 9.
22
     * The divider for the USB clock is 1.5 by default, resulting in 48MHz fusb.
23
     * Select the HSE as PLL source by setting the PLLSRC bit in the configuration register.
24
     * See chapter 8.3.2 in the manual for more information.
25
     */
26
    RCC->CFGR = (0b0111 << RCC_CFGR_PLLMULL_Pos) | RCC_CFGR_PLLSRC;
27
28
    /* PLL On */
29
    RCC->CR |= RCC_CR_PLLON;
30
    
31
    /* Wait until PLL is locked */
32
    while ((RCC->CR & RCC_CR_PLLRDY) == 0);
33
34
    /*
35
     * FLASH configuration block
36
     * enable instruction cache
37
     * enable prefetch
38
     * set latency to 2WS (3 CPU cycles)
39
     */
40
    FLASH->ACR |= FLASH_ACR_PRFTBE 
41
                | FLASH_ACR_LATENCY_2;
42
43
    /* Set HCLK (AHB) prescaler (DIV1) */
44
    RCC->CFGR &= ~(RCC_CFGR_HPRE);
45
46
    /* Set APB1 Low speed prescaler (APB1) DIV2 */
47
    RCC->CFGR |= RCC_CFGR_PPRE1_DIV2;
48
49
    /* SET APB2 High speed prescaler (APB2) DIV1 */
50
    RCC->CFGR &= ~(RCC_CFGR_PPRE2);
51
52
    /* Set clock source to PLL */
53
    RCC->CFGR |= RCC_CFGR_SW_PLL;
54
    /* Busy-wait until PLL is active as clock source */
55
    while ((RCC->CFGR & RCC_CFGR_SWS_PLL) != RCC_CFGR_SWS_PLL);
56
57
58
    SystemCoreClock = 72000000UL;
59
}

von Jan H. (janiiix3)


Lesenswert?

Christopher J. schrieb:
> RCC->CFGR = (0b0111 << RCC_CFGR_PLLMULL_Pos) | RCC_CFGR_PLLSRC;

Nabend.
Danke für deine Hilfe.
Hiermit stellst du den Faktor für die PLL ein oder ? In dem Fall für 
72MHz, sollten das "9" sein oder?

"RCC_CFGR_PLLMULL_Pos" gibt es bei mir in den Headerdateien nicht.

von Dr. Sommer (Gast)


Lesenswert?

Christopher J. schrieb:
> Hier hast du noch eine absolut minimalistische PLL-Config
So lernt er das nie...

Jan H. schrieb:
> "RCC_CFGR_PLLMULL_Pos" gibt es bei mir in den Headerdateien nicht.
Nimm die neuen Header-Dateien die zur HAL gehören, nicht die alten für 
die SPL. Da sind diese xxx_Pos Makros drin.

von Jan H. (janiiix3)


Lesenswert?

Dr. Sommer schrieb:
> Nimm die neuen Header-Dateien die zur HAL gehören, nicht die alten für
> die SPL. Da sind diese xxx_Pos Makros drin.

Was verbirgt sich hinter dem Macro?

von Dr. Sommer (Gast)


Lesenswert?

Jan H. schrieb:
> Was verbirgt sich hinter dem Macro?

Die Position des Bits PLLMULL im RCC_CFGR Register, also einfach 18.

von Jan H. (janiiix3)


Lesenswert?

Dr. Sommer schrieb:
> Jan H. schrieb:
>> Was verbirgt sich hinter dem Macro?
>
> Die Position des Bits PLLMULL im RCC_CFGR Register, also einfach 18.

Jetzt klappt es!
Besten dank. Werde mir das jetzt mal alles Ausführlich anschauen.

von Jan H. (janiiix3)


Lesenswert?

Christopher J. schrieb:
> /*
>      * FLASH configuration block
>      * enable instruction cache
>      * enable prefetch
>      * set latency to 2WS (3 CPU cycles)
>      */
>     FLASH->ACR |= FLASH_ACR_PRFTBE
>                 | FLASH_ACR_LATENCY_2;

Wozu genau wird das gemacht?

von Stefan F. (Gast)


Lesenswert?

Der Flash kann mit maximal 24Mhz gelesen werden. Wenn die CPU schneller 
getaktet wird, muss sie warten. Dafür ist die Latency, es gibt zwei 
mögliche Werte, die je nach Taktfrequenz gewählt werden müssen.

Prefetch aktiviert einen Puffer, der die nächstren Befehle vom Flash in 
einen schnelleren Speicher kopiert, den die CPU ohne Wartezeit lesen 
kann.

Der Prefetch Buffer kann nur direkt aufeinanderfolgende Befehle 
beschleunigen. Bei Sprung-Anweisungen und Interrupts wird sein Inhalt 
verworfen.

von Jan H. (janiiix3)


Lesenswert?

Stefan U. schrieb:
> Der Flash kann mit maximal 24Mhz gelesen werden. Wenn die CPU schneller
> getaktet wird, muss sie warten. Dafür ist die Latency, es gibt zwei
> mögliche Werte, die je nach Taktfrequenz gewählt werden müssen.
>
> Prefetch aktiviert einen Puffer, der die nächstren Befehle vom Flash in
> einen schnelleren Speicher kopiert, den die CPU ohne Wartezeit lesen
> kann.
>
> Der Prefetch Buffer kann nur direkt aufeinanderfolgende Befehle
> beschleunigen. Bei Sprung-Anweisungen und Interrupts wird sein Inhalt
> verworfen.

Kann ich mir das so ungefähr wie ein FiFO für Befehle vorstellen?

Wenn das nicht gemacht wird? Kann es dazu kommen das dass Programm an 
einigen Stellen abstürzen kann?

von Dr. Sommer (Gast)


Lesenswert?

Jan H. schrieb:
> Kann es dazu kommen das dass Programm an
> einigen Stellen abstürzen kann?

Ohne Prefetch wird das Programm lediglich langsamer. Ohne Wait States 
stürzt der Controller beim 1. Flash-Zugriff nach dem Takt-Umschalten ab 
oder macht sonst irgend einen Unfug.

Die STM32F4 haben mit dem "ART" einen verbesserten Cache, und die F7 
einen richtigen L1-Cache.

von Stefan F. (Gast)


Lesenswert?

> Kann ich mir das so ungefähr wie ein FiFO für Befehle vorstellen?

Ja. Während die CPU mit Rechnen beschäftigt ist, kann der Puffer gefüllt 
werden.

> Wenn das nicht gemacht wird?

Dann muss die CPU häufiger auf den Flash Speicher warten, da dieser wie 
gesagt nur 24Mhz schafft. Wenn du das ignorierst und die CPU z.B. mit 
72Mhz ohne Wait States benutzt, dann wird sie abstürzen.

von Christopher J. (christopher_j23)


Lesenswert?

Dr. Sommer schrieb:
> Christopher J. schrieb:
>> Hier hast du noch eine absolut minimalistische PLL-Config
> So lernt er das nie...

Ja ich weiß, das war gespoilert und wenn er das einfach nur per 
Copy-Paste übernimmt ohne es zu hinterfragen, dann bringt es nichts. Das 
ist ja bei Jan scheinbar nicht der Fall. Würde er sich die Konfiguration 
von CubeMX oder sonstwie generieren lassen wäre der Lerneffekt aber 
ebenso gleich Null.

Jedenfalls hab ich selber nochmal drüber geschaut und festgestellt, das 
man sich die erste Zeile, also
1
    /* Enable Power Control clock -> see section 7.3.8 in the manual */
2
    RCC->APB1ENR |= RCC_APB1ENR_PWREN;
prinzipiell schenken kann, wenn man denn keine Low-Power-Modi verwenden 
will. Dann wäre es wirklich minimal ;)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.