Forum: Compiler & IDEs Bei for-Schleife hängt das Programm


von Thomas D. (Gast)


Lesenswert?

int main(void)
{
  DDRC=0xFF;
  unsigned int counter,j;
  for (i=0;i<=64000;i++) {;}
  //for (counter=0;counter<=255;counter++) asm volatile("NOP");
  DDRD=0xFF;
  PORTD=0xFF;
  while (1) {}
  return 0;
}

An  der Schleife hängt das Programm. Wenn ich die Zeile rausnehme, dann
kann man das "FF" an PORTD messen.
Habe schon mehrere for-Varianten probiert, hatte aber alles den
gleichen Effekt. Wo liegt mein Fehler?
(ATmega8, WinAVR)

von Hofer (Gast)


Lesenswert?

Von welchem Typ ist die Variable i?

Wenn sie char oder int ist, wird sie nie den Wert 64000 erreichen,
dann hast Du eine Endlosschleife.
Wenn dann unsigned int.

von Thomas D. (Gast)


Lesenswert?

Tausend Dank, das war das Problem!

von Thomas D. (Gast)


Lesenswert?

Die erste for-Schleife wird ausgeführt, aber an der zweiten (die ist
identisch) bleibt er hängen. Hab ich irgendwas nicht beachtet?

#include <avr/io.h>
#include <stdint.h>
//#include "lcd-atmega8.h"

int main(void)
{
  unsigned int i;
  for (i=0;i<=64000;i++) {;}
  PORTD = 0xAA;
  for (i=0;i<=64000;i++) {;}
  PORTD = 0xFF;
  while (1) {}
  return (0);
}

von A.K. (Gast)


Lesenswert?

Die Sache mit dem NOP würde ich weiterverfolgen, Denn ohne NOP kann so
ungefähr alles dabei rauskommen. Inklusive Rauswurf der ganzen
Schleife, weil nachweislich komplett überflüssig (soweit der Compiler
das erkennen kann).

In dem Fall hast Du etwas Glück: er lässt von der Schleife noch was
übrig. Aber nicht alles. Aus nicht leicht nachvollziehbarem Grund
addiert er 7 pro Iteration, optimiert die Schleife also runter auf
64000/7 Durchläufe. Ob's ein Zufall ist, dass die Schleife 7 Takte
braucht? Jedenfalls kommt so bei 8MHz eine Wartezeit von 8ms raus. Ob
Du davon was siehst?

von Thomas D. (Gast)


Lesenswert?

<i>Inklusive Rauswurf der ganzen Schleife, weil nachweislich komplett
überflüssig (soweit der Compiler das erkennen kann).</i>

Ja, die ist hier überflüssig. Das war auch nur ein Test, weil ich eine
Verzögerungsprozedur machen wollte. Aus der ist er jedoch nicht mehr
zurückgekehrt (tut er immer noch nicht - auch mit "nop").

Ich verstehe jedoch nicht, wieso er bei der ersten Anweisung
weiterkommt, und bei der zweiten nicht, obwohl er beides gleich
übersetzt:
  for (i=0;i<=64000;i++) {asm volatile("NOP");}
  78:  80 e0         ldi  r24, 0x00  ; 0
  7a:  90 e0         ldi  r25, 0x00  ; 0
  7c:  00 00         nop
  7e:  01 96         adiw  r24, 0x01  ; 1
  80:  2a ef         ldi  r18, 0xFA  ; 250
  82:  81 30         cpi  r24, 0x01  ; 1
  84:  92 07         cpc  r25, r18
  86:  d0 f3         brcs  .-12       ; 0x7c

Wer kann mir einen Tipp geben?

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Warum er dabei hängen soll, kann ich mir auch nicht vorstellen, der
generierte Code sieht OK aus.

Anyway, für definierte Verzögerungen sieh' dir mal <avr/delay.h> an.

von Thomas D. (Gast)


Lesenswert?

>Anyway, für definierte Verzögerungen sieh' dir mal <avr/delay.h> an.

Danke, damit scheints wirklich zu funktionieren!
In der Unit steht, man solle die Taktfrequenz angeben (#define F_CPU
1000000UL). Was bedeutet das "UL" am Ende der Zahl?

von Mike (Gast)


Lesenswert?

unsigned long

von Thomas D. (Gast)


Lesenswert?

thx

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.