Wieso geht das nicht ?
while(1)
{
if (licht==1)
{
for(i=0;i<10000;i++)
{
PORTB=0b00111000;
PORTC=0b00111111;
PORTD=0b11100000;
_delay_ms(2);
}
}
if (licht==2)
{
for(i=0;i<10000;i++)
{
PORTB=0b00111000;
PORTC=0b00111111;
PORTD=0b11100000;
_delay_us(750);
PORTB=0b00000000;
PORTC=0b00000000;
PORTD=0b00000000;
_delay_us(250);
}
}
if (licht==3)
{
for(i=0;i<10000;i++)
{
PORTB=0b00111000;
PORTC=0b00111111;
PORTD=0b11100000;
_delay_us(500);
PORTB=0b00000000;
PORTC=0b00000000;
PORTD=0b00000000;
_delay_us(500);
}
}
if (licht==4)
{
for(i=0;i<10000;i++)
{
PORTB=0b00111000;
PORTC=0b00111111;
PORTD=0b11100000;
_delay_us(250);
PORTB=0b00000000;
PORTC=0b00000000;
PORTD=0b00000000;
_delay_us(750);
}
}
if (licht==5)
{
for(i=0;i<10000;i++)
{
PORTB=0b00000000;
PORTC=0b00000000;
PORTD=0b00000000;
_delay_ms(1);
}
}
if (licht==6)
{
licht=licht-6;
}
else if (licht==0)
{
anderes geblinke
}
Geschrieben auf einem Atmega8
Unten befindet sich eine interrupt routine welche den wert licht+1 macht
wenn der Taster gedrückt wird
eigentlich sollte jetzt ja das Lich zuerst Hell und nach jedem Druck
immer Dunkler werden
Danke schonmal im voraus
martaniu
Gast
#4478224
Fehlt da nicht ne Klammer?
Gast
#4478231
- Taste nicht entprellt? - Variable licht falsch initialisiert? - Fall licht > 6 Fall nicht bearbeitet(der ja nicht auftreten sollte, aber ja vielleicht doch auftritt.
Gast
#4478234
Ich D. schrieb: > if (licht==6) > { > licht=licht-6; > } licht = 0 Ich D. schrieb: > if (licht==6) > { > licht=licht-6; > } > else if (licht==0) > { > anderes geblinke > } Wenn licht auf 0 gesetzt wurde (also vorher 6 war) dann kommt man natürlich, im selben durchlauf, nicht in den else zweig.
Ich D. schrieb: > Wieso geht das nicht ? Tolle Frage. Was geht nicht? Natürlich geht das. Es kommt nur nicht das raus, was du erwartest, oder? Du wirst uns schon erzählen müssen, was das ist, was du erwartest.
Gast
#4478255
Was genau heisst: "Funktioniert nicht"? Siehe: https://www.mikrocontroller.net/articles/Netiquette Wenn man Deinen Code ansieht, so hängt einzig die Dauer der Verzögerung von dem Wert der Variablen licht ab. licht delay 1 2ms 2 750us 3 500us 4 250us 5 1ms ... Alle anderen von der Bedingung abhängigen Vorgänge sind unabhängig vom Wert der Variablen licht gleich. Daher ist es zu überlegen, ob Du nicht eine einzige Funktion schreibst, die ausschliesslich ein delay je nach ihrem Parameter ausführt. Das macht das Programm übersichtlicher. Dazu kannst Du wieder eine Kette von if-Anweisungen benutzen oder eine switch-Anweisung. z.B. so
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
Das ist eigentlich auch nur dann nötig, falls Du das delay das mit dem GCC für AVR kommt verwendest, weil dort das delay keine Variable als Parameter akzeptiert. Aber wir wissen ja auch nicht welcher uC oder welcher Compiler. Siehe https://www.mikrocontroller.net/articles/Netiquette Lediglich die Benennung der Ports deutet darauf hin, dass es sich um einen AVR handeln könnte . Das man Tasten wegen ihres Prellens nicht in Interrupt-Funktionen auswertet ist ja schon erwähnt worden.
Gast
#4478257
Ooops. Die Bedingungen müssen natürlich nicht: if (licht==1) sein, sondern if (i == 1) was mich veranlasst, darauf hinzuweisen, das man für Variablennamen möglichst aussagekräftige verwendet. In diesem Sinne ist "licht" unzureichend - aber auch "i".
Gast
#4478264
Noch ein Ooops. Sorry. Natürlich unterscheiden sich die abhängigen Anweisungen in noch mehr Punkten. Ich habe das - offen gesagt - ersteinmal aus Lässigkeit ignoriert. Dann schien es mir wahrscheinlicher, dass es sich um ein Versehen handelt. Aber das muss natürlich nicht zutreffen.
Mein grosses V. schrieb: > Ich D. schrieb: >> Wieso geht das nicht ? > > Tolle Frage. Was geht nicht? Natürlich geht das. Es kommt nur nicht das > raus, was du erwartest, oder? > > Du wirst uns schon erzählen müssen, was das ist, was du erwartest. Ich wollte das wenn ich das erste mal den Taster drücke sich der komplette Würfel auf 100% Helligkeit anschaltet und beim 2.ten mal drücken auf 75% dimmt usw. am Ende soll er aus sein und nach nochmal drücken wieder in die Else-schleife springen. Den Taster kann man benutzen da er Pull-up widerstände hat und auch in der Interroupt ein delay von 100ms ist.
Jetzt geht es halbwegs... Wenn ich am anfang meine variable (geändert auf g) auf 1 setze leuchtet der Würfel und das Dimmen funktioniert, wenn ich allerdings einmal durch bin mit dem Dimmen läuft der Rest einfach durch ohne das ich wieder Dimmen kann.
Gast
#4478276
Schau doch mal nach "switch case" ... das ist ein Klassiker dafür :-)
Gast
#4478277
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
Das Problem deines Programmes ist das delay mit zehn Sekunden. Nur danach wird die Varaible Licht neu ausgewertet, selbst wenn diese durch irgendwas (Interrupt) mittlerweile mehrfach verändert wurde. Du solltest das gesamte Konzept des Programmes umstellen. Offensichtlich willst Du verschiedene Bitmuster getimt an Ports ausgeben. Das kleinste Delay welches ich gesehen habe, ist 250µs. ALso baue einen Timertick mit 250µs und schalte dort geeignet um. Das hier macht noch nicht exakt was du wahrscheinlich willst, aber es sollte an Anreiz gehen:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
35 | |
36 | |
37 | |
38 | |
39 | |
40 | |
41 | |
42 | |
43 | |
44 | |
45 | |
46 | |
47 | |
48 | |
49 | |
50 | |
51 | |
52 | |
53 | |
Ich D. schrieb: > in > der Interroupt ein delay von 100ms ist. very bad idea. 1. Versuche herauszufinden warum. 2. Bemühe dich, verständliche Grammatik anzuwenden.
Ich D. schrieb: > Den Taster kann man benutzen da er Pull-up widerstände hat und auch in > der Interroupt ein delay von 100ms ist. Immerhin hast du 'widerstände' nicht mir 'ie' geschrieben. Das ist aber auch schon das einzig Gute. Pull-Ups haben mit Entprellung gar nichts zu tun und ein Delay in der ISR ist nur in ganz wenigen Ausnahmefällen eine gute Idee. Bei einer nicht funktionierenden Entprellung ist es das allerdings nicht. Einen Timer brauchst du sowieso. Damit und nur damit, kannst du das Entprellen gleich mit erledigen.
Ich D. schrieb: > Wieso geht das nicht ? Das Problem sitzt in der Regel vor dem Computer. mfg klaus
Ich entschuldige mich für meine Rechtschreibung ^^ bin noch in der Schule und nicht so häufig in Foren unterwegs. Die Delays habe ich jetzt aus den if-schleifen genommen und es geht immmer noch so halbwegs Trottdem vielen Dank dafür das ihr mir schonmal soweit geholfen habt. martaniu
Ich D. schrieb: > if-schleifen mit if-Schleifen ist man bei Programmierern sofort unten durch ;-)
Ich D. schrieb: > wenn ich allerdings einmal durch > bin mit dem Dimmen läuft der Rest einfach durch ohne das ich wieder > Dimmen kann. dann versuch mal die Antwort von Kaj zu lesen
Gast
#4478505
Ich D. schrieb: > Ich entschuldige mich für meine Rechtschreibung ^^ bin noch in der > Schule und nicht so häufig in Foren unterwegs. > Die Delays habe ich jetzt aus den if-schleifen genommen und es geht > immmer noch so halbwegs Trottdem vielen Dank dafür das ihr mir schonmal > soweit geholfen habt. > martaniu Nun, wenn Du Schüler bist, dann bist Du vermutlich auch ziemlicher Anfänger. Das waren wir alle mal - und viele haben solchen Code geschrieben wie Du. Du sagst das es so halbwegs geht: Es wäre aber vermutlich doch nützlich und würde Deine Note verbessern, wenn Du uns den kompletten Code hier postest und die Kritiken dazu liest und den Code weiter verbesserst. Ich weiß, Kritik ist nicht nur angenehm und manchmal ist der Ton hier sehr rau. Aber es wäre auch nützlich, wenn es Dir gelänge, das möglichst zu ignorieren. Kritisch finde ich, die Verwendung von Interrupts zur Tastenbehandlung und vor allem die Verwendung von Verzögerungen in Interrupts. Letzteres ist für einen Anfänger unter allen Umständen zu vermeiden. Ersteres kann man mit Erfahrung - wenn man es zwangsweise tun MUSS - irgendwie hinkriegen. Aber der Profi vermeidet das, wie Senf auf der Kirschtorte. Eine der Hauptschwierigkeiten für Anfänger besteht darin, sich den tatsächlichen Ablauf ihres Programms irgendwie vorzustellen. Das zu lernen und zu üben, ist ein Problem vor dem jeder mal steht. Das kann man mit verschiedenen Methoden angehen, von denen Du die für Dich beste erst einmal herausfinden musst. Ich schlage Dir vor, dass Du Dir einen Zeitstrahl auf einem grossen Papier hin zeichnest. Ignoriere im ersten Schritt die Interrupts. Schreibe wirkliche Zeiten an den Strahl. Eine sinnvolle Aufteilung hängt von der Taktfrequenz ab. Bei 1MHz sind das etwa 1 bis 5us. Du musst nicht jeden Befehl hinschreiben, aber doch die für die Funktion wesentlichen Befehle. Darunter die Verzögerung. Dann guck Dir den Interrupt an. Nimm den erst einmal als alleinstehenden Code als wenn es den anderen nicht gäbe. Nimm den selben Zeitmaßstab wie in der vorherigen Zeichnung. Nimm am besten einen zweiten Bogen Papier dazu. Wenn Du das fertig hast, dann lege das Papier mit dem Interrupt mal an die Zeitlinie des Hauptprogramms. Wann kann der Interrupt auftreten? Vermutlich immer; stimmt es? Was hat es für Folgen, wenn der Interrupt kurz vor oder während der Verzögerungen auftritt? Wann werden Variablenänderungen im Interrupt für das Hauptprogramm wirksam? Zu der Entprellung lies mal hier: https://www.mikrocontroller.net/articles/Entprellung Viel Erfolg.
Gast
#4479080
Sinnvoll wäre, mein Kommentar weiter oben nochmal zu lesen...
So sieht mein Code bislang aus. Die idee des Dimmens ist ganz oben. Hab jetzt die For-schleife rausgenommen mit den 10 sek. und die Variable verändert. Danke für eure hilfe martaniu -- Über dem Texteingabefeld steht folgendes: Wichtige Regeln - erst lesen, dann posten! Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang -rufus
Gast
#4479664
Ich D. schrieb: > So sieht mein Code bislang aus. Ach du Sch....öner Kot. Das ist Spaghetti vom Feinsten.
Hab den Fehler gefunden :/ Ich kann aus der for-schleife nicht in die if-schleife springen aus der else-if raus. Wenn ihr Ideen habt was ich verändern kann immer her damit. Schonmal im voraus danke. Martaniu
Ich D. schrieb: > Ich kann aus der for-schleife nicht in die if-schleife springen ... http://www.if-schleife.de
Frank M. schrieb: > Ich D. schrieb: >> Ich kann aus der for-schleife nicht in die if-schleife springen ... > > http://www.if-schleife.de ?
Ein paar Anmerkungen : 1. du definierst die variable b einmal global und einmal lokal in der ISR. Mit sowas legt man sich schnell aufs Kreuz. Schalte mal ein paar compiler warnings scharf und versuche den code sauber zu kriegen. 2. globale Variablen, die von ISRs modifiziert werden, solltest du immer volatile deklarieren. Ohne volatile optimiert der Compiler eventuell die Zugriffe auf eine vermeintlich nutzlose Variable weg.
Gast
#4480295
immer her damit. Indem Du Dir meine Antwort (ziemlich weit oben) mal durchliest und es so umsetzt..
Vermutlich auch nicht so gewollt ? Zeile 569 : if (a==1);
Vor allem ist das eigentlich ein Paradebeispiel, welches mit einer Switch <> Case Anweisung zu machen ist.
Ich würde generell jedem Programmierer empfehlen, sich mal die Clean Code Konzepte zu Gemüte zu führen (google ist dein Freund). Wer diese auch nur ein bisschen befolgt, macht es der Gemeinde hier sehr viel einfacher, seinen code zu verstehen und zu beurteilen.
Antwort schreiben
Bitte melde dich an, um einen Beitrag zu schreiben.