www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik C-Mysterium beim ATMega16


Autor: Jörg Günzel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: A.K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Marius Schmidt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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...

Autor: A.K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: jupp (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

was macht denn das "Delay++;"?
müsste dort nicht Count2++; stehen?


cu

Autor: David W. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nö, das steht ja in der for-Schleifen-Bedingung
for (Count2=0;Count2<15000;>>>Count2++<<<)
Startwert; Endwert; Erhöhung, wenn überhaupt

Autor: jupp (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok! Überzeugt.
Aber was macht denn das Delay++; ??

Autor: Jörg Günzel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@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

Autor: A.K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"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.

Autor: Jörg Günzel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Jörg Günzel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Läubi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
nein es wird einfach Rd udn Rd-1 genommen (mein ich steht auch so im
InstructionSet) ist sozusagen "optional"

Autor: A.K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Herrje, lo8 und hi8 sind doch ziemlich offensichtlich die unteren 8 Bits
und die oberen 8 Bits eines 16-Bit Wertes.

Autor: Jörg Günzel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.