Forum: Mikrocontroller und Digitale Elektronik STM32L073RZ läuft auf HSE nur halb so schnell wie erwartet


von Hans W. (hanswieland)


Angehängte Dateien:

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?
: Bearbeitet durch User
von Wastl (hartundweichware)


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".
von Hans W. (hanswieland)


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
von Veit D. (devil-elec)


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
von Hans W. (hanswieland)


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.
von Hans W. (hanswieland)


Angehängte Dateien:

Lesenswert?

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.
: Bearbeitet durch User
von Hans W. (hanswieland)


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.
von Alexander (alecxs)


Lesenswert?

Hans W. schrieb:
> Was übersehe ich?
1
SET_BIT(RCC->CR, RCC_CR_HSEBYP);
von Hans W. (hanswieland)


Lesenswert?

Alexander schrieb:
> Was übersehe ich?
> SET_BIT(RCC->CR, RCC_CR_HSEBYP);

Haha, echt witzig. Als wäre ich nicht kurz vorher selbst drauf gekommen.

Bonusfrage extra für dich:
Warum ist die Taktfrequenz ohne dieses bit exakt halb so hoch?
: Bearbeitet durch User
von Alexander (alecxs)


Lesenswert?

Hatte sich überschnitten.

Beitrag "STM32 HSE bypass mode"
von Hans W. (hanswieland)


Lesenswert?

Alexander schrieb:
> Beitrag "STM32 HSE bypass mode"

Danke für den Link. Ich hatte den Thread trotz intensiver Suche nicht 
gefunden. Dort hat Gerd eine mögliche Ursache beschrieben und jemand 
hatte den gleichen Effekt.
von Alexander (alecxs)


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?
von Hans W. (hanswieland)


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.
von Ron-Hardy G. (ron-hardy)


Lesenswert?

Hans W. schrieb:
> mal das Ausgangssignal des Oszillators zu
> messen.

Bitte mit 2-Kanal-Oszi damit man Ein-und Ausgang gegenüberstellen kann.
von Alexander (alecxs)


Lesenswert?

Ein- und Ausgang sind klar, interessant wäre die Rückkopplung am OPV.
von Hans-Georg L. (h-g-l)


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;
von Hans W. (hanswieland)


Angehängte Dateien:

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.
: Bearbeitet durch User
Beitrag #8054239 wurde vom Autor gelöscht.
von Hans W. (hanswieland)


Angehängte Dateien:

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.
: Bearbeitet durch User
von Hans-Georg L. (h-g-l)


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.
von Alexander (alecxs)


Lesenswert?

Hans W. schrieb:
> _MAP002.BMP

Ist das die Rückkopplung am Eingang? Da ist wohl nur jeder zweite Peak 
über der Schaltschwelle.
von Hans W. (hanswieland)


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
von Hans W. (hanswieland)


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
von Alexander (alecxs)


Angehängte Dateien:

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.
: Bearbeitet durch User
von Hans W. (hanswieland)


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
von Alexander (alecxs)


Lesenswert?

Muss ja nicht derselbe Eingang sein. OPV haben doch zwei Eingänge, die 
Abbildung ist nur ein Schaltsymbol.
von Hans W. (hanswieland)


Lesenswert?

Alexander schrieb:
> Muss ja nicht derselbe Eingang sein. OPV haben doch zwei Eingänge, die
> Abbildung ist nur ein Schaltsymbol.

Das Ding im Pierce-Oszillator (den wir hier offensichtlich NICHT haben) 
ist kein OPV, sondern ein CMOS Inverter.
: Bearbeitet durch User
von Alexander (alecxs)


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.
von Hans W. (hanswieland)


Lesenswert?

Alexander schrieb:
> Jedenfalls ist mir noch nicht klar wie genau diese Dreiecksspitzen
> rauskommen können

Das werden wir wohl nie erfahren, ohne die Innenschaltung des 
Oszillators zu kennen.
von Hans-Georg L. (h-g-l)


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.
von Hans W. (hanswieland)


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
von Ron-Hardy G. (ron-hardy)


Lesenswert?

Alexander schrieb:
> Jedenfalls ist mir noch nicht klar wie genau diese Dreiecksspitzen
> rauskommen können

deswegen bat ich um eine 2-Kanal-Erfassung um die zeitlichen 
Verhältnisse zu sehen.
von Hans-Georg L. (h-g-l)


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.
von Hans W. (hanswieland)


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
von Bauform B. (bauformb)


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...
von Alexander (alecxs)


Lesenswert?

Im Datenblatt steht etwas von einer 4 MHz Quelle. Wenn die mit 8 MHz vom 
ST-Link übersteuert wird könnte das auch so ein Störbild ergeben.

40 Cent
: Bearbeitet durch User
von Hans-Georg L. (h-g-l)


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.
von Bauform B. (bauformb)


Angehängte Dateien:

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 ;)
von Hans-Georg L. (h-g-l)


Lesenswert?

Bauform B. schrieb:
> 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 ;)
Nö, ich bin Rentner;-)
von Alexander (alecxs)


Angehängte Dateien:

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?
von Hans-Georg L. (h-g-l)


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 ...
von Bauform B. (bauformb)


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.
von Hans W. (hanswieland)


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
von Hans W. (hanswieland)


Angehängte Dateien:

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?
: Bearbeitet durch User
Beitrag #8054702 wurde vom Autor gelöscht.
von Wastl (hartundweichware)


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.
von Alexander (alecxs)


Lesenswert?

Stimmt, ist ein Syntaxfehler auf den niemand geachtet hat, funktioniert 
hier nur zufällig trotzdem.
von Hans W. (hanswieland)


Lesenswert?

Ich bin dann mal weg, habe keinen Bock auf diesen Kindergarten.
von Hans-Georg L. (h-g-l)


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/
von Alexander (alecxs)


Lesenswert?

Bau den Oszillator doch mal simuliert auf, vielleicht in was besserem 
als Falstad, und dann fahre die Spannung mal langsam hoch und 
übersteuere den CMOS Inverter bis das Signal so verzerrt wird wie auf 
_MAP002.bmp
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.