Hallo, wir haben hier im Kollegium ein etwas undurchsichtiges Problem. Innerhalb des "normalen" Programms (Atmega1280 mit winAVR) wird ein Vergleich von zwei uint16 durchgeführt. sporadisch wird aber 512>680 als true erkannt und dann die entsprechende Routine ausgeführt. Da für den Vergleich intern ja das C-Flag benutzt wird, könnte ich mir vorstellen, dass das SREG von einer der vielen ISR verbröselt wird. Und hier beginnt der Glaubenskrieg. Sollte man das SREG in der ISR zwischenspeichern um es am Ende der ISR wieder unverändert zu haben? Gruß Thomas
Wenn die ISR in C geschrieben ist, dann macht das der Compiler selbst. Das ist nur nötig, wenn die ISR in Assembler geschrieben ist. Es könnte also eher sein, dass der Inhalt des Speichers (Register,Stack), in dem das SREG vom Compiler gesichert wird, dank irgendeines Programmfehlers zerstört wird.
ist in C geschrieben Im Listing sehe ich eine Menge Register die auf den Stack geschoben werden, aber keine Sicherung von SREG
Thomas Schulz wrote: > sporadisch wird aber 512>680 als > true erkannt ... Meine Glaskugel meint, dass du den Vergleich selbst nicht gegen das Eindringen eines Interrupts ,,in die Mitte des Vergleichs'' abgesichert hast. Schau dir mal den Header <util/atomic.h> an. http://www.nongnu.org/avr-libc/user-manual/group__util__atomic.html
Die SPannende Frage ist: werden die Variablen, die du vergleichst in der ISR benutzt? Wenn ja, könnte ein Interrupt "Mitten im Vergleich" die Ursache sein. Außerdem sollten die Variablen dann als volatile deklarier sein.
Hallo und vielen Dank für den richtigen Denkanstoss! Die Ursache konnte heute gefunden werden: Scheinbar hat wirklich die ADC-ISR in mitten des Vergleiches die Werte geändert. Dadurch konnte mit einem Breakpoint ->nach<- diesem Vergleich auch nur noch den nun wieder neuen Wert angezeigt werden - der alte war mittlerweile schon wieder in der Variable überschriben worden. Durch ein cli()/sei() in dieser Funktion konnte schonmal der richtige Wert angezeigt werden, der für den Einsprung in die if/then verantwortlich war. Nachdem das schonmal geklärt wurde, ist nun nur der ADC-Interrupt kurzzeitig ausgeschaltet worden und alles läuft wieder wie es sollte. Die Suche danach war wirklich sehr mühsam, da man zudem noch den Optimizer aus schalten mußte um richtig Debuggen zu können... Viele Grüße Björn
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.