Bei for-Schleife hängt das Programm

Gast #237127
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)
Gast
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.
Gast
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);
}
Gast
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?
Gast
<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?
Gast
>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?

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 21 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.