Hallo Leute! Ich versuche gerade im Rahmen meiner anfänglichen Arbeit mit Mikrocontroller 3 Led nacheinander an und auszuschalten mit Hilfe einer Atmega8 von Atmel. So schaut mein code aus: #define F_CPU 3686400 #include <avr/io.h> #include <util/delay.h> //#define F_CPU 3686400 const int delay = 10000000; int main(void) { DDRB = 0xFF; // setzt PortB als ausgang while(1) { PORTB |= (1<< PORTB0); // setzt Bit 0 von Port B auf 1 _delay_ms(delay); // warte eine Zeitspanne PORTB &= (1<< PORTB0); // lösche Bit 0 von Port B PORTB |=(1<< PORTB1); // setzt Bit 1 von Port B auf 1 _delay_ms(delay); // warte wieder eine zeitspanne PORTB &= (1<< PORTB1); // usw. PORTB |=(1<< PORTB2); _delay_ms(delay); } } Anstatt nacheinander an und auszugehen, leuchten die LEDs alle gleichzeitig. Was stimmt mit meinem code nicht?? Danke schon mal im voraus
_delay_ms(delay); _delay_ms will eine tatsächliche Konstante. Auch wenn du die Variable const gemacht hast, ist das in C keine Konstante im eigentlichen Sinne (in C++ wäre sie es). Ausserdem sind 10000000 viel zu lang. 10000 Sekunden sind 166 Minuten, also gut und gerne 2.5 Stunden. Ich denke nicht, dass du so lange warten willst.
1 | #define F_CPU 3686400
|
2 | #include <avr/io.h> |
3 | #include <util/delay.h> |
4 | |
5 | //#define F_CPU 3686400
|
6 | #define TIME 500
|
7 | |
8 | int main(void) |
9 | {
|
10 | DDRB = 0xFF; // setzt PortB als ausgang |
11 | |
12 | while(1) |
13 | {
|
14 | PORTB |= (1<< PORTB0); // setzt Bit 0 von Port B auf 1 |
15 | _delay_ms(TIME); // warte eine Zeitspanne |
16 | |
17 | PORTB &= (1<< PORTB0); // lösche Bit 0 von Port B |
18 | PORTB |=(1<< PORTB1); // setzt Bit 1 von Port B auf 1 |
19 | _delay_ms(TIME); // warte wieder eine zeitspanne |
20 | |
21 | PORTB &= (1<< PORTB1); // usw. |
22 | PORTB |=(1<< PORTB2); |
23 | _delay_ms(TIME); |
24 | }
|
25 | }
|
Der Optimizer des Compilers ist eingeschaltet?
Max schrieb: > Außerdem: > >> The maximal possible delay is 262.14 ms / F_CPU in MHz. Das gilt schon lange nicht mehr.
Patrick N. schrieb: > PORTB &= (1<< PORTB0); // lösche Bit 0 von Port B PORTB &= ~(1<< PORTB0); // lösche Bit 0 von Port B
Karl Heinz Buchegger schrieb: > _delay_ms(delay); > > _delay_ms will eine tatsächliche Konstante. Auch wenn du die Variable > const gemacht hast, ist das in C keine Konstante im eigentlichen Sinne > (in C++ wäre sie es). Nein, _delay_ms kann auch mit Variablen umgehen, dadurch wird der Code aber sehr groß. Max schrieb: > Außerdem: > >> The maximal possible delay is 262.14 ms / F_CPU in MHz. und der darauf folgende Absatz:
1 | The maximal possible delay is 262.14 ms / F_CPU in MHz. |
2 | |
3 | When the user request delay which exceed the maximum possible one, |
4 | _delay_ms() provides a decreased resolution functionality. In this mode |
5 | _delay_ms() will work with a resolution of 1/10 ms, providing delays up to |
6 | 6.5535 seconds (independent from CPU frequency). The user will not be |
7 | informed about decreased resolution. |
Timmo H. schrieb: > Karl Heinz Buchegger schrieb: >> _delay_ms(delay); >> >> _delay_ms will eine tatsächliche Konstante. Auch wenn du die Variable >> const gemacht hast, ist das in C keine Konstante im eigentlichen Sinne >> (in C++ wäre sie es). > > Nein, _delay_ms kann auch mit Variablen umgehen, dadurch wird der Code > aber sehr groß. OK. Umgehen ist das falsche Wort. Die Zeiten stimmen nicht, was ja nicht im Sinne des Erfinders ist.
Hallo Leute! Erstmal vielen dank für die schnellen und zahlreichen Antworten. Das hat mir sehr viel geholfen. So sehr dass ich mich bereit fühlte für den nächste schritt. Und zwar dieses mal eine Routine zu schreiben womit ich alle LEDs die an einem PORT angeschlossen sind nacheinander an und ausschalten kann. und so sieht mein Code aus: #include <avr/io.h> #include <util/delay.h> #define F_CPU 3686400 #define delay 1 #define leuchtdauer 4 #define meinbit 7 void warten_1sek() { unsigned long n; for(n=0; n<50; n++) _delay_ms(80); } void warten_Nsek (unsigned long n) { unsigned long k; for (k=0; k<n; k++) warten_1sek(); } void led_on_off (void){ unsigned long i; for (i=0; i<= meinbit; i++) warten_Nsek (delay); PORTB |= (1<< i); warten_Nsek (leuchtdauer); PORTB = 0x00; } int main(void) { DDRB = 0xFF; // setzt PortB als ausgang while(1) { led_on_off(); } } Aber wie e bei Anfänger so ist, klappt es auch wieder nicht. Die LEDs gehen überhaupt nicht an. woran kann es dieses mal liegen? Danke
Patrick N. schrieb: Rücke diesen Code mal so ein, wie du es haben willst. Welche Anweisungen sollen in der for-Schleife sein: > void led_on_off (void){ > unsigned long i; > for (i=0; i<= meinbit; i++) > warten_Nsek (delay); > PORTB |= (1<< i); > warten_Nsek (leuchtdauer); > PORTB = 0x00; > } Nachdem du deine Vorstellung davon, was alles innerhalb der Schleife passieren soll, mal sauber durch einrücken klar gemacht hast, zeig ich dir, wie der Compiler die Sache sieht. Nämlich so
1 | void led_on_off (void) |
2 | {
|
3 | unsigned long i; |
4 | |
5 | for (i=0; i<= meinbit; i++) |
6 | warten_Nsek (delay); |
7 | |
8 | PORTB |= (1<< i); |
9 | warten_Nsek (leuchtdauer); |
10 | PORTB = 0x00; |
11 | }
|
und das ist etwas anderes als du wolltest. Fazit: eine vernünftige optische Aufbereitung deines Codes, kann dir helfen Fehler zu sehen. Du willst das hier
1 | void led_on_off (void) |
2 | {
|
3 | unsigned long i; |
4 | |
5 | for (i=0; i<= meinbit; i++) |
6 | {
|
7 | warten_Nsek (delay); |
8 | PORTB |= (1<< i); |
9 | }
|
10 | |
11 | warten_Nsek (leuchtdauer); |
12 | PORTB = 0x00; |
13 | }
|
Die { } Klammern machen den Unterschied. Bei mir sieht man auf einen Blick, dass sie da sind. Bei deinem Originalcode muss man wissen, dass man danach suchen soll, sonst siehst du nie und nimmer, dass du sie vergessen hast. Das du dein Vergessen nicht siehst, liegt nicht zuletzt daran, dass dein Code ein monolithischer Haufen Buchstaben ohne jede Struktur ist. Was zb stimmt hier nicht?
1 | int main(void) |
2 | {
|
3 | DDRB = 0xFF; // setzt PortB als ausgang |
4 | |
5 | while(1) |
6 | {
|
7 | led_on_off(); |
8 | }
|
9 | |
10 | }
|
Antwort: Die jeweils schliessende } steht nicht unter der zugehörigen öffnenden { In der while Schleife ist das davon abhängige Statement nicht eingerückt. Dein Einrückungsschema ist inkonsistent. Warum steht das setzen von DDRB am linken Rand und das while danach ist um 4 Zeichen eingerückt. An anderer Stelle in deinem Code hast du 2 Zeichen eingerückt. Das ganze sollte so aussehen
1 | int main(void) |
2 | {
|
3 | DDRB = 0xFF; // setzt PortB als ausgang |
4 | |
5 | while(1) |
6 | {
|
7 | led_on_off(); |
8 | }
|
9 | }
|
optisch sauberer Code ist kein Selbstzweck. Er ist ein Mittel um dem Gehirn eine Leitlinie zu geben. D.h. man macht das immer und nicht erst irgendwann hinterher! Und es hilft dir Fehler zu sehen.
Ich bin dir sehr dankbar für deine Anmerkungen und Antworten an meine Sorgen. Werde mich ab heute viel mehr mühe geben meine code struktur und Sauberkeit zu geben. Danke noch mal.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.