Forum: Mikrocontroller und Digitale Elektronik STM32 Probleme mit dem Takt


von Benni N. (benninori)


Lesenswert?

Hi,

ich muss schon wieder nerven. Nachdem ich jetzt mein Progrämmchen auf 
die Lib von ST umgestellt hab, hab ich irgendwie Probleme mit meiner 
Clock. irgendwas hab ich da im RCC vergeigt und mach jetzt schon wieder 
den halben Tag dran rum und finde den Fehler nicht. Wäre super wenn 
einer von euch Profis mal kurz auf meinen Code schauen könnte:
1
void ClockInit()
2
{
3
  //Clock control register
4
  RCC->CR  = RCC_CR_HSEON ;       //HSE on
5
6
  // Wait for HSE
7
  while (!(RCC->CR & RCC_CR_HSERDY))
8
  {
9
  }
10
11
  //Clock configuration register
12
  RCC->CFGR      = RCC_CFGR_PPRE1_DIV1;     //APB1 nicht teilen
13
  RCC->CFGR     |= RCC_CFGR_PLLSRC;         //HSE als PLL-Eingangssignal
14
  RCC->CFGR     |= RCC_CFGR_PLLMULL6;       //PLL=HSE*6
15
16
  RCC->CR       |= RCC_CR_PLLON;            //PLL einschalten 
17
   
18
  //Wait for PLL
19
  while (!(RCC->CR & RCC_CR_PLLRDY))
20
  {
21
  }
22
  
23
  RCC->CFGR     |= RCC_CFGR_SW_PLL;          //PLL als Systemtakt
24
  
25
  //Wait for SYSCLK
26
  while (!(RCC->CFGR & RCC_CFGR_SWS_PLL))
27
  {
28
  }
29
  
30
  RCC->CFGR    |= RCC_CFGR_OTGFSPRE;        //48MHz für USB
31
  
32
  //Takte für die Peripherie einschalten
33
  RCC->AHBENR   = RCC_AHBENR_SRAMEN;
34
  RCC->AHBENR  |= RCC_AHBENR_CRCEN;
35
  RCC->AHBENR  |= RCC_AHBENR_OTGFSEN;
36
  RCC->APB2ENR  = RCC_APB2ENR_AFIOEN;
37
  RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;
38
  RCC->APB2ENR |= RCC_APB2ENR_IOPBEN;
39
  RCC->APB1ENR |= RCC_APB1ENR_USART2EN;
40
  RCC->APB1ENR |= RCC_APB1ENR_CAN1EN;
41
  RCC->APB1ENR |= RCC_APB1ENR_PWREN;
42
}

Der Knackpunkt an der Sache scheint die Umschaltung auf die PLL als 
SYSCLK zu sein. Da bricht das Programm jedes mal ab. Was mach ich 
falsch?

Da hab ich doch bestimmt wieder was blödes übersehen.

von (prx) A. K. (prx)


Lesenswert?

Ben _ schrieb:

>   RCC->CFGR      = RCC_CFGR_PPRE1_DIV1;     //APB1 nicht teilen

APB1 <= 36MHz.

von Benni N. (benninori)


Lesenswert?

ahh, mein liebster freund und helfer. willst du mir damit sagen, dass 
APB1 maximal 36MHz haben darf?

habe jetzt durch 2 geteilt sprich 36MHz. Leider hab ich immernoch das 
gleiche Problem

von (prx) A. K. (prx)


Lesenswert?

Ben _ schrieb:

> ahh, mein liebster freund und helfer. willst du mir damit sagen, dass
> APB1 maximal 36MHz haben darf?

Genau dies.

von Benni N. (benninori)


Lesenswert?

sonst fällt dir nichts auf?

von (prx) A. K. (prx)


Lesenswert?

Was für ein STM32 ist das eigentlich genau? Das "OTG" Dings erinnert 
mich eher an 105/107.

von Benni N. (benninori)


Lesenswert?

Wieso, wenn ich die 72MHz durch 1,5 teile komme ich doch auf 48MHz. Was 
hab ich da jetzt schon wieder falsch verstanden?


OK, ich habe meinen Knackpunkt gefunden. Verstehe ihn aber nicht.Ich 
benutze einen 12MHz Quarz und wenn ich die PLL auf *4 statt auf *6 
stelle dann funktionierts. Was ist falsch an 72MHz als Systemtakt?

von Benni N. (benninori)


Lesenswert?

Ja, es ist der 105er.

von (prx) A. K. (prx)


Lesenswert?

Ganz sicher, dass im Startup nicht schon irgendwo auf einen anderen Takt 
als HSI geschaltet wird? Denn die PLL live umzuschalten ist ziemlich 
ungünstig. Nummer sicher: Erst auf HSI schalten.

von (prx) A. K. (prx)


Lesenswert?

Ben __ schrieb:

> Wieso, wenn ich die 72MHz durch 1,5 teile komme ich doch auf 48MHz. Was
> hab ich da jetzt schon wieder falsch verstanden?

Yep, aber ich war beim 103er, und der teilt bei 0, teilt nicht bei 1.

von Benni N. (benninori)


Lesenswert?

Laut reference manual schaltet es während des Bootvorgangs einfach auf 
HSI.

von (prx) A. K. (prx)


Lesenswert?

Ich kenne grad den Startup deiner Entwicklungsumgebung nicht, was da 
alles noch drin verbuddelt ist. Vielleicht ist da eine andere ClockInit 
Funktion schneller.

Ggf. verfolgen oder vorher nachsehen was im RCC drinsteht.

von Benni N. (benninori)


Lesenswert?

Ich probiers jetzt mal so aus, dass ich erstmal auf den HSI umschalt und 
schau, ob das dann besser läuft. Ansonsten komm ich auch mit den 48MHz 
klar. Hauptsache es tut.

Danke soweit für deine Hilfe.

von (prx) A. K. (prx)


Lesenswert?

Vorher 2 Flash-Waits einstellen. Sonst säuft er natürlich ab.

von (prx) A. K. (prx)


Lesenswert?

Ich kannte bisher nur die Taktung der 101er und 103er, der 105 sieht
etwas anders aus.

PLLVCO ist offenbar PLLCLK*2 auch wenn das nirgends ausdrücklich steht,
nur ein bischen indirekt im Datasheet. Bei 72MHz Sysclock ist das also
144MHz, bei dir /2 gibt 72MHz.

Da du oben davon ausgehst, dass der USB Takt durch 1,5 geteilt wird,
frage ich mich, in welchem Teil vom Manual zum RCC du nachgesehen hast,
unter Kapitel 6 (low/medium/high density devices 101-103), oder unter
Kapitel 7 (connectivity line 105-107). Denn der 105er teilt bei USB
durch 2 oder 3, aber nie durch 1,5.

>  //Clock configuration register
>  RCC->CFGR      = RCC_CFGR_PPRE1_DIV1;     //APB1 nicht teilen
>  RCC->CFGR     |= RCC_CFGR_PLLSRC;         //HSE als PLL-Eingangssignal
>  RCC->CFGR     |= RCC_CFGR_PLLMULL6;       //PLL=HSE*6

Dieser Teil ist etwas irritierend, denn er suggeriert, dass diese 3 
Zeilen die PLL definieren. Die beiden letzten tun das auch, aber der 
PPRE1-Teiler für APB1 hat damit nichts zu tun. PLLXTPRE_PREDIV1 würde an 
dieser Stelle besser passen.

von (prx) A. K. (prx)


Lesenswert?

A. K. schrieb:

> PLLVCO ist offenbar PLLCLK*2 auch wenn das nirgends ausdrücklich steht,
> nur ein bischen indirekt im Datasheet. Bei 72MHz Sysclock ist das also
> 144MHz, bei dir /2 gibt 72MHz.

PS: Damit wollte ich sagen, dass dein USB bei 72MHz Systemtakt mit 72MHz 
läuft. Denn obwohl der 105er anders dokumentiert ist kommt 
freundlicherweise das gleiche dabei raus.

von Benni N. (benninori)


Lesenswert?

A. K. schrieb:
>PLLVCO ist offenbar PLLCLK*2 auch wenn das nirgends ausdrücklich steht,
>nur ein bischen indirekt im Datasheet. Bei 72MHz Sysclock ist das also
>144MHz, bei dir /2 gibt 72MHz.

Was meinst du damit? Ich finde gerade nicht die Stelle von der du 
redest.

> Da du oben davon ausgehst, dass der USB Takt durch 1,5 geteilt wird,
> frage ich mich, in welchem Teil vom Manual zum RCC du nachgesehen hast,
> unter Kapitel 6 (low/medium/high density devices 101-103), oder unter
> Kapitel 7 (connectivity line 105-107). Denn der 105er teilt bei USB
> durch 2 oder 3, aber nie durch 1,5.

Das mit den 1,5 steht im reference manual unter 6.3.2 Clock 
configuration register (RCC_CFGR). Da steht beim USB_PRE:

Set and cleared by software to generate 48 MHz USB clock. This bit must 
be valid before
enabling the USB clock in the RCC_APB1ENR register. This bit can’t be 
reset if the USB
clock is enabled.
0: PLL clock is divided by 1.5
1: PLL clock is not divided

>>  //Clock configuration register
>>  RCC->CFGR      = RCC_CFGR_PPRE1_DIV1;     //APB1 nicht teilen
>>  RCC->CFGR     |= RCC_CFGR_PLLSRC;         //HSE als PLL-Eingangssignal
>>  RCC->CFGR     |= RCC_CFGR_PLLMULL6;       //PLL=HSE*6
>
> Dieser Teil ist etwas irritierend, denn er suggeriert, dass diese 3
> Zeilen die PLL definieren. Die beiden letzten tun das auch, aber der
> PPRE1-Teiler für APB1 hat damit nichts zu tun. PLLXTPRE_PREDIV1 würde an
> dieser Stelle besser passen.

Ok, vielleicht ein bisschen doof zusammengestellt. Da hast du recht. 
aber PLLXTPRE_PREDIV1  ist doch, wenn ich APB1 als PLL-Eingang nutze. 
Das mach ich ja garnicht.

von (prx) A. K. (prx)


Lesenswert?

Ben __ schrieb:

> Was meinst du damit? Ich finde gerade nicht die Stelle von der du
> redest.

Wenn du stets an der falschen Stelle suchst, wirst du sie nie finden.

> Das mit den 1,5 steht im reference manual unter 6.3.2 Clock
> configuration register (RCC_CFGR). Da steht beim USB_PRE:

Genau das dachte ich mir ja: Du sitzt im falschen Zug. Beim 105er gibt 
es kein USB_PRE, nicht einmal ein Kapitel 6 ;-). Soll heissen, es ist 
nicht auf die 105/107er anwendbar, für die gilt Kapitel 7. Steht in dem 
stets wiederkehrenden Sermon über die low/mid/high/conn Typen vorneweg, 
den man der steten Wiederholung wegen automatisch überspringt.

Immerhin heisst der Bit bei dir im Programm anders, das hätte dir 
eigentlich zu denken geben sollen.

> aber PLLXTPRE_PREDIV1  ist doch, wenn ich APB1 als PLL-Eingang nutze.
> Das mach ich ja garnicht.

APB1 wird vom Ausgang der PLL abgeleitet, hat nichts mit deren Eingang 
zu tun. Da ist allerdings auch ein Prescaler, der dummerweise auch noch 
ähnlich heisst, aber nichts mit den APBs zu tun hat.

von Benni N. (benninori)


Lesenswert?

A. K. schrieb:
> Genau das dachte ich mir ja: Du sitzt im falschen Zug. Beim 105er gibt
> es kein USB_PRE, nicht einmal ein Kapitel 6 ;-). Soll heissen, es ist
> nicht auf die 105/107er anwendbar, für die gilt Kapitel 7. Steht in dem
> stets wiederkehrenden Sermon über die low/mid/high/conn Typen vorneweg,
> den man der steten Wiederholung wegen automatisch überspringt.
>
> Immerhin heisst der Bit bei dir im Programm anders, das hätte dir
> eigentlich zu denken geben sollen.

OH, jetzt blick ichs. Steht ja eigentlich auch groß in der Überschrift. 
Das Kapitel 7 ist mir irgendwie noch nie groß aufgefallen, da ich in 6 
ja alles gefunden hab was ich brauche. Danke, da war ich ein kleines 
bisschen blind.

> APB1 wird vom Ausgang der PLL abgeleitet, hat nichts mit deren Eingang
> zu tun. Da ist allerdings auch ein Prescaler, der dummerweise auch noch
> ähnlich heisst, aber nichts mit den APBs zu tun hat.

OK.

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.