Forum: Mikrocontroller und Digitale Elektronik Fehler in For-Schleife?!


von Dominik K (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

ich hab seid gestern ein sehr seltsames Verhalten bei For-Schleifen.
Da es nicht von Anfang an so war vermute ich ich hab etwas an den µC 
Eigenschaften oder direkt an AVR-Studio verstellt ohne es zu merken.
Einen Defekt des µC kann ich ausschließen da sonst alle kaputt sein 
müssten die ich habe, sogar die die noch unbenutzt waren (bis gestern).


Der Fehler tritt bei jeder For-Schleife auf und mit jedem Inhalt.
In dem Bild im Anhang sieht man jetzt folgendes:
1. Durchlauf des Programms ohne For-Schleife (Oder 1x Durchlauf, hat den 
gleiche Effekt)
2. Durchlauf des Programms mit 8x Schleife
3. Durchlauf des Programms mit 16x Schleife

Seht selber! Ich kann mir darauf keinen Reim machem.
Zeit/Div beträgt 20uS

mfg
Dominik

1
#define F_CPU 8000000
2
#include <avr/io.h>
3
#include <util/delay.h>
4
5
#define leds_on()  PORTB |= (1<<PB0) | (1<<PB1);
6
#define leds_off()  PORTB &= ~((1<<PB0) | (1<<PB1));
7
8
int main()
9
  {  
10
  // Ports
11
  DDRB = (1<<PB0) | (1<<PB1);  
12
  PORTB |= (1<<PB2);  
13
14
   while(1)
15
  { 
16
  for(i=0;i<16;i++)
17
  leds_on();  
18
        delay_us(10);  
19
        leds_off();    
20
        _delay_us(10);
21
  }
22
  return 0;

von holger (Gast)


Lesenswert?

Da fehlen {}

von Hc Z. (mizch)


Lesenswert?

Ein Musterbeispiel, warum das richtige Einrücken des Codes nicht 
überflüssig ist und wie man sich mit falschem Einrücken reinlegen kann.

Anders als Deine Einrückungen suggerieren, befindet sich in der 
for-Schleife nur eine einzige Anweisung.  Du hast Doch sicherlich 
erwartet, dass leds_off() noch in der for-Schleife ist?

von g457 (Gast)


Lesenswert?

Da fehlt noch mehr..
1
$ avr-gcc -Wall -Os -mmcu=atmega8 -o main main.c main.c: In function ‘main’:
2
main.c:16: error: ‘i’ undeclared (first use in this function)
3
main.c:16: error: (Each undeclared identifier is reported only once
4
main.c:16: error: for each function it appears in.)
5
main.c:18: warning: implicit declaration of function ‘delay_us’
6
main.c:22: error: expected declaration or statement at end of input

Immer wieder toll wenn man anhand von kaputtkopierten 
Quellcodefragmenten Probleme aufspüren soll.

von Dominik K (Gast)


Lesenswert?

Klar fehlen da Klammern, auch die Abschlussklammer von der Main.
Trotzdem wird Kompiliert. Woran liegts? Ich hab die Klammern ausversehen 
mitgelöscht als ich die Kommentare entfernt habe.


Natürlich steht da (komplett):
1
while(1)
2
  { 
3
  for(i=0;i<16;i++)
4
 { leds_on();  
5
        delay_us(10);  
6
        leds_off();    
7
        _delay_us(10);
8
}
9
  }
10
  return 0;
11
}

Das wäre aber aufgefallen wenn man sich das Bild angeguckt hätte.

mfg
Dominik Krupp

von Hc Z. (mizch)


Lesenswert?

Dominik K schrieb:
> Natürlich steht da (komplett):

Darf ich Zweifel anmelden?  Das delay_us (ohne führendes „_“) steht 
immer noch da, dafür hast Du die geschweifte Klammer nach dem for 
dazugemogelt (obwohl das Oszillogramm deutlich eine andere Sprache 
spricht) und die Einrückungen sind immer noch Kraut und Rüben.  So 
wird's nix.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Es ist wirklich dringend nötig, daß C-Compiler anfangen, lausig 
formatierten Sourcecode abzuweisen.

von g457 (Gast)


Lesenswert?

> Natürlich steht da (komplett):

Das glaube ich Dir nicht. Erstens ist i noch immer nicht deklariert 
worden..
1
main.c:17: error: ‘i’ undeclared (first use in this function)
..und zweitens ist delay_us() nicht deklariert worden..
1
/tmp/ccfQz91N.o: In function `main':
2
main.c:(.text+0x1c): undefined reference to `delay_us'

Die Lösung zum eigentlichen Problem wurde übrigens schon genannt. Ich 
hack nur auf der Netiquette rum.

von Dominik K (Gast)


Lesenswert?

Ok,

der Code hier, führt zum exakt gleichen Ergebnis, wie oben im Bild 
beschrieben.

1
// CPU Takt
2
#define F_CPU 8000000
3
4
// Includen von Dateien 
5
#include <avr/io.h>
6
#include <util/delay.h>
7
8
// Variablen initialisieren
9
int i;
10
11
// Subroutinen
12
#define leds_on()  PORTB |= (1<<PB0) | (1<<PB1);
13
#define leds_off()  PORTB &= ~((1<<PB0) | (1<<PB1));
14
#define send1()    leds_on();  _delay_us(12.8);  leds_off(); _delay_us(12.8);
15
#define send0()    _delay_us(25.6);
16
17
int main()
18
  {  
19
  DDRB = (1<<PB0) | (1<<PB1);  // Port B0 & B1 sind Ausgänge
20
  PORTB |= (1<<PB2);      // Pull-Up für Port B4
21
    while(1)
22
    { 
23
    for(i=0;i<16;i++)
24
      {
25
      send1(); 
26
      }
27
    }
28
  return 0;
29
  }

Ich hab das send1 einfach runterkopiert damit weniger Code drin steht.
Meiner Meinung hätte das Ergebnis das selbe sein sollen, bzw. ist es bei 
mir ja auch.

mfg
Dominik

von Klaus W. (mfgkw)


Lesenswert?

Lass das mit den Makros statt Funktionen.
Das geht schief, wie du siehst.

So programmiert man nicht, sondern murkst rum.

Wozu sollen diese #define gut sein?
Den Quelltext zu verschleiern?

MAKROS SIND KEINE FUNKTIONEN!

von Huch (Gast)


Lesenswert?

Kannst Du bitte versuchen klar und deutlich Dein Problem zu benennen?
Ich habe keine Ahnung was das Problem sein soll.
Die For-Schleife spielt absolut keine Rolle.

von Dominik K (Gast)


Lesenswert?

@ Klaus,
danke für die Antwort.
Allerdings geht sie an meinem Problem vorbei.

Ich hatte doch geschrieben das dieser Fehler grundsätzlich bei allen 
For-Schleifen auftritt, egal was drin steht (siehe Post 1).

Dann hab ich einfach etwas Code zusammengebastelt damit man den Fehler 
am Oskar auch "sehen" kann und ich ihn hier posten kann damit mir jemand 
sagt wo ich was vestellt habe. Ich dachte mir das ein Bild mehr sagt als 
10 Reihen Text und auch verdeutlicht das der Code ausgeführt wird.


Allerdings verstehe ich wirklich nicht wieso so viele Leute auf ner 
Klammer rumreiten, oder auf ner fehlenden Variable, wohlwissend das das 
Programm gar nicht erst hätte kompiliert werden können wenn sie nicht 
drin gewesen wäre.

Da bekommt man den Eindruck das das erste Post von mir gar nicht gelesen 
wurde, und die Antwortersteller grundsätzlich von der Blödheit aller 
anderen ausgehen und ihre Standardantworten posten.

Ich vermute gleich wird noch jemand posten das der Code keinen Sinn 
erfüllt...


Nochmal: Der Code in meinem Post um 12:32 ist der vollständige 
funktionierende Code bei dem dieser Fehler auftritt. Allerdings noch bei 
dutzenden anderen Kombinationen wo eine For-Schleife enthalten ist.
Es ist nur ein ->Beispiel<- und wurde wegen der Einfachhalt ausgewählt.

mfg
Dominik K

von Dominik K (Gast)


Lesenswert?

@ Huch,

Genau! Sie spielt absolut keine Rolle, oder sie sollte es nicht. Aber 
die Ausgabe verändert sich sobald ich die Durchlaufrate der For-Schleife 
verändere!

Deshalb hab ich ja angenommen ich habe irgendwo was vestellt.


Soll ich ein Video davon machen wie ich den Wert ändere, neu kompiliere, 
hochlade und dann auf das Osziloskop schwenke?


mfg
Dominik

von Huch (Gast)


Lesenswert?

@ Dominik

Deine Arroganz und Selbstgefälligkeit mag ich nicht.
Such Dir den Fehler allein.

von Klaus W. (mfgkw)


Lesenswert?

Dominik K schrieb:
> Allerdings verstehe ich wirklich nicht wieso so viele Leute auf ner
> Klammer rumreiten, oder auf ner fehlenden Variable, wohlwissend das das
> Programm gar nicht erst hätte kompiliert werden können wenn sie nicht
> drin gewesen wäre.

Weil deine Fragestellung ziemlich undurchsichtig ist.
Um jetzt das zu raten, was du nicht sagen willst, müsste man
alles aus dem Programm rekonstruieren.
So wie der Quelltext aussieht (wenn man ihn denn überhaupt nach
etlichem Nachfragen zu sehen bekommt) ist er grottig zu lesen.

Ein sinnvoll geschriebener Quelltext, der sich an halbwegs
gängigen Konventionen orientiert, ist leichter zu verstehen.
Zuimindest wenn man ihn bekommt...

Wieso sollen hier alle lange rumrätseln, nur weil du dein Problem
nicht ordentlich beschreibst?

So ein Gestocher nervt halt.

Zudem gäbe es die meisten solchen Probleme gar nicht, wenn die
Leute halbwegs ordentlich programmieren würden.

von Dominik K (Gast)


Lesenswert?

@ Klaus,

danke für deine Antwort die viel mit dem Thema zu tun hat.
Ebenfalls danke für deine Beleidigungen.


Weitere Vorschläge?


Um Fehler im AVR auszuschließen (ich benutz es ja auch erst seid ein 
paar Wochen) werde ich das Programm mal unter Linux kompilieren und auf 
den µC Laden, mal schauen was dann passiert.

von Klaus W. (mfgkw)


Lesenswert?

Dominik K schrieb:
> Ebenfalls danke für deine Beleidigungen.

Du könntest es auch als Ratschlag auffassen.
Es ist ja nicht mein Problem.

Bin auch raus, der Nächste bitte...

von Hc Z. (mizch)


Lesenswert?

Drei Anläufe für einen Code, der angeblich von Anfang an so aussah wie 
der dritte und wo der dritte etwas deutlich Anderes tun müsste als der 
erste, aber dasselbe tut ... nö, bin auch raus.

von Matthias L. (Gast)


Lesenswert?

So Dominik,

ich habe mir jetzt den kompletten Thread durchgelesen. Und habe mir auch 
dein Oszi-Bild angesehen.

Alles was ich bisher kapiert habe, ist folgendes:

- Du hast eine for-Schleife,
- Du willst LEDs an/aus schalten.
- Das Ergebnis gefällt dir nicht.

Mehr weiß ich nicht.

Also:

1)
Was willst du erreichen? Leds an/ausschalten? Mit welchem Timing?

2)
Wie versuchst du das Ziel zu erreichen? kompletter Quellcode.

3)
Wie erkennst du, das nicht das passiert, was du willst? Oszibilder..

..

von g457 (Gast)


Lesenswert?

> Ich hab das send1 einfach runterkopiert damit weniger Code drin steht.
> Meiner Meinung hätte das Ergebnis das selbe sein sollen, bzw. ist es bei
> mir ja auch.

Ist es auch. Weil Du sowohl in der for-Schleife als auch im #define die 
Klammern vergessen hast. Und ich wette dass obiger Code (von 1232) nicht 
die selbe Ausgabe produziert wie das Bild im ersten Posting darstellt. 
Der "syntaxfehlerbereinigte" Code aus den Postings von vor 1232 dagegen 
macht genau das, was das Bild im ersten Posting darstellt.

Ein letzter Aufruf an die Netiquette.

von Peter (Gast)


Lesenswert?

wenn du glaubst das die anzahl der Schleifendurchläufe einfluss auf das 
timing hat, dann vergleiche doch mal beide ASM-files. Es sollte sich nur 
genau eine stelle ändern. Wenn sich mehr ändert dannn stimmt irgendetwas 
nicht. Dazu könntest du beide ASM files mal hochladen.

von Dominik K (Gast)


Lesenswert?

@ Matthias,
ok war evt. etwas unverständlich.
Evt. ist das so klarer.


Das Programm wurde 3x kompiliert und auf den µC geladen.
Die 3 Programme waren vollkommen identisch ausser folgender Code:

for(i=0;i<1;i++)
for(i=0;i<8;i++)
for(i=0;i<16;i++)

Das meinte ich mit dem Teil:

__
Der Fehler tritt bei jeder For-Schleife auf und mit jedem Inhalt.
In dem Bild im Anhang sieht man jetzt folgendes:
1. Durchlauf des Programms ohne For-Schleife (Oder 1x Durchlauf, hat den
gleiche Effekt)
2. Durchlauf des Programms mit 8x Schleife
3. Durchlauf des Programms mit 16x Schleife
__

Wenn ich das jetzt nochmal durchlese hätte ich den Teil auf dem ich mich 
beziehe evt. gesondert markieren sollen.

Mit dem Ergebnis das die Schleife nicht das macht was sie soll.
Und nochmal, das mit der LED ist nur ein Beispiel. Als ich als 
Fehlerquelle die For-Schleife lokalisiert habe, habe ich ein so 
einfaches Beispiel gemacht wo eigentlich garnichts falsch laufen dürfte.

mfg
Dominik

von Matthias L. (Gast)


Lesenswert?

Also ist dein Problem, dass die for-Schleife offenbar "ignoriert" wird?

von Dominik K (Gast)


Lesenswert?

Nein, das der Inhalt der For-Schleife offenbar manchmal ignoriert wird.


Das Signal wird unsymetrisch. Mall ist der Positive Teil 3x* so lang wie 
der Negative, und mal ist der Negative 3x* so lang wie der Positive.
Deshalb hatte ich das Bild angehangen.


Das der Kompiler manchmal Code ignoriert war mir klar (wobei ich da das 
Gefühl habe das der Windows gcc wesentlich agressiver löscht, aber das 
könnte Subjektiv sein) aber ich glaube nicht das es daran liegt.

Bzw. wie könnte man das den feststellen?


* p.s. Der Wert 3 ist "geschätzt" bitte nicht drauf rumreiten.

mfg
Dominik

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Passt doch super zum Oszi-Bild oben. Der Compiler optimiert da gar 
nichts weg. Nimm mal das hier:
1
for(i=0;i<1;i++)
2
        leds_on();  
3
_delay_us(10);  
4
leds_off();    
5
_delay_us(10);
Das sieht entrollt etwa so aus:
1
leds_on();  
2
_delay_us(10);  
3
leds_off();    
4
_delay_us(10);
Also etwa 10us low und 10us high.

Das hier:
1
for(i=0;i<8;i++)
2
        leds_on();  
3
_delay_us(10);  
4
leds_off();    
5
_delay_us(10);
sieht entrollt etwa so aus:
1
leds_on();  
2
leds_on();  
3
leds_on();  
4
leds_on();  
5
leds_on();  
6
leds_on();  
7
leds_on();  
8
leds_on();  
9
_delay_us(10);  
10
leds_off();    
11
_delay_us(10);
Er macht recht oft die LED an, und dann nach 10us wieder aus.

Und schliesslich das hier:
1
for(i=0;i<16;i++)
2
        leds_on();  
3
_delay_us(10);  
4
leds_off();    
5
_delay_us(10);
sieht entrollt etwa so aus:
1
leds_on();  
2
leds_on();  
3
leds_on();  
4
leds_on();  
5
leds_on();  
6
leds_on();  
7
leds_on();  
8
leds_on();  
9
leds_on();  
10
leds_on();  
11
leds_on();  
12
leds_on();  
13
leds_on();  
14
leds_on();  
15
leds_on();  
16
leds_on();  
17
_delay_us(10);  
18
leds_off();    
19
_delay_us(10);
Er macht sehr sehr oft die LED an, und dann nach 10us wieder aus.

Merkst du was?


> Mit dem Ergebnis das die Schleife nicht das macht was sie soll.
Die Frage aller Fragen, auf die bisher keine Antwort kam:
Was sollte sie den deiner Meinung nach machen?

Ich tippe (wie viele andere vor mir): Du hast die Klammern falsch 
gesetzt.
1
  while(1) { 
2
     for(i=0;i<16;i++) {
3
        leds_on();  
4
        delay_us(10);  
5
        leds_off();    
6
        _delay_us(10); 
7
     }
8
  }
9
  return 0;

von Christian H. (netzwanze) Benutzerseite


Lesenswert?

Wenn ich mir nur das Oszillogram ansehe denke ich folgendes:

1. Bild: Pulspause- und dauer sind gleich. Ca 13,2µs.
2. Bild: Die Pulsdauer ist größer. Die Pulspause nicht.
3. Bild: Die Pulsdauer ist größer. Die Pulspause nicht.

Sehe ich mir das Programm im ersten Post an.

Ohne For-Schleife wird die LED mittels delay für 10µs ein- und für 10µs 
ausgeschaltet. Bild 1 passt.

Mit 8-fach-For-Schleife wird die LED 8x eingeschaltet (dauert etwas), 
dann wird 10µs gewartet, die LED ausgeschaltet, wieder 10µs gewartet. 
Die LED wieder 8x eingeschaltet... Bild 2 passt.

Mit 16-fach-For-Schleife passt das Bild auch.

Ich erwarte von Programm genau das, was ich auf den Bildern sehe.


Vom letzen Programm erwarte ich aber eine andere Ausgabe.

von Christian H. (netzwanze) Benutzerseite


Lesenswert?

Überschnitten.

Lothar Miller schrieb:
> Ich tippe (wie viele andere vor mir): Du hast die Klammern falsch
> gesetzt.

Das denke ich auch. Und ich denke auch, dass das Oszillogram des letzten 
Programms nicht mit dem ersten Post zusammenstimmt.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Christian H. schrieb:
> Und ich denke auch, dass das Oszillogram des letzten
> Programms nicht mit dem ersten Post zusammenstimmt.
Das erste Programm passt zum Oszibild. Und zwar ist der gepostete Fall 
(i<16) in der untersten Ozi-Zeile zu sehen. Die Kurve darüber ist der 
i<8 Fall und die oberste ist die mit i<1.
Im i<16 Fall setzt das Makro leds_on() den Port 16 mal, dann wird 10 us 
gewartet, dann wird der Port zurückgesetzt, dann wird 10us gewartet, 
dann gehts von vorn los.

> Das denke ich auch. Und ich denke auch, dass das Oszillogram des
> letzten Programms nicht mit dem ersten Post zusammenstimmt.
Logisch. Es ist ja auch ein ganz anderes Programm. Ein wenig 
Präprozessor gespielt und for-Schleifen entrollt und schon sieht man 
das.

Nur: das erklärt immer noch nicht, was eigentlich die Frage war...

von Dominik K (Gast)


Lesenswert?

@ Christian,

ich messe direkt am/im STK500.

Pulspause und Pulsdauer sind vertauscht.

Bei led_off() ist die Led an (am Oskar 1).
und beim led_on() ist die Led aus (am Oskar 0).

Somit ist das was du im Bild siehst zwar richtig, aber passt nicht zum 
Code da sonst die Pulspause länger sein müsste.

Trotzdem Danke


@ Lothar,

ich erwarte das die Schleife von oben bis unten durchläuft und X-mal das 
macht was drin steht.

Nicht so beliebiges hin und her springen.


z.B.
Programm Start
16 x Schleife laufen lassen -> 16 X an und aus
Programm Ende
Wieder Programm Start...



Ich werd jetzt erstmal den gcc auf die neuste Version Updaten.
Das es ein Bug ist glaub ich nicht, der Fehler tritt ja erst seid 
gestern auf. Aber evt. hat Windows einfach was zerschossen.

mfg
Dominik

von Dominik K (Gast)


Lesenswert?

OK,

ich hab gerade mal unoptimiert kompiliert.
Der Fehler ist weg... und nun?

von Peter (Gast)


Lesenswert?

zeig doch mal bitte die 3 verschienden ASM Files. jeweils mit 1, 8 und 
16.

von Johannes M. (johannesm)


Lesenswert?

Dominik K schrieb:
> ich messe direkt am/im STK500.
>
> Pulspause und Pulsdauer sind vertauscht.
>
> Bei led_off() ist die Led an (am Oskar 1).
> und beim led_on() ist die Led aus (am Oskar 0).

hast du daran gedacht, das die LEDs auf dem STK500 low-aktiv sind?

von Dominik K (Gast)


Lesenswert?

@ Peter,

wo finde ich die asm Dateien bei AVR-Studio?


__________________

Ich hab das Problem jetzt auch im optimierten Code erkannt.
1
for(i=0;i<16;i++)
2
      { befehl(); }

verhält sich anders wie:
1
for(i=0;i<16;i++)
2
      befehl();

Aber nur wenn die Optimierung eingeschaltet ist.



Ich glaub langsam ich bin zu blöd für C für µC... ich glaub ich bleib 
bei Software Entwicklung und SPS bei Hochsprachen und bei µC bei 
Assembler.

Das der Unterschied so groß ist, hätte ich nicht gedacht.

mfg
Dominik

von Peter (Gast)


Lesenswert?

Dominik K schrieb:
> wo finde ich die asm Dateien bei AVR-Studio?

suche mal nach den *.lst
> Ich hab das Problem jetzt auch im optimierten Code erkannt.
>
> for(i=0;i<16;i++)
>       { befehl(); }
> verhält sich anders wie:
>
> for(i=0;i<16;i++)
>       befehl();

aber nur bei deinen Makros, sonst nicht.

von Huch (Gast)


Lesenswert?

Man denkt immer, es geht nicht noch schlimmer ...
Aber es geht doch.

von Dominik K (Gast)


Lesenswert?

@ Huch,
danke für eine weitere Beleidigung.


@ Peter,

das man bei Makros keine Klammern braucht ist mir klar.
Mein Fehler tritt bereits in der Main auf.

Deckt sich übrigens mit einem Fehler den ich letzte Woche gepostet habe, 
wo der Compiler wahrlos Code gelöscht hat.

Aber Danke, ich weiß ja jetzt das ich drauf achten muss.
Wobei ich das Warum nicht vestehe, ich hab damals mal gelernt das man 
keine Klammern braucht wenn nur 1 Befehl drin stehen würde.

mfg
Dominik

von Rolf Magnus (Gast)


Lesenswert?

Dominik K schrieb:
> Dann hab ich einfach etwas Code zusammengebastelt damit man den Fehler
> am Oskar

Wer oder was ist "Oskar"?

> auch "sehen" kann und ich ihn hier posten kann damit mir jemand
> sagt wo ich was vestellt habe. Ich dachte mir das ein Bild mehr sagt als
> 10 Reihen Text und auch verdeutlicht das der Code ausgeführt wird.

Um damit was anfangen zu können, muß aber "der Code" mit gepostet werden 
und nicht irgendwas anderes, was so ähnlich aussieht.

> Allerdings verstehe ich wirklich nicht wieso so viele Leute auf ner
> Klammer rumreiten,

Weil die das Problem perfekt erklären würde.

> oder auf ner fehlenden Variable, wohlwissend das das Programm gar nicht
> erst hätte kompiliert werden können wenn sie nicht drin gewesen wäre.

Sowas deutet eben darauf hin, daß du nicht den Code gepostet hast, der 
den von dir beobachteten Fehler verursacht hat. Ich lese jetzt seit über 
15 Jahren in Foren und Newsgroups mit. Weißt du, wie oft ich es schon 
erlebt hab, daß einer ein Problem hat und dann statt des Code, der 
dieses verursacht, für das Posting extra nochmal neuen Code schreibt, 
der nie einen Compiler gesehen hat und den angegebenen Fehler gar nicht 
enthält, dafür jede Menge anderer Fehler? Es ist ziemlich frustrierend, 
wenn man sich die Mühe macht, den Code anzuschauen und diese Fehler zu 
erklären, nur um dann nachher gesagt zu bekommen, daß der "eigentliche" 
Code diese "natürlich" gar nicht enthält und der Fehler wo ganz anders 
liegt. Ich finde es ehrlich gesagt reichlich unverschämt, als 
Hilfesuchender sowas zu veranstalten und dann die bereitwillig helfenden 
auch noch von oben herab zu behandeln, weil einem die Antworten nicht 
gefallen.

> Nochmal: Der Code in meinem Post um 12:32 ist der vollständige
> funktionierende Code bei dem dieser Fehler auftritt.

Also wirklich exakt der Code, den du so durch den Compiler hast laufen 
lassen und dann in den µC geschrieben hast? Ohne danach noch 
irgendwelche Änderungen dran gemacht zu haben? Der paßt so nämlich nicht 
mehr zur Fehlerbeschreibung.

Dominik K schrieb:
> Ich hab das Problem jetzt auch im optimierten Code erkannt.
> for(i=0;i<16;i++)
>       { befehl(); }
>
> verhält sich anders wie:
> for(i=0;i<16;i++)
>       befehl();
>
> Aber nur wenn die Optimierung eingeschaltet ist.

Und wieder einmal sind die Informationen unvollständig. Was ist 
befehl()? Eine Funktion oder eins deiner Makros? Bedenke, daß ein Makro 
nichts weitere ist als eine Textersetzung. Wenn a also steht:
1
#define befehl() a; b; c;

dann wird aus der zweiten Schleife:
1
for(i=0;i<16;i++)
2
     a; b; c;

was sich übersichtlicher schreiben läßt:
1
for(i=0;i<16;i++)
2
     a;
3
4
b;
5
c;

Aber daran kann es ja nicht liegen, da du ja Stein und Bein geschworen 
hast, daß der Code mit geschweiften Klammern ("Post um 12:32") der 
ist, der nicht funktioniert.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

> Wobei ich das Warum nicht vestehe, ich hab damals mal gelernt das man
> keine Klammern braucht wenn nur 1 Befehl drin stehen würde.

Dein Makro aber ist NICHT NUR EIN BEFEHL.

von Oliver (Gast)


Lesenswert?

Dominik K schrieb:
> Ich werd jetzt erstmal den gcc auf die neuste Version Updaten.

Welche WinAVR-Version nutzt du denn?

Dominik K schrieb:
> Ich hab das Problem jetzt auch im optimierten Code erkannt.
> for(i=0;i<16;i++)
>       { befehl(); }
>
> verhält sich anders wie:
> for(i=0;i<16;i++)
>       befehl();
>
> Aber nur wenn die Optimierung eingeschaltet ist.

Kannst du nicht mal ein kompilierbares Beispiel bringen, an dem man das 
nachvollziehen kann?


Dominik K schrieb:
> ich hab damals mal gelernt das man
> keine Klammern braucht wenn nur 1 Befehl drin stehen würde.

So war das, so ist das, und so wird es immer sein. Wenn nicht, wäre es 
nicht mehr C.

Oliver

von Huch (Gast)


Lesenswert?

>@ Huch,
>danke für eine weitere Beleidigung.
Das sollte gar keine sein.

Aber wenn Du meinst, dann nehme ich das mit Bedauern zurück.

Du disqualifizierst Dich nur andauernd selbst.

>Deckt sich übrigens mit einem Fehler den ich letzte Woche gepostet habe,
>wo der Compiler wahrlos Code gelöscht hat.

>Wobei ich das Warum nicht vestehe, ich hab damals mal gelernt das man
>keine Klammern braucht wenn nur 1 Befehl drin stehen würde.

Man könnte Dir ja helfen, wenn Du nicht von bestimmten "Wahrheiten" so 
überzeugt wärst.

Aber da Du nunmal so gestrickt bist wie Du es bist, musst Du da alleine 
durch. Wertestarrheit kann man nunmal nicht durch Erklärungen beseitigen 
nur durch eigene Erfahrung.

von Floh (Gast)


Lesenswert?

> das man bei Makros keine Klammern braucht ist mir klar.
> Mein Fehler tritt bereits in der Main auf.

Wenn man mehrere Anweisungen als ein Block verwenden will
-> geschweifte Klammern rum

> Deckt sich übrigens mit einem Fehler den ich letzte Woche gepostet habe,
> wo der Compiler wahrlos Code gelöscht hat.

Ja klar, der Compiler ist an allen Fehlern in deinem Programm schuld.
Komisch nur, dass andere mit demselben Compiler arbeiten und es sogar 
läuft... sicher Zufall.

> Aber Danke, ich weiß ja jetzt das ich drauf achten muss.
> Wobei ich das Warum nicht vestehe, ich hab damals mal gelernt das man
> keine Klammern braucht wenn nur 1 Befehl drin stehen würde.

Es steht aber nicht ein Befehl drin.
Makros ERSETZEN nur Text VOR dem Compilieren, daher stehen dann in 
deinem Fall 4 Befehle ohne Klammern unter dem for, also wird nur der 
erste ausgeführt.

Ich sag schon mal gerngeschehen, falls ich dich beleidigt habe.

von Dominik K (Gast)


Lesenswert?

@ Rufus,

danke der Klarstellung.
Wurde zwar schon 5x gesagt, wusste ich auch vorher und hat überhaupt nix 
mit dem Problem zu tun.


@ Oliver
1
// CPU Takt
2
#define F_CPU 8000000
3
4
// Includen von Dateien 
5
#include <avr/io.h>
6
#include <util/delay.h>
7
8
// Variablen initialisieren
9
int i;
10
11
// Subroutinen
12
#define leds_on()  PORTB |= (1<<PB0) | (1<<PB1);
13
#define leds_off()  PORTB &= ~((1<<PB0) | (1<<PB1));
14
#define send1()    leds_on();  _delay_us(12.8);  leds_off(); _delay_us(12.8);
15
#define send0()    _delay_us(25.6);
16
17
int main()
18
  {  
19
  DDRB = (1<<PB0) | (1<<PB1);  // Port B0 & B1 sind Ausgänge
20
  PORTB |= (1<<PB2);      // Pull-Up für Port B4
21
    while(1)
22
    { 
23
    for(i=0;i<16;i++)
24
      {
25
      send1(); 
26
      }
27
    }
28
  return 0;
29
  }
1
// CPU Takt
2
#define F_CPU 8000000
3
4
// Includen von Dateien 
5
#include <avr/io.h>
6
#include <util/delay.h>
7
8
// Variablen initialisieren
9
int i;
10
11
// Subroutinen
12
#define leds_on()  PORTB |= (1<<PB0) | (1<<PB1);
13
#define leds_off()  PORTB &= ~((1<<PB0) | (1<<PB1));
14
#define send1()    leds_on();  _delay_us(12.8);  leds_off(); _delay_us(12.8);
15
#define send0()    _delay_us(25.6);
16
17
int main()
18
  {  
19
  DDRB = (1<<PB0) | (1<<PB1);  // Port B0 & B1 sind Ausgänge
20
  PORTB |= (1<<PB2);      // Pull-Up für Port B4
21
    while(1)
22
    { 
23
    for(i=0;i<16;i++)
24
      send1(); 
25
    }
26
  return 0;
27
  }


Diese beiden Programme führen zu unterschiedlichem Ergebnis am Oskar (= 
Oszilloskop [für Rolf]).

Ich benutze die avr-gcc Version 433.

Kennt jemand nen gutes Programm für Bildschirmvideos? [Win7 - 64bit] 
Anders scheinen mir hier einige das nicht zu glauben.

mfg
Dominik

von Huch (Gast)


Lesenswert?

Wuuaahahaha. Ich kann nicht mehr. Hör auf, bitte. Bitte. Lern stricken 
oder sowas.

von Peter (Gast)


Lesenswert?

Dominik K schrieb:
> Diese beiden Programme führen zu unterschiedlichem Ergebnis am Oskar

Ist ja klar, weil du immer noch Makros verwendest. Makros sind keine 
Funktionen!!!!!!. Schreib es als richtige Funktion und schon wird es 
gehen.

von Klaus W. (mfgkw)


Lesenswert?

Dominik K schrieb:
> Diese beiden Programme führen zu unterschiedlichem Ergebnis am Oskar (=
> Oszilloskop [für Rolf]).

kein Wunder!
Auch wenn es dich beleidigt: Wird dein Makro raus und mache eine 
Funktion draus.
Dann geht es.

von Klaus W. (mfgkw)


Lesenswert?

Huch schrieb:
> Wuuaahahaha. Ich kann nicht mehr. Hör auf, bitte. Bitte. Lern stricken
> oder sowas.

zu kompliziert, außerdem beleidigend.

von Klaus W. (mfgkw)


Lesenswert?

Klaus Wachtler schrieb:
> Auch wenn es dich beleidigt: Wird dein Makro raus und mache eine
> Funktion draus.

Sollte heißen:
Auch wenn es dich beleidigt: Wirf dein Makro raus und mache eine
Funktion draus.

von Klaus W. (mfgkw)


Lesenswert?

Es gibt übrigens auch Bücher über C, da steht sowas drin.
Stichwort Präprozessor.

von Dominik K (Gast)


Lesenswert?

@ Floh,

ich hatte doch im alten Thread selber gesagt das ich nicht verstehe 
warum der Compiler etwas wegoptimiert und das es unoptimiert so läuft 
wie es soll.

Das der Fehler bei mir liegt stand doch nie zur Diskussion, sonst hätte 
ich ja nicht gefragt wie ich das wegbekomme.

Und warum sollte ich mich von dir Beleidigt fühlen? Du hast doch eine 
Antwort zum Thema verfasst. Selbst wenn du dabei ausfallen werden 
solltest, ist mir das egal, solange ich weiter komme.


Dank die Hilfe von einigen hier habe ich es ja jetzt auf die 
Unwissenheit über die Benutzungvon Klammern eingegrenzt. Jetzt würde ich 
nur noch gerne wissen warum es unterschiede zwischen Optimiertem 
(-O123s) und Unoptimiertem -(O0) gibt.

mfg
Dominik

von Klaus W. (mfgkw)


Lesenswert?

Rufus t. Firefly schrieb:
> Dein Makro aber ist NICHT NUR EIN BEFEHL.

Dominik K schrieb:
> @ Rufus,
>
> danke der Klarstellung.
> Wurde zwar schon 5x gesagt, wusste ich auch vorher und hat überhaupt nix
> mit dem Problem zu tun.

Dominik K schrieb:
> Diese beiden Programme führen zu unterschiedlichem Ergebnis am Oskar (=
> Oszilloskop [für Rolf]).

Diese Sequenz macht dich zum sicheren Kandidaten für den Mitarbeiter des 
Monats.

von holger (Gast)


Lesenswert?

Probier das mal ohne Klammern beim for()

#define send1()    do { leds_on();  _delay_us(12.8);  leds_off(); 
_delay_us(12.8); }while(0);

Muss natürlich alles in eine Zeile.

von Huch (Gast)


Lesenswert?

>Es gibt übrigens auch Bücher über C, da steht sowas drin.
>Stichwort Präprozessor.

Wozu denn das? Der gute Mann programmiert seit Jahren in Hochsprachen.

Siehe hier: 24.10.2010 14:21

>Ich glaub langsam ich bin zu blöd für C für µC... ich glaub ich bleib
>bei Software Entwicklung und SPS bei Hochsprachen und bei µC bei
>Assembler.

Das ist nur ein Problem mit dem uC (falls es nicht doch der Compiler 
ist).

Naja. Aber ich halte mich jetzt wirklich raus. Ist auch für mich nicht 
wirklich positiv meiner Bösartigkeit solchen Raum zu geben.

von Klaus W. (mfgkw)


Lesenswert?

Dominik K schrieb:
> Und warum sollte ich mich von dir Beleidigt fühlen? Du hast doch eine
> Antwort zum Thema verfasst. Selbst wenn du dabei ausfallen werden
> solltest, ist mir das egal, solange ich weiter komme.

Das haben alle anderen auch schon, du hast es aber nur als Beleidigung 
gesehen.

Um weiter zu kommen, müsstest du nur mal die bisherigen Antworten lesen 
UND VERSTEHEN.

Dominik K schrieb:
> Dank die Hilfe von einigen hier habe ich es ja jetzt auf die
> Unwissenheit über die Benutzungvon Klammern eingegrenzt. Jetzt würde ich
> nur noch gerne wissen warum es unterschiede zwischen Optimiertem
> (-O123s) und Unoptimiertem -(O0) gibt.

Das ist eine Illusion von dir, behaupte ich frech.

von Dominik K (Gast)


Lesenswert?

Ok,

einige hier scheinen sich wohl immer nur Bruchstücke meines Post 
rauszufischen und sich daran aufzugeilen.


Ihr sagtet Makros werdem vom Präprozi eingefügt. Klar, macht jeder 
Präprozi so. Wobei ich daran am Anfang nicht gedacht habe.

Und wer will mir jetzt erklären warum bei unoptimiertem Kompilieren die 
Klammern plötzlich egal sind?

mfg
Dominik

von Klaus W. (mfgkw)


Lesenswert?

Dominik K schrieb:
> Und wer will mir jetzt erklären warum bei unoptimiertem Kompilieren die
> Klammern plötzlich egal sind?

ist es doch nicht.

von Peter (Gast)


Lesenswert?

Dominik K schrieb:
> Und wer will mir jetzt erklären warum bei unoptimiertem Kompilieren die
> Klammern plötzlich egal sind?
auch dort sind sie nicht egal, aber _delay_us(12.8) geht ohne 
optimierung überhaupt nicht. Es sieht also nur so aus als ob es gehen 
würde weil die _delay_us viel zu lange braucht.

von Rolf Magnus (Gast)


Lesenswert?

Dominik K schrieb:
> Kennt jemand nen gutes Programm für Bildschirmvideos? [Win7 - 64bit]
> Anders scheinen mir hier einige das nicht zu glauben.

Ähm, die glauben das schon. Du bist derjenige, es am Anfang nicht 
geglaubt hat, als dir gesagt wurde, daß es an den geschweiften Klammern 
liegt. Ob du die Einzelaktionen direkt hinschreibst oder in einem Makro, 
macht dabei keinen Unterschied. Das Makro versteckt den Fehler nur 
besser.

Dominik K schrieb:
> Jetzt würde ich nur noch gerne wissen warum es unterschiede zwischen
> Optimiertem (-O123s) und Unoptimiertem -(O0) gibt.

Meine Vermutung: Das "schiefe" Timing kommt daher, daß du das Setzen des 
Ports, das ja auch Zeit braucht, mehrmals hintereinander ausführst. Wenn 
du die Optimierung ausschaltest, wird _delay_us() dadurch wahrscheinlich 
so langsam, daß das mehrfahre Portsetzen nicht mehr sonderlich ins 
Gewicht fällt.

von Dominik K (Gast)


Lesenswert?

@ Peter,

kannst du das bitte etwas genauer erklären? Das mit dem "nur so 
aussehen" habe ich nicht verstanden.

mfg
Dominik

von Floh (Gast)


Lesenswert?

Dominik K schrieb:
> Und wer will mir jetzt erklären warum bei unoptimiertem Kompilieren die
> Klammern plötzlich egal sind?

Sollten sie nicht.
Optimiert wird z.B. nach Geschwindigkeit oder Codegröße, aber der Ablauf 
des Programms darf nicht verändert werden.

Noch ein paar Tipps:
- Makros als Funktionsersatz vermeiden, gibt nur Probleme
- Schreibkonvention: Makros in Capslock
- Optimierung ausschalten (bringt auf AVRs wegen der billigen Sprünge 
sowiso fast nix)
:-)

von Oliver (Gast)


Lesenswert?

Dominik K schrieb:
> Jetzt würde ich
> nur noch gerne wissen warum es unterschiede zwischen Optimiertem
> (-O123s) und Unoptimiertem -(O0) gibt.

Extra für dich kommt da so eine komische Meldung vom Compiler, wenn du 
mit -O0 kompilierst. Da könnte man sich schon fragen: Was wollen uns 
diese Worte sagen?

RTFM zu _delay_us

Dominik K schrieb:
> ich hatte doch im alten Thread selber gesagt das ich nicht verstehe
> warum der Compiler etwas wegoptimiert und das es unoptimiert so läuft
> wie es soll.

Der Compiler optimiert nichts weg. Und unoptimiert läuft _delay_us 
niemals, wie es soll.

Oliver

von Dominik K (Gast)


Lesenswert?

@ Rolf,

danke das wenigstens einer mir glaubt.


Die ersten 10 Antworten gingen doch nur darüber das ich den Quellcode 
nicht vollständig eingestellt habe. Die nächsten 20 gingen darüber das 
ich Lüge.
Super!

Stat zu sagen "häng bitte die projekt.c (oder was auch immer) mit an, 
das machts einfacher" wird munter drauf los gelästet.


Nur 3 Leute hier sind wirklich bereit zu helfen.
Danke an die 3 Personen.

von Klaus W. (mfgkw)


Lesenswert?

Floh schrieb:
> - Optimierung ausschalten (bringt auf AVRs wegen der billigen Sprünge
> sowiso fast nix)

Die _delay-Funktionen stimmen aber nur mit eingeschalteter Optimierung
richtig!
http://www.nongnu.org/avr-libc/user-manual/group__util__delay.html

von Peter (Gast)


Lesenswert?

Dominik K schrieb:
> @ Peter,
> kannst du das bitte etwas genauer erklären? Das mit dem "nur so
> aussehen" habe ich nicht verstanden.
weil _delay_us ohne optimiung viel zu lange braucht, das ist auch ein 
Makro. Und in der Doku steht extra drin das ist nur mit optimierung 
funktioniert.

Wenn jetzt das _delay_us zu lange braucht, dann ändert das dein 
komplettes timing. Danach kannst du alle mögichen ergbnisse bekommen 
aber richtig wird keines davon sein.

von Klaus W. (mfgkw)


Lesenswert?

Dominik K schrieb:
> Die ersten 10 Antworten gingen doch nur darüber das ich den Quellcode
> nicht vollständig eingestellt habe. Die nächsten 20 gingen darüber das
> ich Lüge.
> Super!
>
> Stat zu sagen "häng bitte die projekt.c (oder was auch immer) mit an,
> das machts einfacher" wird munter drauf los gelästet.

Wenn die ersten 10 den vollständigen Quelltext verlangen, kommst du
nicht selbst auf die Idee, dein projekt.c zu zeigen (wenn es denn so
heisst)?

Was sonst glaubst verlangt man vor dir, wenn fehlender Quelltext
angemeckert wird?

von Huch (Gast)


Lesenswert?

>Stat zu sagen "häng bitte die projekt.c

Da reisst mir doch die Hutschnur...

Das ist Deine verd.... Pflicht uns ohne alle Nachfrage alle nötigen 
Informationen zu geben und nicht unsere, Dir jeden Sch... einzeln aus 
der Nase zu ziehen und uns dann noch blöde und unqualifizierte Antworten 
gefallen lassen zu müssen.

Du willst hier was von uns.
Deine Kenntnismängel an sich sind überhaupt nicht das Problem. Das 
Problem ist die Mischung aus Arroganz und Unwissen.

von Dominik K (Gast)


Lesenswert?

OK,

also habe ich bei dem Versuch meinen ursprünglichen Klammerfehler zu 
Identifizieren mir ein Eigentor geschossen was nur so aussah.
Danke @ Peter und Co.


Aber was den nun?
Der eine sagt Optimierung muss aus, der andere sagt das führt zu 
Fehlern, der dritte sagt das geht gar nicht.

mfg
Dominik

von Huch (Gast)


Lesenswert?

Du kannst hier Klaus Wachtler, Rolf und den anderen auf Knien danken, 
das sie das entweder anders sehen oder toleranter sind.

Mann, auf so Halbdackel haben wir hier schon immer gewartet.

von Peter (Gast)


Lesenswert?

Dominik K schrieb:
> Aber was den nun?
> Der eine sagt Optimierung muss aus, der andere sagt das führt zu
> Fehlern, der dritte sagt das geht gar nicht.
ohne optimierung geht delay nicht, also braucht du auf jeden fall die 
Optimierung. Und alle Fehler die durch die Optimierung entstehen sind 
fehler in deinem Code. Also programmiere sauber dann gibt es keine 
Probleme.

von Dominik K (Gast)


Lesenswert?

@ Huch,

wenn du wirklich der Meinung bist das es OK ist, wenn du andere Leute 
anmaulst und dich über sie Lustig zu machen weil sie irgendwas nicht 
wissen, dann tust du mir irgedwie Leid.

Ich hoffe das du mal in die Lage kommst jemandes Hilfe zu benötigen und 
dann an jemanden wie dich zu kommen.



@ Klaus, Peter, Matthias, Lothar,

DANKE für die Hilfe.
Ich beschäftige mich jetzt mal was mit Hintergrundwissen zum Kompiler.

von Christian H. (netzwanze) Benutzerseite


Lesenswert?

Ohne Optimierung macht "for(i=0;i<16;i++) led_on();" folgendes:

led_on();
led_on();
led_on();
led_on();
...
led_on();
(insgesamt 16x).

Mit Optimierung aber das:

led_on();

Das liegt daran, dass es für die Optimierung keinen Sinn macht, warum Du 
einem Portbit 4x hintereinander setzt. Einmal reicht aus - und das macht 
der Optimierer auch daraus. Vom Ergebnis ist es das selbe (außer die 
Rechnenzeit) also darf der Optimierer das so machen.

von Huch (Gast)


Lesenswert?

@ Dominik

Ja, ja. Wie Du meinst.

von Peter (Gast)


Lesenswert?

Christian H. schrieb:
> Ohne Optimierung macht "for(i=0;i<16;i++) led_on();" folgendes:
> led_on();
> led_on();
> led_on();
> led_on();
> led_on();
>
> (insgesamt 16x).
>
>
>
> Mit Optimierung aber das:
> led_on();
> Das liegt daran, dass es für die Optimierung keinen Sinn macht, warum Du
> einem Portbit 4x hintereinander setzt. Einmal reicht aus - und das macht
> der Optimierer auch daraus. Vom Ergebnis ist es das selbe (außer die

FALSCH!!!!

Das Stimmt nicht, weil port zugriffe volatil sind, das darf der Compiler 
auf keinen Fall Optimieren - macht er auch nicht. Sonst könnten man 
keine Seriellen daten senden. Dort schreibt man den wert immer auf einen 
Port. Wenn er das Optimierne würde dann geht das schief.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Christian H. schrieb:
> Das liegt daran, dass es für die Optimierung keinen Sinn macht, warum Du
> einem Portbit 4x hintereinander setzt.
Da würde ich dem Compiler aber was erzählen...
Es hat die Optimierung einen Schnurz zu kümmern, ob ich einen Portpin 
zigmal setze. Das ist mein ausdrücklicher Wunsch an die Umwelt, und das 
darf nicht wegoptimiert werden...
Irgendwelche internen Abläufe, da darf meinetwegen optimiert werden. 
Aber alles was nach Extern geht, hat so ausgeführt zu werden, wie ich 
das will.

von Christian H. (netzwanze) Benutzerseite


Lesenswert?

Peter schrieb:
> weil port zugriffe volatil sind

Ok, war mir nicht klar. Dann halt nicht.
Trotzdem kann man meinen Beitrag als Beispiel nehmen, wieso mit und ohne 
Optimierung unterschiedlich sein kann.

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.