Forum: Mikrocontroller und Digitale Elektronik STM32CubeMX Probleme bei Clock Einstellung


von R. H. (breezer)


Angehängte Dateien:

Lesenswert?

Hallo,

ich habe hier ein STM32L432KC Nucleo Board. Die Konfiguration möchte ich 
über STM32CubeMX machen, leider habe ich Probleme bei der Clock 
Einstellung.

Als Clock Source wollte ich den "MSI RC" verwenden, dieser funktioniert 
aber nur wenn ich ihn direkt als Sysclock verwende. Gehe ich damit über 
den PLL Zweig taktet der MC nicht richtig.

Da der MSI RC über den LSE Clock abgeglichen wird und genauer wird 
(better than ±0.25 % accuracy) wollte ich diesen Modus verwenden, das 
funktioniert aber wohl nur über den PLL Zweig.

Als Test habe ich den Timer 7 genommen und lasse diesen bis 8000 zählen, 
dann wird ein Interrupt ausgelöst und ein Pin getoggelt.

Bei direkter Verwendung von 16Mhz MSI RC funktioniert das auch, der pin 
toggelt alle 0,5 ms (Bild 1).

Gehe ich aber über den PLL Zweig toggelt der pin immer alle 1 ms, egal 
was ich da auch einstelle, auch wenn ich die maximale Frequenz von 80 
MHz wähle (Bild 2).

hat da einer nen Tipp was ich falsch mache?

von Dr. Sommer (Gast)


Lesenswert?

Hast du denn mal den Initialisierungs Code durchgesteppt um zu schauen 
ob das Anschwingen von MSI, PLL und Umschalten des Sysclk korrekt 
funktioniert und nicht in einen Timeout läuft?

von Mr. Big (Gast)


Lesenswert?

Programmier das schnell von Hand, ist doch in 10 Minuten erledigt. Dann 
siehst Du, ob die MCU richtig funktioniert.

von Dr. Sommer (Gast)


Lesenswert?

Das will ich sehen, wie du die RCC-Initialisierung mit allen Registern, 
Warteschleifen, Dividierern und Multiplizierern, richtiger Reihenfolge, 
Flash Wait-States, Power Skalierung in 10 Minuten programmierst.

von R. H. (breezer)


Lesenswert?

Ich habe jetzt mal den Master Clock Out pin aktiviert und das Oszi dran. 
Irgendwie ist CubeMX verbuggt, da passt irgendwie gar nichts was über 
den PLL läuft.

Beim MSI RC über den PLL kommen als SysClk immer 8 MHz raus, egal was 
ich am PLL einstelle.

Der MC läuft an sich und die Initialiesirung läuft durch...

von Mr. Big (Gast)


Lesenswert?

Dr. Sommer schrieb:
> Das will ich sehen, wie du die RCC-Initialisierung mit allen Registern,
> Warteschleifen, Dividierern und Multiplizierern, richtiger Reihenfolge,
> Flash Wait-States, Power Skalierung in 10 Minuten programmierst.


Komm vorbei!

Im Übrigen mache ich das mit allen STM32-Controllern so. Ist:
1. Kein Hexenwerk
2. Steht alles im Reference Manual
3. habe ich schon ein bisschen Erfahrung (Cortex-M3 seit den Luminaries)

Ich verstehe nicht, wieso so viele davor zurückscheuen.

Hier im Forum habe ich ja bereits die (wirklich sehr kurze) 
STM32F407-Initialisierung gepostet, die vom STM32L432 ist nur 
unwesentlich länger für R.H.s Zwecke.
Dadurch wird der Code und Flash-Bedarf viel kürzer und auch die 
Ausführungszeit.

Wie man hier auch sieht, ist diese ST-Bloat-Blackbox reine 
Zeitverschwendung.

von Dr. Sommer (Gast)


Lesenswert?

R. H. schrieb:
> Irgendwie ist CubeMX verbuggt,
Das sowieso...

R. H. schrieb:
> Der MC läuft an sich und die Initialiesirung läuft durch...
Läuft korrekt durch oder geht in einen Fallback-Modus?

Mr. Big schrieb:
> 2. Steht alles im Reference Manual
Ja. Allein das zu lesen dauert länger als 10 Minuten.

Mr. Big schrieb:
> Ich verstehe nicht, wieso so viele davor zurückscheuen.
Weil es bedeutet, das Rad zum 1000. Mal neu zu erfinden. Allein schon 
das Berechnen der PLL-Faktoren ist lästige Fummelei. Das erspart man 
sich gerne.

Mr. Big schrieb:
> Hier im Forum habe ich ja bereits die (wirklich sehr kurze)
> STM32F407-Initialisierung gepostet
Link? Kurzer Code bedeutet nicht kurze Entwicklungszeit...

Mr. Big schrieb:
> Wie man hier auch sieht, ist diese ST-Bloat-Blackbox reine
> Zeitverschwendung.
Wen jucken die paar Takte mehr oder weniger bei der Initialisierung.

Ich hab sowas auch schon für mehrere Controller gemacht und sehe die 
Nutzung von CubeMX hier durchaus als großen Vorteil.

von Mr. Big (Gast)


Lesenswert?

Dr. Sommer schrieb:
> Mr. Big schrieb:
>> Ich verstehe nicht, wieso so viele davor zurückscheuen.
> Weil es bedeutet, das Rad zum 1000. Mal neu zu erfinden. Allein schon
> das Berechnen der PLL-Faktoren ist lästige Fummelei. Das erspart man
> sich gerne.


Drei Faktoren? Also das schaffen ja schon Grundschüler in 30 Sekunden. 
Das Klicken in der GUI dauert doch länger.

Und schau mal, wie lange R.H. schon erfolglos damit rummacht...

von Mr. Big (Gast)


Lesenswert?

Dr. Sommer schrieb:
> Mr. Big schrieb:
>> 2. Steht alles im Reference Manual
> Ja. Allein das zu lesen dauert länger als 10 Minuten.


Du schlägst doch nicht allen Ernstes vor, einen Controller ohne Lesen 
des Manuals einfach mal so zu benutzen, oder?

Kein Wunder, dass soviel Mist entwickelt wird.
Das Lesen des Manuals ist ja wohl ganz klar Pflicht!

von Dr. Sommer (Gast)


Lesenswert?

Mr. Big schrieb:
> Drei Faktoren? Also das schaffen ja schon Grundschüler in 30 Sekunden.
Ok, mit welcher Formel erhält man die direkt? Selbst CubeMX probiert 
anscheinend einfach nur alle möglichen Kombinationen durch. Man muss ja 
gewisse Randbedingungen bachten (max. Frequenz, Faktoren sind ganze 
Zahlen, haben Minimum/Maximum).

Mr. Big schrieb:
> Und schau mal, wie lange R.H. schon erfolglos damit rummacht...
Noch ist nicht gesagt dass CubeMX schuld ist.

von R. H. (breezer)


Lesenswert?

Ich möchte schon bei CubeMX bleiben, da ich auch die Einstellungen der 
ganzen Peripherie darüber mache und die HAL Lib nutze.

Dr. Sommer schrieb:
> Läuft korrekt durch oder geht in einen Fallback-Modus?

Ich habe in der SystemClock_Config Funktion in alle Error Handler einen 
Breakpoint eingefügt, keiner wird angesprungen...

von Dr. Sommer (Gast)


Lesenswert?

R. H. schrieb:
> Ich habe in der SystemClock_Config Funktion

Zeigen!

von R. H. (breezer)


Lesenswert?

in jeder if Bedingung wo error handler steht habe ich einen 
Breakpoint...
1
void SystemClock_Config(void)
2
{
3
4
  RCC_OscInitTypeDef RCC_OscInitStruct;
5
  RCC_ClkInitTypeDef RCC_ClkInitStruct;
6
7
    /**Configure LSE Drive Capability 
8
    */
9
  HAL_PWR_EnableBkUpAccess();
10
11
  __HAL_RCC_LSEDRIVE_CONFIG(RCC_LSEDRIVE_LOW);
12
13
    /**Initializes the CPU, AHB and APB busses clocks 
14
    */
15
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE|RCC_OSCILLATORTYPE_MSI;
16
  RCC_OscInitStruct.LSEState = RCC_LSE_ON;
17
  RCC_OscInitStruct.MSIState = RCC_MSI_ON;
18
  RCC_OscInitStruct.MSICalibrationValue = 0;
19
  RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_6;
20
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
21
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_MSI;
22
  RCC_OscInitStruct.PLL.PLLN = 16;
23
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV7;
24
  RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
25
  RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
26
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
27
  {
28
    _Error_Handler(__FILE__, __LINE__);
29
  }
30
31
    /**Initializes the CPU, AHB and APB busses clocks 
32
    */
33
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
34
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
35
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
36
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV2;
37
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
38
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
39
40
  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
41
  {
42
    _Error_Handler(__FILE__, __LINE__);
43
  }
44
45
  HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_SYSCLK, RCC_MCODIV_1);
46
47
    /**Configure the main internal regulator output voltage 
48
    */
49
  if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1) != HAL_OK)
50
  {
51
    _Error_Handler(__FILE__, __LINE__);
52
  }
53
54
    /**Configure the Systick interrupt time 
55
    */
56
  HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
57
58
    /**Configure the Systick 
59
    */
60
  HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
61
62
    /**Enable MSI Auto calibration 
63
    */
64
  HAL_RCCEx_EnableMSIPLLMode();
65
66
  /* SysTick_IRQn interrupt configuration */
67
  HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
68
}

von Mr. Big (Gast)


Lesenswert?

Dr. Sommer schrieb:
> Mr. Big schrieb:
>> Drei Faktoren? Also das schaffen ja schon Grundschüler in 30 Sekunden.
> Ok, mit welcher Formel erhält man die direkt? Selbst CubeMX probiert
> anscheinend einfach nur alle möglichen Kombinationen durch. Man muss ja
> gewisse Randbedingungen bachten (max. Frequenz, Faktoren sind ganze
> Zahlen, haben Minimum/Maximum).


Reference Manual Seite 194-197, in epischer Breite sind die Bits des PLL 
configuration register erklärt. Da kann man nichts missverstehen.


> Mr. Big schrieb:
>> Und schau mal, wie lange R.H. schon erfolglos damit rummacht...
> Noch ist nicht gesagt dass CubeMX schuld ist.


Sage ich auch gar nicht. Ich sage, dass mit "von-Hand-Programmierung" 
und dem Reference Manual schon das Ding wie gewünscht laufen würde.

von Dr. Sommer (Gast)


Lesenswert?

R. H. schrieb:
> in jeder if Bedingung wo error handler steht habe ich einen
> Breakpoint...

Das interessante passiert in den Funktionen HAL_RCC_OscConfig und 
HAL_RCC_ClockConfig. Einfacher und sicherer statt Breakpoints ist es, 
den Code durchzusteppen und zu sehen wo er in Fehler-Handler geht.

von Mr. Big (Gast)


Lesenswert?

R. H. schrieb:
>
1
>   RCC_OscInitStruct.OscillatorType = 
2
> RCC_OSCILLATORTYPE_LSE|RCC_OSCILLATORTYPE_MSI;
3
>   RCC_OscInitStruct.LSEState = RCC_LSE_ON;
4
>   RCC_OscInitStruct.MSIState = RCC_MSI_ON;
5
>   RCC_OscInitStruct.MSICalibrationValue = 0;
6
>   RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_6;
7
>   RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
8
>   RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_MSI;
9
>   RCC_OscInitStruct.PLL.PLLN = 16;
10
>   RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV7;
11
>   RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
12
>   RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
13
>


Wie geschrieben, kenne ich mich mit dem ST-Bloat nicht aus, aber wird da 
MSIPLLEN irgendwo implizit gesetzt oder muss das auch über diese üblen 
structs erst gesetzt werden?

von R. H. (breezer)


Lesenswert?

Mr. Big schrieb:
> Wie geschrieben, kenne ich mich mit dem ST-Bloat nicht aus, aber wird da
> MSIPLLEN irgendwo implizit gesetzt oder muss das auch über diese üblen
> structs erst gesetzt werden?

Ich denke durch diese Funktion:
1
HAL_RCCEx_EnableMSIPLLMode();

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.