Auf meiner Platine habe ich einen komischen Effekt, wenn ich mittels LED
einen Fehler anzeigen möchte.
1
voiderror(intcode){
2
while(1){
3
for(inti=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.
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.
> 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.
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.
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?
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!
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.
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!
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.