wenn die erste If-Bedingung erfüllt ist wird die zweite If-Schleife
übersprungen, wenn die erste If-Bedingung nicht erfüllt ist und der
Else-Zweig abgearbeitet wird, wird die zweite If-Schleife ganz normal
abgearbeitet.
Ich habe keine Ahnung, warum die zweite Schleife übersprungen wird.
Es wäre schön wenn ihr mir weiterhelfen könnt.
Tschau
SIME
Probiere doch mal die Kurzform:
void start()
{
if (((~PINB) & 0b00001000) == 0b00001000) ? PORTA |=0b01000000 PORTA
&=0b10111111;
if ((PIND & 0b10000000) == 0b10000000) ? PORTA |=0b01000000 : PORTA
&=0b10111111;
};
K. S. schrieb:> Aber eigentlich sollte es doch keinen Unterschied machen oder?
würde ich auch sagen, der code sieht richtig aus. Die Frage ist welcher
werte wirklich anliegen, das können wir leider nicht sehen.
K. S. schrieb:> Ich habs durchgespielt mit F11 und dabei immer mal PINC3 gesetzt und> nicht gesetzt.> Vielleicht liegts ja auch an meinen Einstellungen.
aber was hat das ganze mit PINC3 zu tun? kommt doch nirgends vor.
tausche doch mal beide If blöcke.
K. S. schrieb:> Wenn ich die Blöcke tausche, gehts auch nicht.> Es muss irgend etwas Prinzipielles sein.
was geht da nicht, wird der 1. Block wieder übersprungen oder diesemal
der 2.?
Hast Du die Kurzform mal ausprobiert? Es könnte ja sein, dass der
Compiler aus irgendwelchen Gründen das zweite If als Bestandteil des
Else des ersten if sieht.
Mache außerdem mal ein Semikolon nach der Klammer:
if (bed) {...} else {...}*;*
Martin Schwaikert schrieb:> Hast Du die Kurzform mal ausprobiert? Es könnte ja sein, dass der> Compiler aus irgendwelchen Gründen das zweite If als Bestandteil des> Else des ersten if sieht.
warum sollte er das machen?
test schrieb:> #define limes while>> int n=42;> limes (n-->0) {> foo(n);> }
ich verstehe nicht warum du 42 gegen 0 gehen lassen willst, wo es doch
die Antwort auf alle Fragen ist.
Nur leider hat das jetzt auch schon wieder nicht geklappt. Ich dachte
eigentlich das der Code so funktionieren müsste und hatte gehofft
irgendjemand weiß eine schnelle Lösung.
Kann vielleicht mal jemand das Programm kurz bei sich einspielen.
Vielleicht habe ich ja auch irgendeinen Mist beim AVR-Studio
eingestellt.
Danke
SIME
Peter II schrieb:> Martin Schwaikert schrieb:>> Hast Du die Kurzform mal ausprobiert? Es könnte ja sein, dass der>> Compiler aus irgendwelchen Gründen das zweite If als Bestandteil des>> Else des ersten if sieht.>> warum sollte er das machen?
wollte ich auch gerade fragen, denn der zweite IF hat überhaupt nicht
mit den Varaiblen aus dem ersten IF zu tun...
Wie stellst du eigentlich fest, dass hier etwas abnormes passiert?
Wenn der Optimizer des Compilers eingeschaltet ist, dann zeigt dir der
Simulator den Programmablauf nicht mehr genau so an, wie du ihn
geschrieben hast.
Ich bin darauf gekommen, als meine Hardware nicht das gemacht hat, was
ich dachte geschrieben zu haben.
Daraufhin habe ich dann das mit den If-Blöcken versucht und bin es
Schritt für Schritt durchgegangen und das überspringen der Schleife hat
auch zu meinem Problem gepasst.
Darum denke ich, dass da irgend ein Fehler drinn sein muss.
Tschau
SIME
So
nachdem ich jetzt 3 mal die Stellen der Binärzahlen abgezählt habe und
mich natürlich prompt 5 mal verzählt habe, darf ich vorschlagen, das
ganze mal vernünftig zu schreiben, so dass man
a) das ganze schnell erfassen kann, und man
b) weniger Tippfehler machen kann?
1
voidstart()
2
{
3
if(!(PINB&(1<<PB3)))
4
{
5
PORTA|=(1<<PA6);
6
}
7
else
8
{
9
PORTA&=~(1<<PA6);
10
}
11
12
if(PIND&(1<<PD7))
13
{
14
PORTA|=(1<<PA6);
15
}
16
else
17
{
18
PORTA&=~(1<<PA6);
19
}
20
}
Jetzt sieht man auch auf einen Blick, dass beide ifs denselben Pin am
Port A bedienen. Ist das so gewollt?
Ich würde einfach mal mit 2 Eingängen dann auch 2 getrennte Ausgänge
manipulieren. So wie das hier jetzt voneinander abhängt und letztlich
auf 1 Ausgang geht, könnte für manchen der Eindruck einer gewissen
Abhängigkeit entstehen...
K. S. schrieb:> Daraufhin habe ich dann das mit den If-Blöcken versucht und bin es> Schritt für Schritt durchgegangen und das überspringen der Schleife hat
Wenn dich schon jemand darauf hinweist, dass if keine Schleife ist, dann
solltest du das auch annehmen.
Eine 'Schleife' ist nicht etwas in dem { } Klammern vorkommen, sondern
eine Schleife ist etwas, in dem Code (potentiell) wiederholt wird, so
wie in einem for, while. Darum heißßt es Schleife, weil es 'im Kreis rum
geht', genau wie ein Tonband, welches man zu 'einer Schleife'
zusammengeklebt hat.
Ein if trifft einfach nur eine Auswahl aus 2 Möglichkeiten und das hat
mit einer Schleife genau gar nichts zu tun. Das ist eine Abfrage.
> Darum denke ich, dass da irgend ein Fehler drinn sein muss.
Also in realer Hardware.
Da hier der A-Port im Spiel ist.
AVcc ist angeschlossen?
Dir ist bewusst, dass du am A-Port denselben Ausgangspin ansteuerst. Ist
das so gewollt?
Karl Heinz Buchegger schrieb:> Dir ist bewusst, dass du am A-Port denselben Ausgangspin ansteuerst. Ist> das so gewollt?
ja.
ich habe zwei verschiedene Taster die jeweils die selbe LED zum leuchten
bringen sollen.
Das mit der If- Schleife tut mir leid ich habe extra Blöcke geschrieben
aber in der nächsten Zeile ist es mir wieder rausgerutscht
SIME
K. S. schrieb:> Karl Heinz Buchegger schrieb:>> Dir ist bewusst, dass du am A-Port denselben Ausgangspin ansteuerst. Ist>> das so gewollt?>> ja.> ich habe zwei verschiedene Taster die jeweils die selbe LED zum leuchten> bringen sollen.
Dann musst du das grundsätzlich anders machen.
Denn dein erster if setzt zwar die LED richtig, aber dein zweites if
ändert das gleich wieder.
mit dem einen Taster kannst du die LED schon einschalten. Aber wenn der
zweite Taster nicht gedrückt ist, dann brennt die nur ein paar
Mykro-Sekunden lang. Und so schnell kannst du nicht schauen.
ALso: Du hast einen Logikfehler.
Was du wirklich willst:
Wenn der eine Taster gedrückt ist ODER der andere (oder beide), dann
schalte die LED ein, ansonsten aus.
(Apropos: wie sind deine Taster eigentlich verschaltet? Den einen fragst
du auf 0 ab, den anderen auf 1)
Karl Heinz Buchegger schrieb:> ALso: Du hast einen Logikfehler.
Ich habe jetzt auch mal in dem zweiten Block einen anderen Ausgang
gesetzt.
Jetzt wird beim durchlaufen mit F11 trotzdem wieder der zweite Block
übersprungen.
Ich weiß ehrlich gesagt nicht wie der Optimizer funktioniert aber
eigentlich müsste doch jede Zeile die genutzt wird beim F11-Betrieb
angesprochen werden oder?
K. S. schrieb:> Karl Heinz Buchegger schrieb:>> ALso: Du hast einen Logikfehler.>> Ich habe jetzt auch mal in dem zweiten Block einen anderen Ausgang> gesetzt.> Jetzt wird beim durchlaufen mit F11 trotzdem wieder der zweite Block> übersprungen.
Im Simulator.
Nochmal: Wenn der OPtimizer des Compilers eingeschaltet ist, dann zeigt
der der Debugger den Ablauf nicht unbedingt genau so, wie du ihn
geschrieben hast. Der Optimizer des Compilers kann, darf und wird da die
Anweisungen umgruppiere, so dass der Debugger keine einwandfreie
Zuordnung mehr machen kann, welche Assemblerinstruktionen jetzt zu
welchem C Code gehören.
Wichtig ist ob die Pins genau das tun, was du programmiert hast!
Und im Zweifel gilt immer:
wie sieht das Programm jetzt aus? Ohne aktuellen Code kann dir hier
keiner auseinanderdividieren was wirklich passiert.
Karl Heinz Buchegger schrieb:> nd im Zweifel gilt immer:> wie sieht das Programm jetzt aus? Ohne aktuellen Code kann dir hier> keiner auseinanderdividieren was wirklich passiert.
also hier mal der aktuelle Code:
**************************************
1
# define F_CPU 3686400UL
2
# include <avr/io.h>
3
# include <util/delay.h>
4
voidstart();
5
6
# define F_CPU 3686400UL
7
# include <avr/io.h>
8
# include <util/delay.h>
9
voidstart();
10
11
voidstart()
12
{
13
if(((~PINB)&0b00001000)==0b00001000)//wenn die Bedingung
14
//erfüllt ist
15
{
16
PORTA|=0b01000000;//springt er hierher
17
}
18
else
19
{
20
PORTA&=0b10111111;//lässt das aus
21
}
22
23
if((PIND&0b10000000)==0b10000000)//lässt aber auch diesen
Und?
Wenn du am Ende der Funktion, nach dem Rücksprung, dir im Simulator die
Bits vom Port C im I/O View ansiehst, sind die richtig gesetzt oder
nicht?
(Ansonsten schalt halt mal den Optimizer aus)
Karl Heinz Buchegger schrieb:> Ansonsten schalt halt mal den Optimizer aus)
hab ich gemacht.
Jetzt läufts und meine LEDs auch so wie sie sollen.
Danke und sorry das ich nicht eher nach dem Optimizer gefragt habe.
Ich hab jetzt so viel in meinem eigentlichen Programm rumgewühlt, dass
ich nicht mal mehrt sagen kann was der Grund für den Fehler war.
Jetzt läufts wieder.
Vielen Dank an alle.
Tschau
SIME
K. S. schrieb:> Karl Heinz Buchegger schrieb:>> Ansonsten schalt halt mal den Optimizer aus)> hab ich gemacht.> Jetzt läufts und meine LEDs auch so wie sie sollen.> Danke und sorry das ich nicht eher nach dem Optimizer gefragt habe.
Das sollte dir klar sein: ein anderes Verhalten beim Zu- und Abschalten
des Optimierers deutet auf einen Programmfehler hin.
Justus Skorps schrieb:> bei dem kurzen Programm könnte man sich doch auch mal den erstellen> Assembler-Code anschauen...
Wenn ich alle Aussagen so im Kontext zusammensetze, haben wir wieder mal
den Fall, dass dieser Code nicht der ist, der eigentlich Probleme macht.
Peter II schrieb:> Martin Schwaikert schrieb:>> Hast Du die Kurzform mal ausprobiert? Es könnte ja sein, dass der>> Compiler aus irgendwelchen Gründen das zweite If als Bestandteil des>> Else des ersten if sieht.>> warum sollte er das machen?
Um auszuschließen, dass der Compiler das Programm so umstrukturiert,
dass die zweite If-Abfrage als Bestandteil des Else-Zweiges der ersten
Bedingung verarbeitet wird - genauso eben, wie ich es schon geschrieben
habe!
K. S. schrieb:> Danke und sorry das ich nicht eher nach dem Optimizer gefragt habe.
Der Optimizer ist gut und tut genau das, was er soll - er optimiert und
rationalisiert. Wenn er Code findet, der unsinnig ist, wird er in die
Tonne getreten. Genau das passiert wohl bei Dir auch. Ich persönlich
habe die Erfahrung gemacht, dass man gerade zum Herumprobieren den
Optimizer auslassen sollte, es sei denn, man schreibt seinen Quelltext
so, dass der Compiler ihn nicht einfach weglöscht.
Richtig ärgerlich kann es dann nebenbei werden, wenn der Debugger auf
einen Fehler hinweist, der in einer Berechnung stattfindet, und man
einfach nicht versteht, warum er dabei auseinanderfliegt. Irgendwann
einmal merkt man, dass der Optimizer eine Zeile Code entfernt hat, und
alle Haltepunkte um eine Zeile verschoben sind und der Fehler eigentlich
ganz woanders auftritt.
Martin Schwaikert schrieb:> Peter II schrieb:>> Martin Schwaikert schrieb:>>> Hast Du die Kurzform mal ausprobiert? Es könnte ja sein, dass der>>> Compiler aus irgendwelchen Gründen das zweite If als Bestandteil des>>> Else des ersten if sieht.>>>> warum sollte er das machen?>> Um auszuschließen, dass der Compiler das Programm so umstrukturiert,> dass die zweite If-Abfrage als Bestandteil des Else-Zweiges der ersten> Bedingung verarbeitet wird - genauso eben, wie ich es schon geschrieben> habe!
Du greifst da jetzt aber nach einem Strohhalm.
Sicher, es gibt schon mal dumme Fehler in einem Compiler, aber so ist
das dann auch wieder nicht, dass Compiler völlig ungetestet auf die
Menschheit losgelassen werden. So ein Fehler fällt beim ALLERERSTEN
Programm, welches diese Compilerversion compiliert sofort auf. Zumal man
sich schon sehr anstrengen muss, um so ein Verhalten in die Grammatik
reinzukriegen.
> rationalisiert. Wenn er Code findet, der unsinnig ist, wird er in die> Tonne getreten. Genau das passiert wohl bei Dir auch.
Genau das ist in der überwiegenden Mehrzahl der Fälle das eigentliche
Problem. C lässt ein paar Dinge offen bzw. hat ein paar Dinge, die ein
Optimizer ausnutzen kann und wird, die aber der Absicht des
Programmierers zuwider laufen. Das Problem ist nicht der Optimizer,
sondern dass der Programmierer mit seinen Kenntnissen noch nicht soweit
ist, diese Dinge zu wissen und entsprechend zu programmieren.
Womit wir wieder bei meinem Lieblingsthema sind: die 'Ausbildung' vieler
'Programmierer' die hier aufschlagen ist unter aller Sau. Wer analog so
vorbereitet in den Strassenverkehr gehen würde, würde an der nächsten
Strassenecke sofort vom nächsten Passanten wegen Gefahr im Verzug aus
dem Verkehr gezogen und bis zum Eintreffen der Polizei festgehalten
werden. Nur beim Thema 'Ich werde jetzt Programmierer' ist das ein
kleineres Kavaliersdelikt, wie ich mir von so manchem schon habe sagen
lassen müssen. Denn, hey, ICH brauch doch kein Buch! Wozu denn? Ich will
ja nicht Profi werden.
Karl Heinz Buchegger schrieb:> Du greifst da jetzt aber nach einem Strohhalm.> Sicher, es gibt schon mal dumme Fehler in einem Compiler, aber so ist> das dann auch wieder nicht, dass Compiler völlig ungetestet auf die> Menschheit losgelassen werden.
Nein, das nicht. Der "Dumme" sitzt da zumeist vorm Bildschirm. Ich
persönlich hatte schonmal den Fall, dass ein fehlender ";" hinter einer
Anweisung (obwohl in diesem Zusammenhang nicht nötig, und deshalb auch
nicht geschrieben) dazu führte, dass er die nächste Zeile noch als einen
Befehl mit aufnahm. Leider habe ich kein konkretes Beispiel mehr, da es
schon etwas länger her ist, aber ich hatte damals ein ähnliches
verhalten. Allerdings unter Visual Studio 2010 und nicht speziell beim
µC.
Karl Heinz Buchegger schrieb:> Genau das ist in der überwiegenden Mehrzahl der Fälle das eigentliche> Problem. C lässt ein paar Dinge offen bzw. hat ein paar Dinge, die ein> Optimizer ausnutzen kann und wird, die aber der Absicht des> Programmierers zuwider laufen.
Mit Sicherheit. Wie ich ja auch geschrieben hatte schreibt man mal
schnell ein paar Zeilen Code, die einfach wegrationalisiert werden, da
sie bei genauerem Betrachten unsinnig sind.
Martin Schwaikert schrieb:> Peter II schrieb:>> Martin Schwaikert schrieb:>>> Hast Du die Kurzform mal ausprobiert? Es könnte ja sein, dass der>>> Compiler aus irgendwelchen Gründen das zweite If als Bestandteil des>>> Else des ersten if sieht.>>>> warum sollte er das machen?>> Um auszuschließen, dass der Compiler das Programm so umstrukturiert,> dass die zweite If-Abfrage als Bestandteil des Else-Zweiges der ersten> Bedingung verarbeitet wird - genauso eben, wie ich es schon geschrieben> habe!
Die Variablen PORT und PIN Variablen sind aber volatile, da hat der
Compiler nicht viel Spielraum. Insbesondere muss er die Reihenfolge der
Zugriffe einhalten und darf keine Zugriffe wegoptimieren, außer sie
wären in nicht erreichbarem Code.
> Richtig ärgerlich kann es dann nebenbei werden, wenn der Debugger auf> einen Fehler hinweist, der in einer Berechnung stattfindet, und man> einfach nicht versteht, warum er dabei auseinanderfliegt. Irgendwann> einmal merkt man, dass der Optimizer eine Zeile Code entfernt hat, und> alle Haltepunkte um eine Zeile verschoben sind und der Fehler eigentlich> ganz woanders auftritt.
Die Debugging-Information stimmen natürlich mit dem erzeugten
(optimierten) Code überein, da können sich nicht einfach alle
Haltepunkte um eine Zeile verschieben. Wenn das passiert dann stimmt
eher der Code mit den Debugging-Informationen, den der Debugger sieht,
nicht mit dem überein, der tatsächlich ausgeführt wird, d.h. es ist ein
Benutzerfehler.
Optimierter Code kann im Single Step im Debugger bei den Source Code
Zeilen in nicht nachvollziehbaren Schritten vor und zurück springen und
mancher Code kann schlicht nicht mehr existieren. Aber der Debugger wird
nicht konstant um eine wegoptimierte Zeile daneben liegen.