Hallo, ich habe bis gestern gedacht, ich kann mal schnell nebenbei ein Lauflicht programmieren. Doch leider wurde mir nach längerer Fehlersuche eines besseren belehrt. Das Licht sollte einfach nur nach rechts laufen. Das tut es auch mehr oder weniger, aber jeden LED blinkt nur kurz auf statt für 1sec zu leuchten. Das lustige an der Sach ist aber wenn ich über ledra oder ledla alle LEDs blinken lasse bzw. aktivieren Funktioniert es. Kann mir bitte jemand helfen? Ich finden den Fehler leider nicht. AVR Atmega8 Internen Quarz AVR Studio 6 LEDS über BC639 an: PB6 PB7 PD5 PD6 PD7 PB0 das wäre der Sourcecode: ------------------------------------------------------------------------ --- #include <avr/io.h> #include <util/delay.h> #define F_CPU 1000000 unsigned char ledl1 = 0; unsigned char ledl2 = 0; unsigned char ledl3 = 0; unsigned char ledr1 = 0; unsigned char ledr2 = 0; unsigned char ledr3 = 0; unsigned char ledla = 0; unsigned char ledra = 0; void ausgabe(void) { if (ledl1 == 1) { PORTB = PORTB | (1<<PD0); } else { PORTB = PORTB &~ (1<<PB0); } if (ledl2 == 1) { PORTD = PORTD | (1<<PD7); } else { PORTD = PORTD &~ (1<<PD7); } if (ledl3 == 1) { PORTD = PORTD | (1<<PD6); } else { PORTD = PORTD &~ (1<<PD6); } if (ledr1 == 1) { PORTD = PORTD | (1<<PD5); } else { PORTD= PORTD &~ (1<<PD5); } if (ledr2 == 1) { PORTB = PORTB | (1<<PB7); } else { PORTB = PORTB &~ (1<<PB7); } if (ledr3 == 1) { PORTB = PORTB | (1<<PB6); } else { PORTB = PORTB &~ (1<<PB6); } if (ledla == 1) { PORTB = PORTB | (1<<PB0); PORTD = PORTD | (1<<PD7); PORTD = PORTD | (1<<PD6); } else { PORTB = PORTB &~ (1<<PB0); PORTD = PORTD &~ (1<<PD7); PORTD = PORTD &~ (1<<PD6); } if (ledra == 1) { PORTD = PORTD | (1<<PD5); PORTB = PORTB | (1<<PB7); PORTB = PORTB | (1<<PB6); } else { PORTD = PORTD &~ (1<<PD5); PORTB = PORTB &~ (1<<PB7); PORTB = PORTB &~ (1<<PB6); } } int main(void) { DDRB = DDRB | (1<<PB0)| (1<<PB6)| (1<<PB7); // Ausgänge DDRD = DDRD | (1<<PD5)| (1<<PD6)| (1<<PD7); // Ausgänge PORTD = 0x1F; //Pullups für Eingänge aktiviren while(1 == 1) { ledl1=0; ledl2=0; ledl3=0; ledr1=0; ledr2=0; ledr3=0; ausgabe(); _delay_ms(1000); ledl1=0; ledl2=1; ledl3=0; ledr1=0; ledr2=0; ledr3=0; ausgabe(); _delay_ms(1000); ledl1=0; ledl2=0; ledl3=1; ledr1=0; ledr2=0; ledr3=0; ausgabe(); _delay_ms(1000); ledl1=0; ledl2=0; ledl3=0; ledr1=1; ledr2=0; ledr3=0; ausgabe(); _delay_ms(1000); ledl1=0; ledl2=0; ledl3=0; ledr1=0; ledr2=1; ledr3=0; ausgabe(); _delay_ms(1000); ledl1=0; ledl2=0; ledl3=0; ledr1=0; ledr2=0; ledr3=1; ausgabe(); _delay_ms(1000); } } ------------------------------------------------------------------------ -- Besten Dank! PS: Ich würde fast darauf wetten, dass es ein peinlicher Fehler ist :-)
Gast
#2785034
Rolf Schmidt schrieb: > PS: Ich würde fast darauf wetten, dass es ein peinlicher Fehler ist :-) Das glaube ich auch, so macht doch kein Mensch ein Lauflicht! Schau Dir mal die logischen Operationen wie Bitshift an. Alternativ auch die Multiplikation/Division mit/durch 2.
Gast
#2785037
Wie ist deine Optimierung eingestellt? Ich sehe keinen Fehler. Beschreib mal dein Blitzen! Welche IDE? Ingo
Gast
#2785038
Reihenfolge
1 | |
2 | |
falsch ;( hans
Wow. Das ist das komplizierteste Lauflicht, an das mich erinnern kann. Und das will in diesem Forum was heißen.
Gast
#2785041
Schmeiß den Code weg und fang von vorne an. Vorher aber bitte in einem Buch über den shift-operator lesen... Alle LEDs an einen PORT, dann ist das ein 3-Zeiler.
Gast
#2785042
OK, zu langsam...
Gast
#2785048
hans schrieb: > Reihenfolge#include <util/delay.h> > #define F_CPU 1000000 > falsch ;( > > hans Richtig, hatte ich überlesen (Bei dem riesen Code). Aber wenn der interne Oszillator läuft (8Mhz oder 1MHz), dann sollte die 1s halt etwas länger sein. Ingo
Karl Heinz Buchegger schrieb: > Wow. > Das ist das komplizierteste Lauflicht, an das mich erinnern kann. > Und das will in diesem Forum was heißen. Aber .... Ingo hat Recht. Einen offensichtlichen Fehler gibt es nicht.
Wie sieht deine Schaltung aus (LEDs, Transistoren etc.)?
Gast
#2785096
Dämlichster (Troll-)Fehler wo gibt!!! Bei ausgabe() schaltest Du deine Wunsch-Led ein und unten bei der letzten if-clause setzt Du beide Ports wieder auf aus. Ausnahme: Es werden alle LEDs ein- oder ausgeschaltet. Ab in die Ecke und schämen!!!
debugger schrieb: > Dämlichster (Troll-)Fehler wo gibt!!! > > Bei ausgabe() schaltest Du deine Wunsch-Led ein und unten bei der > letzten if-clause setzt Du beide Ports wieder auf aus. Ausnahme: Es > werden alle LEDs ein- oder ausgeschaltet. <Hand an die Strin klatsch> > > Ab in die Ecke und schämen!!! Richtig. Nämlich: wir Helfer.
Klar kenn ich die shift-operatoren. Wenn man sich den Code an sieht, dann sieht man auch, dass ich ihn zum setzten der Ausgänge nehme :-) Er ist aber wegen Zusatzfunktionen (nicht online) leider ungeeignet. Und wenn die Hardware schon fertig ist, kann man nicht einfach irgendwelche Pins tauschen :-) Aber ich hatte recht, es war ein sehr peinlicher und einfacher Fehler. X+2 Augen sind halt immer besser als nur zwei :-) Danke für den Hinweis
Gast
#2786340
Wirst du nach Codezeilen bezahlt? :)
Du könntest doch wenigstens die ganzen (unsigned char) durch eine einzige ersetzen, bei der jedes Bit für eine LED steht. Dann brauchst Du im Hauptprogramm auch nicht (gefühlte) 500 Schreibzugriffe, sondern nur:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
Nur so als Denkanstoß. Wie die ausgabe() Funktion umgeschrieben werden muss, kannst Du Dir sicher selbst denken.
das muss ich natürlich zugeben, diese Variante ist bedeutent schöner programmiert als meine "quick and dirty" Version.
Gast
#2787931
Bei der langen Tipparbeit und Fehlersuche, ist das wohl kaum als "quick" zu bezeichnen...
R. Schmidt schrieb: > Und wenn die Hardware schon fertig ist, kann man nicht einfach > irgendwelche Pins tauschen :-) Das ist richtig. Aber man kann sich zb in einem, nein 2, Arrays die jeweils an den ports auszugebenden Werte ablegen und dann ganz einfach in ausgabe() in die Arrays indizieren um den Wert zu erfahren, der ausgegeben werden soll. Dann spart man sich einen Großteil dieser if - else kette
Gast
#2787939
R. Schmidt schrieb: > mal schnell nebenbei ein > Lauflicht programmieren. Gratuliere. Dein Code hat es in meine All-Time "so-macht-man-es-nicht" Sammlung geschafft...
Bart schrieb: > Bei der langen Tipparbeit und Fehlersuche, ist das wohl kaum als "quick" > zu bezeichnen... Dafür dirty!
Gast
#2788226
Also ich finde den Code toll. Den hebe ich mir auf und erschrecke damit kleine Kinder.
Gast
#2788235
Checker Bunny schrieb: > Den hebe ich mir auf Das wäre doch was zur Abschreckung neugieriger Kollegen? Das muss auch in die Schreibunterlage mit rein!
Gast
#2791037
Ich bin zwar auch Anfänger, aber da musste auch ich schlucken.
Kompliziert.
Wie es der Zufall so will, habe ich vor 2 Tagen auch ein Lauflicht
gemacht.
Mein Code ist extrem simpel da er erstmal zum testen war, man kann noch
etwas optimieren.
Das ganze läuft auf einem Attiny 44 mit internem Takt. Das einzigste was
Du tun musste ist die Pinausgänge festlegen und Pinnamen entsprechend
Deines Avr ändern.
#include <avr/io.h>
#include <util/delay.h>
int main(void)
{
DDRA = (1 << PA0) | (1 << PA1) | (1 << PA2) | (1 << PA3) | (1 << PA5)
| (1 << PA7);
DDRB = (1 << PB0) | (1 << PB1) | (1 << PB2);
while(1)
{
PORTA |= (1 << PA0); _delay_ms(70);
PORTA &= ~((1 << PA0));
PORTA |= (1 << PA1); _delay_ms(70);
PORTA &= ~((1 << PA1));
PORTA |= (1 << PA2); _delay_ms(70);
PORTA &= ~((1 << PA2));
PORTA |= (1 << PA3); _delay_ms(70);
PORTA &= ~((1 << PA3));
PORTB |= (1 << PB0); _delay_ms(70);
PORTB &= ~((1 << PB0));
PORTB |= (1 << PB1); _delay_ms(70);
PORTB &= ~((1 << PB1));
PORTB |= (1 << PB2); _delay_ms(70);
PORTB &= ~((1 << PB2));
PORTA |= (1 << PA7); _delay_ms(70);
PORTA &= ~((1 << PA7));
PORTA |= (1 << PA5); _delay_ms(70);
PORTA &= ~((1 << PA5));
PORTA |= (1 << PA7); _delay_ms(70);
PORTA &= ~((1 << PA7));
PORTB |= (1 << PB2); _delay_ms(70);
PORTB &= ~((1 << PB2));
PORTB |= (1 << PB1); _delay_ms(70);
PORTB &= ~((1 << PB1));
PORTB |= (1 << PB0); _delay_ms(70);
PORTB &= ~((1 << PB0));
PORTA |= (1 << PA3); _delay_ms(70);
PORTA &= ~((1 << PA3));
PORTA |= (1 << PA2); _delay_ms(70);
PORTA &= ~((1 << PA2));
PORTA |= (1 << PA1); _delay_ms(70);
PORTA &= ~((1 << PA1));
}
}
Also wie man sieht geht es auch extrem einfach.
Gruß
Fred
Gast
#2791043
Achja. Du kannst z.B. einfach einen Vorwiderstand vor die LED bauen. Plus kommt vom Chip und Minus an gemeinsame Masse.
Gast
#2791045
lol
Gast
#2791047
Fred schrieb: > Also wie man sieht geht es auch extrem einfach. Genau:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
SCNR Wie wäre es mit einem Wettbewerb: Wer schreibt das kürzeste Lauflicht?
Gast
#2791054
Das ist mir klar, daß ich das ganze in einer schleife machen kann. Ich wollte halt nur zeigen, daß seines schon extrem umständlich ist. Auch wenn Deines schön klein ist, so finde ich es absolut unübersichtlich. Zum lernen finde ich die Portnamen etc. besser.
Gast
#2791056
troll schrieb: > Wie wäre es mit einem Wettbewerb: Wer schreibt das kürzeste Lauflicht? Ich leg dann mal vor:
1 | |
2 | |
3 | |
Kann sein dass man noch unsigned vor den char setzen muss, hab gerade keinen AVR-GCC zur Hand. Mal sehen, vielleicht schlage ich Karl-Heinz ja dieses Mal...
Gast
#2791060
troll schrieb: > Kann sein dass man noch unsigned vor den char setzen muss Nein Blödsinn, das war für eine andere Version. :-(
Gast
#2791061
Ich sehe schon, wie in so manchen anderen Threads wird hier alles ins lächerliche gezogen. Vielleicht sollte man mal über die Gastfunktion nachdenken.
Gast
#2791065
Fred schrieb: > Ich sehe schon, wie in so manchen anderen Threads wird hier alles ins > lächerliche gezogen. > Vielleicht sollte man mal über die Gastfunktion nachdenken. Ich ziehe überhaupt nichts ins Lächerliche... Sei nicht so humorlos, kurze (und unübersichtliche) Programme in C haben eine lange Tradition. Siehe auch IOCC. :-)
Gast
#2791067
Sorry for x-fach-Post. Ich bessere nochmal nach: Beispiel =~ s!#include <util/delay.h>!! Sollte funktionieren, Defaultwerte passen.
...viel interessanter ist ein Lauflicht mit 10 Duo LED an 5 Portpins mit 5 Widerständen. Mit integriertem weichem Farbwechsel von rot zu grün während das Lauflicht läuft.... TS
Die Ausgabefunktion kann man auch drastisch vereinfachen. Und Parameterübergabe macht man nicht in globalen Variablen, sondern direkt:
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 | |
Peter
Antwort schreiben
Bitte melde dich an, um einen Beitrag zu schreiben.
