Forum: Compiler & IDEs Hauptprogramm warten lassen


von Nico (Gast)


Lesenswert?

Ich lasse in einem Timer Interrupt die Variable (uint16_t) zeit 
hochzählen. Das Hauptprogramm soll solange warten bis der Wert 750 
erreicht ist.

While (zeit<750);

Weder im Simulator, noch in der Hardware funktioniert das. Die 
While-Schleife wird nie verlassen, auch „zeit“ größer als 750 wird. Aber 
warum?

von Nico (Gast)


Lesenswert?

Falls der Letzte Satz unverständlich war:

Die While-Schleife wird nie verlassen, auch wenn „zeit“ größer als 750 
wird. Aber warum?

von kosmonaut pirx (Gast)


Lesenswert?

hallo,
ohne glaskugel ganz schwer zu sagen. vll das volatile-procedere, vll 
auch nicht.

poste bitte ein "funktionierendes" und aussagekräftiges beispiel deines 
codes.
danke.

bye kosmo

von Johannes M. (johnny-m)


Lesenswert?

kosmonaut pirx wrote:
> hallo,
> ohne glaskugel ganz schwer zu sagen. vll das volatile-procedere, vll
> auch nicht.
Der Zusammenhang lässt erahnen, dass tatsächlich die Variable nicht 
volatile deklariert ist.

2:0 für volatile...

von Nico (Gast)


Lesenswert?

Ich habe den Fehler jetzt mit Hilfe des Disassembler gefunden:

87:            while (zeit<750) ;
+0000017C:   91800060    LDS     R24,0x0060       Load direct from data 
space
+0000017E:   91900061    LDS     R25,0x0061       Load direct from data 
space
+00000180:   E022        LDI     R18,0x02         Load immediate
+00000181:   3E8E        CPI     R24,0xEE         Compare with immediate
+00000182:   0792        CPC     R25,R18          Compare with carry
+00000183:   F3E0        BRCS    PC-0x03          Branch if carry set
+00000184:   E020        LDI     R18,0x00         Load immediate
+00000185:   E2E0        LDI     R30,0x20         Load immediate
+00000186:   E4FE        LDI     R31,0x4E         Load immediate

Das Problem ist, dass der Sprungbefehl nur 3 Befehle zurück reicht. Es 
müssten die Register R24 und R25 aber wieder neu aus dem Speicher 
geladen werden. Es müssten also die ersten zwei LDS Befehle auch wieder 
ausgeführt werden. Wie mache ich das dem Compiler klar? Er rechnet 
anscheinend nicht damit das ein Interrupt den Speicher ändern könnte.

von Johannes M. (johnny-m)


Lesenswert?

Nico wrote:
> Das Problem ist, dass der Sprungbefehl nur 3 Befehle zurück reicht. Es
> müssten die Register R24 und R25 aber wieder neu aus dem Speicher
> geladen werden. Es müssten also die ersten zwei LDS Befehle auch wieder
> ausgeführt werden. Wie mache ich das dem Compiler klar? Er rechnet
> anscheinend nicht damit das ein Interrupt den Speicher ändern könnte.
Wie oben schon angedeutet: Indem Du die Variable "zeit" volatile 
deklarierst. Dann weiß der Compiler auch, dass diese Variable sich 
außerhalb seines Einflussbereiches ändern kann.

von Nico (Gast)


Lesenswert?

Vielen Dank, Ich musste „Zeit“ einfach als volatine deklarieren.
So ist das leider beim Studium, dort lernt man das zwar mal alles, aber 
nur theoretisch. Erst wenn man praktisch solche Probleme hat weis man 
für was solche Befehle gut sind.

von Johannes M. (johnny-m)


Lesenswert?

Nico wrote:
> Vielen Dank, Ich musste „Zeit“ einfach als volatine deklarieren.
> So ist das leider beim Studium, dort lernt man das zwar mal alles, aber
> nur theoretisch. Erst wenn man praktisch solche Probleme hat weis man
> für was solche Befehle gut sind.
"volatile" ist kein Befehl, sondern ein Typqualifizierer. Allerdings 
frage ich mich, warum Du die beiden ersten Antworten anscheinend einfach 
ignoriert hast. Da stand doch schon alles...

von Nico (Gast)


Lesenswert?

Weil ich nicht damit gerechnet habe so schnell eine Antwort zu bekommen 
und hatte desshalb eure antworten noch nicht gelesen.

von Johannes M. (johnny-m)


Lesenswert?

Nico wrote:
> Weil ich nicht damit gerechnet habe so schnell eine Antwort zu bekommen
> und hatte desshalb eure antworten noch nicht gelesen.
Mist, wir sind zu schnell...;-)

von Nico (Gast)


Lesenswert?

oder ich zu langsam ;)

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.