Forum: Mikrocontroller und Digitale Elektronik LED und HAL_Delay Fehler (STM32F7)


von kpw (Gast)


Lesenswert?

Auf meiner Platine habe ich einen komischen Effekt, wenn ich mittels LED 
einen Fehler anzeigen möchte.
1
void error(int code) {
2
  while (1) {
3
    for (int i = 0; i < code; ++i) {
4
      GPIOH->BSRR = 0x0002;
5
      HAL_Delay(500);
6
      GPIOH->BSRR = 0x00020000;
7
      HAL_Delay(400);
8
    }
9
    HAL_Delay(1500);
10
  }
11
}

An H2 hängt eine LED. Ich hoffe, das ist so i.O., da ich den HSI 
verwende. H2 ist korrekt als Output konfiguriert.

Wenn ich error(1) aufrufe, erhalte ich je nach den Werten in den 
HAL_Delays entweder eine konstant leuchtende LED, oder die LED glimmt 
kurz ganz schwach auf.

Auf einer früheren Platinen-Version funktionierte das, aber da hatte ich 
einen anderen Pin verwendet.

Liegt das nun wirklich am H-Port? Im Datenblatt steht m.W. nichts dazu.

von Harry L. (mysth)


Lesenswert?

kpw schrieb:
> GPIOH->BSRR = 0x0002;
>       HAL_Delay(500);
>       GPIOH->BSRR = 0x00020000;

Einmal 0x0002 und einmal 0x00020000 ?!

Dir ist schon klar, daß du so nicht den selben Pin ansprichst?

Ausserdem solltest du dir dringend diese MagicNumbers abgewöhnen und 
sinnvolle Macros nutzen, dann kommt es auch nicht zu solchen Fehlern!.

Warum du für die Pin-Funktionen nicht HAL_GPIO_WritePin nutzt, wenn du 
schon HAL verwendest ist mir vollkommen schleierhaft.

Wenn du die Initialisierung mit CubeMX generiert hast, findest du in 
Inc/main.h sogar schon fertig definierte Makros für Port und Pin deiner 
LED.

von Stefan F. (Gast)


Lesenswert?

> Dir ist schon klar, daß du so nicht den selben Pin ansprichst?

Doch das ist schon richtig. Das eine Bit setzt den Pin auf High, das 
andere setzt ihn auf Low.

Hast du die Funktion eventuell aus einer ISR heraus aufgerufen oder 
vorher Interrupts gesperrt? Diese Delay Funktion hängt davon ab, das der 
Systick Timer läuft und seine Interrupts bedient werden.

> Liegt das nun wirklich am H-Port? Im Datenblatt steht m.W. nichts dazu.

Hättest du das konkrete Modell genannt, könnten wir beim gucken helfen.

von kpw (Gast)


Lesenswert?

Harry L. schrieb:
> Ausserdem solltest du dir dringend diese MagicNumbers abgewöhnen und
> sinnvolle Macros nutzen, dann kommt es auch nicht zu solchen Fehlern!.

Ich habe hier mein Makro ersetzt, damit man sieht, was passiert.

von Stefan K. (stefan64)


Lesenswert?

Solltest Du für H2 nicht 0x0004 verwenden?

H0 -> 0x0001
H1 -> 0x0002
H2 -> 0x0004


Gruß, Stefan

von kpw (Gast)


Lesenswert?

Stefanus F. schrieb:
> Hast du die Funktion eventuell aus einer ISR heraus aufgerufen oder
> vorher Interrupts gesperrt? Diese Delay Funktion hängt davon ab, das der
> Systick Timer läuft und seine Interrupts bedient werden.

Ja, das ist es!

Während der Schleife sind div. Interrupts aktiv, und die haben eine 
höhere Priorität als Systick, da sie keine Unterbrechung vertragen. Ich 
kann nicht genau schätzen, wieviel Zeit in einem Handler verbracht wird, 
aber ich denke es sind weniger als 50%.

Die error() Funktion selbst wird aus main.c aufgerufen, vor der großen 
While-Schleife.

Wenn ich nun in error() die Interrupts (also nicht Systick) deaktiviere, 
funktioniert alles wie es soll.

Dann ist für mich der Fall gelöst, und ich muß nur aufpassen, wenn ich 
an anderen Stellen HAL_Delay verwenden möchte.

Ich vermute, bei Verwendung von Timern habe ich das gleiche Problem?

von kpw (Gast)


Lesenswert?

Stefan K. schrieb:
> Solltest Du für H2 nicht 0x0004 verwenden?

Ja, aber. Im Original-Code verwende als Makro LED2 und LED2OFF, da es 
noch LED1 gibt, deshalb habe ich beim Übertragen einen Denkfehler 
gemacht.

H1 (und dann 0x0002) ist natürlich richtig. Danke für den Hinweis!

von Stefan F. (Gast)


Lesenswert?

kpw schrieb:
> Während der Schleife sind div. Interrupts aktiv

Dennoch kann der Systick Timer funktionieren - es sei denn, deine 
Interrupthandler verbrauchen bereits die gesamte CPU Zeit. Das kann wohl 
kaum so gewollt sein.

von kpw (Gast)


Lesenswert?

Stefanus F. schrieb:
> kpw schrieb:
>> Während der Schleife sind div. Interrupts aktiv
>
> Dennoch kann der Systick Timer funktionieren - es sei denn, deine
> Interrupthandler verbrauchen bereits die gesamte CPU Zeit. Das kann wohl
> kaum so gewollt sein.

Du meinst, der muss nur ab und zu zum Zuge kommen, also sagen wir mal 
jede us? Wenn dem so wäre, müsste ich mal schauen, ob ich nicht aus 
Versehen einen Dauerläufer habe!

von Stefan F. (Gast)


Lesenswert?

kpw schrieb:
> Du meinst, der muss nur ab und zu zum Zuge kommen, also sagen wir mal
> jede us?

ja

> Wenn dem so wäre, müsste ich mal schauen, ob ich nicht aus
> Versehen einen Dauerläufer habe!

Darauf wollte ich hinaus. Wenn deine Interrupt-Handler die gesamte CPU 
Zeit auf braucht, kann nichts mehr mit dem korrekten Timing ablaufen. 
Auch nicht dieser eine "exklusive" Interrupthandler.

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.