STM32L073RZ läuft auf HSE nur halb so schnell wie erwartet

OP #8053872
Lesenswert?

Ich benutze das Nucleo L073RZ Board mit der Arduino IDE und lasse eine LED blinken:

1
void setup() {    
2
    pinMode(PA5, OUTPUT);
3
}
4

5
void loop() {
6
    digitalWrite(PA5, LOW);
7
    delay(500);
8

9
    digitalWrite(PA5, HIGH);
10
    delay(500);
11
}

Funktioniert bis dahin. Die Blink-Frequenz der LED bestätigt, dass das Setup korrekt funktioniert.

Dann habe ich mir den Quelltext der Taktkonfiguration angeschaut und gesehen, dass der Systemtakt vom internen Oszillator HSI (= 16 MHz) bezogen wird. Das möchte ich auf HSE (= 8 MHz vom ST-Link) umstellen.

Aber egal wie ich es versuche, die CPU läuft immer nur halb so schnell wie sie soll.

Versuch 1:

Zuerst habe ich den Code von STM32duino kopiert und modifiziert. Ich habe HSI durch HSE ersetzt und die PLL verdoppelt. Das sollte wieder 32 MHz ergeben, läuft aber nur halb so schnell.

1
void SystemClock_Config(void)
2
{
3

4
  RCC_OscInitTypeDef RCC_OscInitStruct = {};
5
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {};
6
  RCC_PeriphCLKInitTypeDef PeriphClkInit = {};
7

8
  /* Configure the main internal regulator output voltage */
9
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
10

11
  /* Initializes the CPU, AHB and APB busses clocks */
12
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_HSI48;
13
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
14
  //RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
15
  RCC_OscInitStruct.HSI48State = RCC_HSI48_ON;
16
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
17
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
18
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLLMUL_8;
19
  RCC_OscInitStruct.PLL.PLLDIV = RCC_PLLDIV_2;
20
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
21
    Error_Handler();
22
  }
23

24
  /* Initializes the CPU, AHB and APB busses clocks */
25
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK
26
                                | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
27
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
28
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
29
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
30
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
31

32
  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK) {
33
    Error_Handler();
34
  }
35

36
  PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USB;
37
  PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_HSI48;
38
  if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) {
39
    Error_Handler();
40
  }
41
}

Versuch 2: Komplett selbst geschrieben. Sollte 32 MHz ergeben, läuft aber nur halb so schnell.

1
void SystemClock_Config(void) {
2

3
    // Wait until voltage regulator is stabilized
4
    while(READ_BIT(PWR->CSR, PWR_CSR_VOSF)) {}
5

6
    // Switch to voltage scaling range 1
7
    MODIFY_REG(PWR->CR, PWR_CR_VOS, 1 << PWR_CR_VOS_Pos);
8

9
    // Wait until voltage regulator is stabilized
10
    while(READ_BIT(PWR->CSR, PWR_CSR_VOSF)) {}
11

12
    // Enable HSE oscillator
13
    SET_BIT(RCC->CR, RCC_CR_HSEON);
14

15
    // Wait until HSE oscillator is ready
16
    while(!READ_BIT(RCC->CR, RCC_CR_HSERDY)) {}
17

18
    // Switch to HSE oscillator
19
    MODIFY_REG(RCC->CFGR, RCC_CFGR_SW, RCC_CFGR_SW_HSE);
20

21
    // Wait until the switch is done
22
    while ((RCC->CFGR & RCC_CFGR_SWS_Msk) != RCC_CFGR_SWS_HSE) {}
23

24
    // Disable the PLL
25
    CLEAR_BIT(RCC->CR, RCC_CR_PLLON);
26

27
    // Wait until the PLL is fully stopped
28
    while(READ_BIT(RCC->CR, RCC_CR_PLLRDY)) {}
29
   
30
    // Flash latency 1 wait state
31
    SET_BIT(FLASH->ACR, FLASH_ACR_LATENCY);
32

33
    // 32 MHz using the 8 MHz HSE oscillator multiply by 8 divide by 2
34
    RCC->CFGR = RCC_CFGR_PLLSRC_HSE + RCC_CFGR_PLLMUL8 + RCC_CFGR_PLLDIV2;
35

36
    // Enable PLL
37
    SET_BIT(RCC->CR, RCC_CR_PLLON);
38

39
    // Wait until PLL is ready
40
    while(!READ_BIT(RCC->CR, RCC_CR_PLLRDY)) {}
41

42
    // Select PLL as clock source
43
    MODIFY_REG(RCC->CFGR, RCC_CFGR_SW, RCC_CFGR_SW_PLL);
44

45
    // Update system timer
46
    SystemCoreClock=32000000;
47
    SysTick_Config(SystemCoreClock/1000);
48

49
    // Switch the MSI oscillator off
50
    CLEAR_BIT(RCC->CR, RCC_CR_MSION);    
51
}

Versuch 3: Die CPU soll ganz simpel direkt von HSE getaktet werden, ohne PLL. Ich erwarte 8 MHz, sie läuft aber wieder nur halb so schnell:

1
void SystemClock_Config(void) {
2

3
    // Enable HSE oscillator
4
    SET_BIT(RCC->CR, RCC_CR_HSEON);
5

6
    // Wait until HSE oscillator is ready
7
    while(!READ_BIT(RCC->CR, RCC_CR_HSERDY)) {}
8

9
    // Switch to HSE oscillator
10
    MODIFY_REG(RCC->CFGR, RCC_CFGR_SW, RCC_CFGR_SW_HSE);
11

12
    // Wait until the switch is done
13
    while ((RCC->CFGR & RCC_CFGR_SWS_Msk) != RCC_CFGR_SWS_HSE) {}
14

15
    // Update system timer
16
    SystemCoreClock=8000000;
17
    SysTick_Config(SystemCoreClock/1000);
18

19
    // Switch the MSI oscillator off
20
    CLEAR_BIT(RCC->CR, RCC_CR_MSION);    
21
}

Wie gesagt habe ich den HSE Takt mit einem Oszilloskop kontrolliert. Der hat wirklich 8 MHz, so wie es dokumentiert ist.

Was übersehe ich?

Angehängte Dateien:
: Bearbeitet durch User
#8053875
Lesenswert?

Hans W. schrieb:

Was übersehe ich?

Zunächst übersiehst du mal dass dir bei jedem Beitrag, den du schreibst, gesagt wird dass:

"Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang"

Länger bedeuted in diesem Zusammenhang "mehr als eine Bildschirmseite".

Das ist ein Gebot der Freundlichkeit und der Netiquette. Siehe dazu speziell auch "Äußere Form".

OP #8053877
Lesenswert?

Zum Vergleich: Mit dem Nucleo F303RE Board habe ich das Problem nicht. Dort konnte ich problemlos auf den HSE wechseln:

1
    // Enable HSE oscillator
2
    SET_BIT(RCC->CR, RCC_CR_HSEON);
3

4
    // Wait until HSE oscillator is ready
5
    while(!READ_BIT(RCC->CR, RCC_CR_HSERDY)) {}
6

7
    // Switch to HSE oscillator
8
    MODIFY_REG(RCC->CFGR, RCC_CFGR_SW, RCC_CFGR_SW_HSE);
9

10
    // Wait until the switch is done
11
    while ((RCC->CFGR & RCC_CFGR_SWS_Msk) != RCC_CFGR_SWS_HSE) {}
12

13
    // Disable the PLL
14
    CLEAR_BIT(RCC->CR, RCC_CR_PLLON);
15

16
    // Wait until PLL is fully stopped
17
    while(READ_BIT(RCC->CR, RCC_CR_PLLRDY)) {}
18
    
19
    // Flash latency 2 wait states
20
    MODIFY_REG(FLASH->ACR, FLASH_ACR_LATENCY, 2 << FLASH_ACR_LATENCY_Pos);
21
    
22
    // 72 MHz using the 8 MHz HSE oscillator with 9x PLL, lowspeed I/O runs at 36 MHz
23
    RCC->CFGR = RCC_CFGR_SWS_HSE + RCC_CFGR_PLLSRC_HSE_PREDIV + RCC_CFGR_PLLMUL9 + RCC_CFGR_PPRE1_DIV2;
24

25
    // Enable PLL
26
    SET_BIT(RCC->CR, RCC_CR_PLLON);
27

28
    // Wait until PLL is ready
29
    while(!READ_BIT(RCC->CR, RCC_CR_PLLRDY)) {}
30

31
    // Select PLL as clock source
32
    MODIFY_REG(RCC->CFGR, RCC_CFGR_SW, RCC_CFGR_SW_PLL);
33

34
    // Update system timer
35
    SystemCoreClock=72000000;
36
    SysTick_Config(SystemCoreClock/1000);
37
    
38
    // Disable the HSI oscillator
39
    CLEAR_BIT(RCC->CR, RCC_CR_HSION);
: Bearbeitet durch User
#8053885
Lesenswert?

Hallo,

Hans W. schrieb:

Was übersehe ich?

Du hast die Hardwarekonfiguration geändert, nur das Programm selbst weiß noch nichts davon. Funktionen wie delay() beruhen auf der Definition vom CPU Takt. Du müsstest noch #define F_CPU anpassen. Heißt bei AVR so, ob der Name bei STM gleich lautet weiß ich nicht, nehme ich aber stark an.

Edit: Wenn bei STM 'SystemCoreClock' dem AVR 'F_CPU' entspricht und du das geändert hast, dann weiß ich es nicht.

: Bearbeitet durch User
OP #8053891
Lesenswert?

Veit D. schrieb:

Du hast die Hardwarekonfiguration geändert, nur das Programm selbst weiß noch nichts davon. Funktionen wie delay() beruhen auf der Definition vom CPU Takt.

Daran liegt es nicht. Diese Zeilen erledigen das:

SystemCoreClock=72000000; SysTick_Config(SystemCoreClock/1000);

Habe ich mit anderen Frequenzen auf Basis des HSI gegen getestet.

Du müsstest noch #define F_CPU anpassen. Heißt bei AVR so, ob der Name bei STM gleich lautet weiß ich nicht, nehme ich aber stark an.

F_CPU ist als Alias für SystemCoreClock definiert.

OP #8053895
Lesenswert?

Juhuuu, ich hab's gefunden!

falsch:

1
    // Enable HSE oscillator
2
    SET_BIT(RCC->CR, RCC_CR_HSEON);

richtig:

1
    // Enable HSE oscillator
2
    SET_BIT(RCC->CR, RCC_CR_HSEON + RCC_CR_HSEBYP);

Das ist aber echt schräg, dass durch diesen Fehler exakt die halbe Taktfrequenz entsteht. Ich habe dieses HSEBYP Bit noch nie zuvor benutzen müssen. Werde mich jetzt dazu einlesen.

Beitrag #8053897 wurde vom Autor gelöscht.
#8054065
Lesenswert?

Nur die Erklärung habe ich nicht verstanden. Die Schmitt‑Trigger Hysterese des OPV teilt die Frequenz da nur steigende Flanken überhaupt erkannt werden. Bei jeder Flanke wird getoggelt. Liegt es daran dass ein PWM ein über 0 geschobenes Signal ist und die negative Welle unter 0 vom echten Sinus die man von einem schwingenden Quarz erwarten würde einfach ausbleibt?

OP #8054177
Lesenswert?

Eine andere mögliche Erklärung wäre, dass der Oszillator das rechteck Signal als Fehler interpretiert und wiederholt Neustarts versucht.

Mein Chef hat angeregt, mal das Ausgangssignal des Oszillators zu messen. Das werde ich heute Abend tun. Bin gespannt, was wir dort zu sehen bekommen.

#8054199
Lesenswert?

Hans W. schrieb:

Ich habe das Problem auch unabhängig von allen Frameworks mit einem minimalen Projekt in der Cube IDE. Auch dieses Programm läuft nur halb so schnell, wie es sollte.

Aus deinem Code: // 32 MHz using the 8 MHz HSE oscillator multiply by 8 divide by 2 RCC->CFGR = RCC_CFGR_PLLSRC_HSE + RCC_CFGR_PLLMUL8 + RCC_CFGR_PLLDIV2;

Schau dir mal das Register im Debugger an was da für bits gesetzt wurden und dann das gleiche mit: RCC->CFGR = RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMUL8 | RCC_CFGR_PLLDIV2;

OP #8054237
Lesenswert?

Hans-Georg L. schrieb:

Schau dir mal das Register im Debugger an was da für bits gesetzt wurden und dann das gleiche mit

Macht keinen Unterschied.

Hans W. schrieb:

mal das Ausgangssignal des Oszillators zu messen. Das werde ich heute Abend tun.

Blöderweise tritt der Fehler heute nicht mehr auf (mit HSEBYP=0).

Ron-Hardy G. schrieb:

Bitte mit 2-Kanal-Oszi damit man Ein-und Ausgang gegenüberstellen kann.

Ich habe einzeln gemessen, weil ich die Tastköpfe sonst nicht sicher hätte halten können. Interessant, dass das Ausgangssignal (2) so einen geringen Pegel hat.

Ich lass das mal eine Weile laufen und behalte die blinkende LED im Blick. Vielleicht kommt der Fehler später doch wieder.

Angehängte Dateien:
: Bearbeitet durch User
Beitrag #8054239 wurde vom Autor gelöscht.
OP #8054257
Lesenswert?

Ich habe nicht bedacht, dass dieses HSEBYP Bit nur mit einem Power-Cycle zurück gesetzt werden kann. Meine Änderung im Code hatte deswegen keine Auswirkung.

Fehler ist wieder da, und jetzt gibt es auch was interessantes zu sehen.

Die Messpunkte sind wieder die gleichen wie in meinem vorherigen Beitrag.

Angehängte Dateien:
: Bearbeitet durch User
#8054261
Lesenswert?

Hans W. schrieb:

Hans-Georg L. schrieb:

Schau dir mal das Register im Debugger an was da für bits gesetzt wurden und dann das gleiche mit

Macht keinen Unterschied.

Glaube ich nicht, denn A+B+C ist ungleich A|B|C
Da fehlt auch noch das verunden mit der Maske die alle PLL Bits (Bit 16 bis 23) vorher löscht. Wahrscheinlich hast du irgendwelche MUX im gleichen Register überbügelt und der Takt kommt vielleicht nicht von der PLL. Vergleiche das komplette Register mit Ref Manual ob alle Bits richtig sind.
Wenn der Chip einen MCO Ausgang hat kannst du den Systemtakt auch ausgeben.

OP #8054273
Lesenswert?

1
// 32 MHz using the 8 MHz HSE oscillator multiply by 8 divide by 2
2
RCC->CFGR = RCC_CFGR_PLLSRC_HSE + RCC_CFGR_PLLMUL8 + RCC_CFGR_PLLDIV2;

Hans-Georg L. schrieb:

A+B+C ist ungleich A|B|C

Trifft hier nicht zu, weil in A B und C keine überlappenden Bits gesetzt sind.

Da fehlt auch noch das verunden mit der Maske die alle PLL Bits (Bit 16 bis 23) vorher löscht.

Nein. Die Zuweisung benutzt keine alten Bits auf dem Register.

Wahrscheinlich hast du irgendwelche MUX im gleichen Register überbügelt und der Takt kommt vielleicht nicht von der PLL.

Nein. Siehe ganz oben mein Gegentest "Versuch 3:".

Vergleiche das komplette Register mit Ref Manual ob alle Bits richtig sind.

Habe ich doch alles gemacht, wozu hat man sonst einen Debugger?

Wenn der Chip einen MCO Ausgang hat kannst du den Systemtakt auch ausgeben.

Damit ich einen dritten Indikator für die halbe Taktfrequenz bekomme? Brauche ich nicht. Der Systick timer und eine einfache erprobte delay-loop genügen mir als Beweis.

Und dann haben wir noch den Screenshot vom Oszilloskop, den ich gerade in Beitrag "Re: STM32L073RZ läuft auf HSE nur halb so schnell wie erwartet" nachgereicht habe.

Können wir jetzt bitte aufhören, von dem eigentlichen Problem abzulenken?

: Bearbeitet durch User
OP #8054277
Lesenswert?

Alexander schrieb:

Ist das die Rückkopplung am Eingang? Da ist wohl nur jeder zweite Peak über der Schaltschwelle.

Habe ich im Schaltplan mit (2) beschriftet. Das ist der OSC_OUT Anschluss.

Ich weiß nicht, was du mit "Rückkopplung" und "Hysterese des OPV" meinst. Ich kann den Chip nicht aufsägen und hinein kriechen.

Aber da dies der Ausgang des Oszillators ist, kann man wohl deutlich sehen, dass er gerade versagt.

: Bearbeitet durch User
#8054289
Lesenswert?

Ich bin einfach mal von einem Pierce-Oszillator ausgegangen. Die Rückkopplung erfolgt über den Widerstand von Ausgang zu Eingang des Operationsverstärkers.

https://electronics.stackexchange.com/questions/214907/need-help-in-creating-and-debugging-a-8mhz-clk-circuit/214913

Die Hysterese ergibt sich aus dem Schnitt-Trigger, der aber anscheinend optional sein kann.

Gustl B. schrieb:

Der Schmitt-Trigger macht einen sauberen Rechteck wenn dein Oszillator einen Sinus ausgibt.

Angehängte Dateien:
: Bearbeitet durch User
OP #8054295
Lesenswert?

Alexander schrieb:

Ich bin einfach mal von einem Pierce-Oszillator ausgegangen. Die Rückkopplung erfolgt über den Widerstand von Ausgang zu Eingang des Operationsverstärkers.

Das Eingangssignal habe ich ja auch dargestellt - ein sauberer Rechteck mit 3,3V Pegeln.

Schau dir nochmal die Bilder in Beitrag "Re: STM32L073RZ läuft auf HSE nur halb so schnell wie erwartet" an. 1=Eingang, 2=Ausgang

Ich denke, damit ist offensichtlich, dass der Oszillator anders aufgebaut ist.

: Bearbeitet durch User
#8054305
Lesenswert?

Okay. Das Schaltzeichen habe ich dann wohl verwechselt. Hatte mich bisher nur mit OPV auseinandergesetzt.

https://www.elektronik-kompendium.de/sites/bau/0209241.htm

Jedenfalls ist mir noch nicht klar wie genau diese Dreiecksspitzen rauskommen können, immer schön ein großer und ein kleiner Peak im Wechsel, wenn das Eingangssignal doch ein Rechtecksignal ist. Da muss es eine Form von Rückkopplung/Verzerrung geben.

#8054359
Lesenswert?

Hans W. schrieb:

Ich habe nicht bedacht, dass dieses HSEBYP Bit nur mit einem Power-Cycle zurück gesetzt werden kann. Meine Änderung im Code hatte deswegen keine Auswirkung.

Fehler ist wieder da, und jetzt gibt es auch was interessantes zu sehen.

Die Messpunkte sind wieder die gleichen wie in meinem vorherigen Beitrag.

Und HSEBYP kann nur geschaltet werden wenn HSE aus ist. Ist der OSC_OUT GPIO richtig geschaltet ?. Sollte kein Ausgang mehr sein und HiZ haben.

OP #8054363
Lesenswert?

Hans-Georg L. schrieb:

Ist der OSC_OUT GPIO richtig geschaltet ?.

Habe ich nicht geändert, also im Zustand wie vom Reset vorgegeben. Einen vollständigen Quelltext hatte ich in Beitrag "Re: STM32L073RZ läuft auf HSE nur halb so schnell wie erwartet" gepostet.

Mit richtig gesetztem HSEBYP=1 kommt da nur ein schwaches Signal raus, siehe Beitrag "Re: STM32L073RZ läuft auf HSE nur halb so schnell wie erwartet" Vermutlich Kapazitives Übersprechen.

: Bearbeitet durch User
#8054388
Lesenswert?

Hans W. schrieb:

Hans-Georg L. schrieb:

Ist der OSC_OUT GPIO richtig geschaltet ?.

Habe ich nicht geändert, also im Zustand wie vom Reset vorgegeben.

Mir kam der Pegel der da rauskommt für reines internes Übersprechen etwas hoch vor ...

Vielleicht probierst du es nochmal mit der HAL. Ich lasse für meine Bords den RCC den Code durch CubeMX als makefile erzeugen, und hatte noch nie Probleme. Habe aber auch kein L073RZ Nucleo-Board nur G4,H4,H7,H7R als Nucleo und andere.

Das würde dann etwa so aus sehen (H7):

1
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
2
  RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS;
3
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
4
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
5
  
6
  // PLL 
7
  ...

Wenn es dann funktioniert durch den Code steppen und genau schauen was der macht.

OP #8054437
Lesenswert?

Hans-Georg L. schrieb:

Vielleicht probierst du es nochmal mit der HAL.

Habe ich doch, mit Cube MX generiert. Damit tritt der gleiche Fehler auf, wenn ich das HSEBYP Bit falsch (nicht) setze. Und mit Arduino ebenso. Und auch ohne Framework.

hatte noch nie Probleme.

Dito. Deswegen hat es mich ja überrascht. Bis vor kurzem dachte ich, dass Bit sei optional und nur dazu da, den externen Ausgang des Oszillators zu deaktivieren.

RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS; Wenn es dann funktioniert durch den Code steppen

Es ist seit Beitrag "Re: STM32L073RZ läuft auf HSE nur halb so schnell wie erwartet" klar, dass es am HSEBYP Bit scheiterte. Hast du nicht gelesen?

: Bearbeitet durch User
#8054478
Lesenswert?

So ein Oszillator muss dafür sorgen, dass der Quarz sicher anschwingt. Aber anschliessend soll die Amplitude möglichst weit reduziert werden um den Quarz nicht zu überlasten und um Strom zu sparen - gerade bei den L Typen.

Also stellt er mit dem externen 3.3 V Rechteck die minimale Verstärkung ein, die ist aber zu klein, also dreht er wieder auf...

Nur meine 2 Cent Theorie...

#8054568
Lesenswert?

Hans W. schrieb:

Habe ich doch, mit Cube MX generiert. Damit tritt der gleiche Fehler auf, wenn ich das HSEBYP Bit falsch (nicht) setze. Und mit Arduino ebenso. Und auch ohne Framework.

Es ist seit Beitrag "Re: STM32L073RZ läuft auf HSE nur halb so schnell wie erwartet" klar, dass es am HSEBYP Bit scheiterte. Hast du nicht gelesen?

Bei mir hat CUBE MX das HSEBYP noch nie falsch gesetzt ;-)

Was mir Heute Morgen noch aufgefallen ist ...
Du setzt den Bypass und den HSE gleichzeitig.
SET_BIT(RCC->CR, RCC_CR_HSEON + RCC_CR_HSEBYP); Im RM steht HSEBTYP kann(soll) nur gesetzt werden wenn HSE off.

Vielleicht gibt es an der Stelle ein überschneiden das den Oszillator hochlaufen lässt und den externen Takt dazu koppelt. Schalte mal erst den HSEBYP und dann den HSE ein. Evtl. noch ein paar Takte warten dazwischen.

#8054602
Lesenswert?

Alexander schrieb:

Im Datenblatt steht etwas von einer 4 MHz Quelle

Auf der Suche nach dieser Quelle fand ich ein Bildnis wunderschön ;)

Hans-Georg L. schrieb:

Du setzt den Bypass und den HSE gleichzeitig. SET_BIT(RCC->CR, RCC_CR_HSEON + RCC_CR_HSEBYP); Im RM steht HSEBTYP kann(soll) nur gesetzt werden wenn HSE off.

Du bist Rechtsanwalt, gib's zu ;)

Angehängte Dateien:
#8054633
Lesenswert?

Bauform B. schrieb:

Auf der Suche nach dieser Quelle fand ich ein Bildnis wunderschön ;)

Pierce-Oszillator mit CMOS-Inverter ohne Hysterese und abschaltbaren Rückkopplungswiderstand?

https://de.wikipedia.org/wiki/Transkonduktanzverstärker

Hans-Georg L. schrieb:

Vielleicht gibt es an der Stelle ein überschneiden das den Oszillator hochlaufen lässt und den externen Takt dazu koppelt.

Könnte man mit einem 4 MHz Takt einen 8 MHz Quarz anschwingen?

Angehängte Dateien:
#8054656
Lesenswert?

Alexander schrieb:

Bauform B. schrieb:

Auf der Suche nach dieser Quelle fand ich ein Bildnis wunderschön ;)

Pierce-Oszillator mit CMOS-Inverter ohne Hysterese und abschaltbaren Rückkopplungswiderstand?

https://de.wikipedia.org/wiki/Transkonduktanzverstärker

Hans-Georg L. schrieb:

Vielleicht gibt es an der Stelle ein überschneiden das den Oszillator hochlaufen lässt und den externen Takt dazu koppelt.

Könnte man mit einem 4 MHz Takt einen 8 MHz Quarz anschwingen?

Siehe: https://www.mikrocontroller.net/attachment/697863/2026-05-26_17-20.png Bei den Nucleo Boards sind die Quarze nicht bestückt. Der extere 8MHz Takt kommt vom MCO Ausgang des STLINK. Und wenn der auf die schon/noch eingeschaltete Oszillatorschaltung trifft regt er die an und das könnte diesen Effekt bewirken, so meine Vermutung. Es ist ja nicht nur der Oscillator, da ist ja auch noch eine Regelung drin. https://www.mikrocontroller.net/attachment/697915/STM32L073-oscillator.png

Wir werden ja sehen ...

#8054667
Lesenswert?

Es gibt noch einen Widerspruch. Die Messung an PF0 und PF1 passt gut zu dem Bild https://www.mikrocontroller.net/attachment/697915/STM32L073-oscillator.png und das Signal am PF1 würde auch den halben CPU-Takt erklären. Im Bild ist "fHSE to core" aber am Eingang des Inverters angeschlossen. Wenn das stimmt, müsste die CPU mit dem vollen Takt laufen.

Den halben Takt gibt es nur am Ausgang des Inverters. Instinktiv hätte ich den Chip auch so verdrahtet. Am Ausgang gibt es ein geregeltes niederohmiges Signal, am Eingang ist das Signal klein und hochohmig und man verstimmt unnötig den Quarz.

OP #8054669
Lesenswert?

Hans-Georg L. schrieb:

Was mir Heute Morgen noch aufgefallen ist ... Du setzt den Bypass und den HSE gleichzeitig. SET_BIT(RCC->CR, RCC_CR_HSEON + RCC_CR_HSEBYP); Im RM steht HSEBTYP kann(soll) nur gesetzt werden wenn HSE off.

Schau dir die Doku des Registers an und den Quelltext der HAL, dann siehst du, dass ich es richtig gemacht habt.

Schalte mal erst den HSEBYP und dann den HSE ein.

Schau dir die Doku des Registers an, dann siehst du ...

HSEBYP kann man nicht einschalten, wenn HSE bereits eingeschaltet ist.

: Bearbeitet durch User
OP #8054698
Lesenswert?

Hans W. schrieb:

Schau dir die Doku des Registers an,

Sorry Hans-Georg, ich habe dich missverstanden. Mir scheint gerade zu viel Sonne auf Dach.

Ich denke, ich könnte wirklich zuerst HSEBYP=1 setzen und danach HSEON=1. Aber wozu? Es funktioniert ja auch so.

===========================

Was ich eigentlich schreiben wollte:

Da hier einige Leute offenbar den Knackpunkt verpasst haben, fasse ich die Situation nochmal zusammen.

Ich war es gewohnt, dass man wahlweise einen Quarz oder eine externe Taktquelle anschließen konnte, wenn HSEBYP=0 ist. Am vergangenen Wochenende klappte das plötzlich nicht mehr, obwohl Board und Quelltext beide alt und erprobt waren.

Symptom: Der Systemtakt ist nur 4 MHz, obwohl die Taktquelle 8 MHz liefert. Das zweite Oszillogramm vom Pin PF1/OSC_OUT bestätigt die Fehlfunktion des fremd getriebenen Oszillators.

Es stellte sich heraus, dass das Problem verschwindet, wenn man das HSEBYP Bit passend zur Schaltung auf 1 setzt. Es ist also doch wichtig.

Bitte hört auf, meine Registerzugriffe zu hinterfragen. Ja, ich hatte anfangs darum gebeten, aber inzwischen ist 100% klar, dass es nur an diesem einem HSEBYP Bit hängt. Und wie man es richtig setzt ist auch klar, dazu brauche ich keine Hilfe.

Wir haben KEIN Softwareproblem mehr.

Die einzige Frage, die man hier noch sinnvoll weiter diskutieren kann, ist: Warum verhält sich der Oszillator so? Was könnte Elektrotechnisch dahinter stecken?

Angehängte Dateien:
: Bearbeitet durch User
Beitrag #8054702 wurde vom Autor gelöscht.
#8054704
Lesenswert?

Hans W. schrieb:

Die einzige Frage, die man hier noch sinnvoll weiter diskutieren kann, ist:

.... ob man beim Setzen eines Registers die Tokens der einzelnen Bits addiert oder ver-odert. Ich sage: nein, addieren von Bits tut man nicht tuten, denn es könnten mal ein paar Bits übereinander liegen und das ergibt dann einen falschen Registerwert und man sucht sich ggf. dumm und dämlich.

#8054726
Lesenswert?

Hans W. schrieb:

snip .....

Was ich eigentlich schreiben wollte:

Da hier einige Leute offenbar den Knackpunkt verpasst haben, fasse ich die Situation nochmal zusammen.

Super !!!

Ich war es gewohnt, dass man wahlweise einen Quarz oder eine externe Taktquelle anschließen konnte, wenn HSEBYP=0 ist. Am vergangenen Wochenende klappte das plötzlich nicht mehr, obwohl Board und Quelltext beide alt und erprobt waren.

Symptom: Der Systemtakt ist nur 4 MHz, obwohl die Taktquelle 8 MHz liefert. Das zweite Oszillogramm vom Pin PF1/OSC_OUT bestätigt die Fehlfunktion des fremd getriebenen Oszillators.

Es stellte sich heraus, dass das Problem verschwindet, wenn man das HSEBYP Bit passend zur Schaltung auf 1 setzt. Es ist also doch wichtig.

Bitte hört auf, meine Registerzugriffe zu hinterfragen. Ja, ich hatte anfangs darum gebeten, aber inzwischen ist 100% klar, dass es nur an diesem einem HSEBYP Bit hängt. Und wie man es richtig setzt ist auch klar, dazu brauche ich keine Hilfe.

Wir haben KEIN Softwareproblem mehr.

Ihr habt kein Softwareproblem mehr schön für euch !

Denke aber bitte mal daran, das dies ein öffentliches Forum ist und Suchmaschinen den Thread finden. Wenn irgenwann mal jemand hier, mit dem gleichen Problem, vorbei kommt, findet er dann die Lösung oder ist er noch mehr verwirrt ?. Deshalb habe ich nachgefragt, und kommentiert, nicht um dich zu ärgern.

Mit dem gleichzeitigen setzen der beiden bits sehe ich noch Probleme. Weil der HSE Zeit braucht um hoch zu laufen, deshalb gibt es die while Schleife zum warten bis das Bit HSE läuft gesetzt ist und ich nehme sehr stark an das dieses Bit zum Sperren des HSEBYP benutzt wird. Was passiert dann bei gleichzeitigen setzen ? Deshalb würde ich es nicht empfehlen. Ok du hast keine Zeit für Versuche zu machen. Vielleicht probiere ich das mal, ich habe hier noch ein Nucleo L476.

Die einzige Frage, die man hier noch sinnvoll weiter diskutieren kann, ist: Warum verhält sich der Oszillator so? Was könnte Elektrotechnisch dahinter stecken?

Das habe ich mir auch überlegt ...

Der 8MHz Takt liegt am Eingang an und regt gleichzeitig die Oszillatorschaltung an, die wiederum über den Rf Widerstand eingekoppelt wird. Aber dann müsste sie doch mit 8MHz schwingen. Woher kommen die 4MHz ? Meine Theorie ist, es verhält sich wie "Injection-locked oscillators". Damit kann man mit 2 Oszillatoren gleicher Frequenz ganzzahlig dividieren.
Das ist reine Spekulation von mir, aber eine andere Lösung ist mir nicht eingefallen. Vielleicht kennt sich da ja Jemand besser aus ...

https://www.hajim.rochester.edu/ece/sites/laics/ilo_fd_m/

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren