LED und HAL_Delay Fehler (STM32F7)

Gast #5707266
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.
#5707365
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.
Gast #5707385
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.
Gast #5707454
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?
Gast #5707507
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!
Gast #5707522
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.

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