Hallo, mir ist etwas widerfahren, was ich mir beim besten Willen nicht erklären kann. Ich programmiere den ATMega16 in avr-gcc. Einige Zählvaraiablen (long int), die vorher mit i, k, usw. benannt waren, habe ich umbenannt in Count1, Count2, ... um die Aussagekraft zu erhöhen. Dabei ist mir ein Ersetzungsfehler unterlaufen: ... for (Count1=0;Count1<6;Count1++) { LED[Count1] anmachen // Verzögerungsschleife for (Count2=0;Count2<15000;Count2++) { Delay++; } LED[Count1] ausmachen } ... while(1) { ... for (Count1=0;Count2<15000;Count2++) ... } Vor der Endlosschleife wird eine Kaskade von 6 LEDs über ein Schieberegister einmal von links nach rechts zum Aufleuchten gebracht. In der for-Schleife der Endlosschleife müsste richtigerweise 'Count2=0' statt 'Count1=0' stehen. Das wirkt sich in der fehlerhaften Version so aus, dass der Aufleuchte-Vorgang der LEDs, der vor der Endlosschleife steht, dann dreimal so lang dauert. Wie kann es sein, dass ein logischer Fehler in einem sequentiellen Programm sich auf eine vorher abgearbeitete Anweisung auswirkt? Verletzt das nicht das Kausalitätsprinzip? Hat irgendjemand eine Idee? Gruß Jörg
Ich vermute, dass Du nur den Optimizer strapazierst. Denn wenn "Count2" und "Delay" nicht als "volatile" deklariert sind, dann ist for (Count2=0;Count2<15000;Count2++) { Delay++; } aus Sicht des Compilers funktionell identisch mit Count2 = 15000; Delay += 15000; und je nach Kontext, Laune und Wasserstand kann es sein, dass der Compiler das mal wegoptimiert, mal nicht. Daher: Delay-Funktion der Library verwenden.
Wenn man jetzt noch wüsste wie die heißt ^^ Ich weiss es zB nicht und wäre davon ausgegangen das man einen timer benutzen muss für sowas...
Siehe Doku der avr-libc, unter "Busy-wait delay loops". Oder <avr/delay.h> Timer nur nötig, wenn man zwischendurch besseres zu tun hat als einfach nur Schleifchen zu drehen.
Hi, was macht denn das "Delay++;"? müsste dort nicht Count2++; stehen? cu
Nö, das steht ja in der for-Schleifen-Bedingung for (Count2=0;Count2<15000;>>>Count2++<<<) Startwert; Endwert; Erhöhung, wenn überhaupt
@jupp Das Delay++ war dafür gedacht, dass die Schleife nicht wegoptimiert wird, obwohl die Gefahr lt. A.K. ja trotzdem besteht. @alle Das scheint mir aber bei mir nicht der Fall zu sein. Denn der von mir oben beschriebene schnellere Fall, zeigt die LEDs immer noch deutlich länger als wenn nur die beiden Befehle: Count2 = 15000; Delay += 15000; statt der Schleife ausgeführt werden. Was höchstens sein könnte ist, dass beim schnelleren Fall die Schleife zu: for (Count2=0;Count2<15000;Count2++) { } Delay+= 15000; teiloptimiert wird und im langsamen Fall unverändert als for (Count2=0;Count2<15000;Count2++) { Delay++; } ausgeführt wird. Die *.lst scheint mir die Assemblerdatei zu sein, die man diesbezüglich untersuchen sollte, oder? Gruß Jörg
"Die *.lst scheint mir die Assemblerdatei zu sein, die man diesbezüglich untersuchen sollte, oder?" Ja. Generell empfiehlt sich aber, erkennbar sinnlosen Code entweder ganz zu vermeiden, oder dem Compiler unter Verwendung von "volatile" die Optimierung abzugewöhnen. Alles andere ist ausgesprochen fragil.
In der lst-Datei finde ich die Zeile ldi r24,lo8(14999) Ich konnte dieses 'lo8' (und auch 'hi8', das auch vorkommt) weder im Datenblatt des ATMega, noch im 'Instruction Set' von Atmel noch in 'io.h' oder 'iom16.h'. Kannst Du mir vielleicht sagen, was deren Bedeutung ist und wo ich hätte suchen müssen? Gruß Jörg
Hallo das soll jetzt nicht in eine Assembler-Fragestunde ausarten, aber auf Seite 120 des Atmel-Instruction-Set steht für den Befehl 'SBIW', dass dort zwingend immer ein Register-Paar übergeben werden muss, als Beispiel ist dort 'sbiw r25:r24,1' angegeben. In meinem lst-File taucht aber die Zeile sbiw r24,1 auf. Widerspricht dies nicht den obigen Angaben? Gruß Jörg
nein es wird einfach Rd udn Rd-1 genommen (mein ich steht auch so im InstructionSet) ist sozusagen "optional"
Herrje, lo8 und hi8 sind doch ziemlich offensichtlich die unteren 8 Bits und die oberen 8 Bits eines 16-Bit Wertes.
Ja, das ist mir dann auch aufgefallen. Trotzdem sollte diese Syntax doch in irgendeinem Manual erklärt sein oder woher soll man von ihrer Existenz wissen, wenn man sie nicht gerade aus bestehendem Code herausliest. Zwar sind "+" oder "-" auch nicht erklärt, aber lo8 und hi8 haben auch nicht diese Allgemeingültigkeit. In einem DSP-Assembler-Dialekt mit dem ich auch mal gearbeitet habe, gab es lo8 jedenfalls nicht. Gruß Jörg
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.