Kannst du dir nicht wenigstens Punkt 5 der universellen Forumsregeln merken ?
Die fünf universellen Forumsregeln :
Threadüberschrift lesen
Evtl. Datum beachten
Posting verstehen
Falls nicht 3., dann nachfragen oder Klappe halten.
Auf die Fragen eingehen und / oder Alternativen bzw. Verbesserungen
nennen.
Die Punkte kann man an einer Hand abzählen und deshalb evtl. gut merken,
wenn nicht dann nur Punkt 3 und Punkt 4 merken.
Der Fehler ist natürlich nicht weg, sondern taucht bei der Konstellation nicht auf. Wenn ich OCR3A z.B. mit 694 lade ist er wieder da.
Das ganze dient zum Erkennen, wann meine Schrittmotorkonstruktion anfängt Schritte zu verlieren. Es wird die FastPWM Mode 15-Kurve ohne Vorteilung mit einem CPU-Takt von 16MHz druchlaufen.
Dazu lasse ich den SM einen bestimmten Kurvenbereich abfahren, dann sofort zurück und hiernach wird ca. 1,5 Sekunden gewartet bis es von neuem losgeht.
Aber sporadisch läuft die Sache dann schief. Dort im leider schlechtem Video kann man es sehen :
Die Print::print() werden sofort ausgeführt.
Es wird ein char/uint8_t Ringbuffer mit den Ausgaben gefüllt.
Die Probleme/Blockaden entstehen, wenn der Ringbuffer voll ist.
Seltsam, ich hatte doch 3 weitere Print-Befehle hinzugefügt, da hätte der Fehler demnach erst recht auftauchen müssen.
Auch da sich Ausgaben des Hauptprogramms und Ausgaben in der ISR
vermischen können/werden.
Das Hauptproblem ist halt, dass stepCount entweder nachgeladen oder mit einem falschen Wert geladen wird. Das kann ich halt nicht festellen.
Ich verstehe halt nicht wie dies sein kann.
Nur bei stepCount == 0, wird ja die entscheidene Loop-Routine durchlaufen und nur wenn dann auch die Richtung stimmt, wird stepCount neu geladen.
Da wird wohl irgend ein Interrupt dazwischenfunken, aber dass dürfte doch egal sein, wenn dieser IRQ nicht die selbe Varialbe ( stepCount ) nutzt oder ?
Da muss auch eine Interruptsperre drumherum. Denn sonst kann die Variable beim Lesen verändert werden.
Angenommen, StepCount hat vor dem if-Befehl gerade den Wert 256 (hex: 00 00 01 00). Nun werden die vier Bytes nacheinander von rechts nach links gelesen:
Viertes Byte: 00
Jetzt kommt ein Interrupt, welcher den Wert auf 255 ändert (hex: 00 00 00 FF)
Drittes Byte: 00
Zweites Byte: 00
Erstes Bytes: 00
Alle vier haben "scheinbar" den Wert 0, die if-Bedingung ist erfüllt. Dann kommt die korrekte Ausgabe der Variable.
Anmerkung:
Wenn die Intervalle zwischen den Interrupts kürzer wären, könnte auch die Ausgabe mittels Serial.print(steCount) gestört werden.
Es gibt sehr spezielle Ausnahmen, wo das nicht nötig ist, aber das ist
eher ein Thema für fortgeschrittene Programmierer.
Ihr könnte das ja gerne in einem weiter führenden Thread ausdiskutieren. Das letzte mal ist immerhin länger als ein Monat her. Aber seid dem Bernd bitte nicht böse, wenn er an diesem Detail (gerade) kein Interesse hat.
Aber seid dem
Bernd bitte nicht böse, wenn er an diesem Detail (gerade) kein Interesse
hat.
Ich glaube nicht, dass es deine Entscheidung ist, was ihm schmeckt, oder auch nicht.
Weiterhin:
Es gibt diese schönen Makros.
Also kann man sie auch verwenden.
Ist nicht so dolle eigenbrötlerisch denn es nutzt einen dokumentierten und ausgetretenen Pfad.
Dann brauchts auch kein volatile.
Man/Bernd muss noch nicht mal verstehen, was die Makros "wirklich" tun.
Disclaimer: Dieses ist ein Rat. Ein kostenloser Rat.
PS:
Dass ihm da schlampig vorgegangen ist, sollte ihm auch mittlerweile klar geworden sein.
Angenommen, StepCount hat vor dem if-Befehl gerade den Wert 256 (hex: 00
00 01 00). Nun werden die vier Bytes nacheinander von rechts nach links
gelesen:
Viertes Byte: 00
Jetzt kommt ein Interrupt, welcher den Wert auf 255 ändert (hex: 00 00
00 FF)
Drittes Byte: 00
Zweites Byte: 00
Erstes Bytes: 00
Alle vier haben "scheinbar" den Wert 0, die if-Bedingung ist erfüllt.
Dann kommt die korrekte Ausgabe der Variable.
Vielen dank für diese verständliche Erklärung.
Habe dies umgesetzt und es scheint die Ursache gewesen zu sein.
Bisher 140 Errorzählungen ohne Fehler auch beim Verfahren des SM.
1
int32_ttmp;
2
3
cli();
4
tmp=stepCount;// Ein verfaelschen durch ISR verhindern
5
sei();
6
7
if(tmp==0){
Ach, in diesem Zusammenhang fällt mir ein:
Ist der Zugriff in C auf 16-Bit Register bzw. Variablen schon von Haus aus geschützt oder müsste ich dies auch per Interruptsperre schützen?
Eine eigene Frage?
Dieser Thread ist über 3 Jahre alt.
Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.