Hallo zusammen, ich hoffe ihr könnt mir helfen. Also ich habe mir vor kurzem einen 4x4x4 LED Würfel gelötet. Dieser wird mit einem Atmega 16 angesteuert Er wird Folgendermaßen angesteuert, insgesamt laufen 20 Signalleitungen zu der Platine. Diese sind wie folgt belegt, -16 dieser Leitungen gehen an die verschiedenen Fußpunkte eines LED Türmchens, d.h. immer 4 LED's übereinander hängen an einem Port -4 dieser Leitungen schalten die Masse für die verschiedenen Ebenen durch. Jetzt versuche ich gerade ein Initialiserungsprogramm in C zu schreiben. Es sollte jede LED einzeln ansteuern und 3 mal blinken lassen. Einfach als LED Test ob noch alle LED's funktionsfähig sind. Leider komme ich hier gerade nicht weiter. Die for Schleifen führt er alle nicht sichtbar aus, er braucht zwar jetzt einen Moment nach dem Microcontroller Reset bevor die while schleife ausgeführt wird, allerdings ist von der for schleife nichts zu sehen, ich hoffe ihr könnt mir helfen. #include <avr/io.h> #include <util/delay.h> #include <stdint.h> void delay_ms(uint16_t ms) { for (uint16_t t=0; t<=ms; t++) _delay_ms(1); } int ebene, tab, turmcd; /* Blinkfunktion beginn */ void blinken() { int zaehler; zaehler=0; for (uint8_t zaehler=0; zaehler<=3; zaehler++) PORTA = tab; PORTB = ebene; PORTD = turmcd; _delay_ms(500); PORTA = 0; PORTB = 0; PORTD = 0; _delay_ms(200); } /*Blinkfunktion Ende */ //Globalvariablendeklaration //int ebene, tab, turmcd; //Hauptprogramm int main() { //Variablendefinition ebene=1; tab=0; turmcd=0; DDRA=0xFF; // Turm A und B DDRB=0xFF; // Ebene DDRD=0xFF; // Turm C und D for (ebene=1; ebene<=4; ebene++); { for (tab=0; tab<=8; tab++); { blinken(); } for (turmcd=0; turmcd<=8; turmcd++); { blinken(); tab=0; turmcd=0; } } while (1) { PORTA = 0b11111111; PORTB = 0b11111111; PORTD = 0b11111111; delay_ms (10000); PORTA = 0b00001110; PORTB = 0b00111100; PORTD = 0b00111100; delay_ms (500); } return 0; }
Ich weiß nicht ob das so gewollt ist... laut syntax vermute ich mal nicht... aber wenn du eine for schleife mit ; abschließt, hast du eine leere schleife
In der Funktion "blinken" fehlen meines Erachtens nach geschweifte Klammern hinter der for-Schleife. An anderen for-Schleifen sind wahrscheinlich ungewollte Semikolons dran... gute Nacht ;)
Hallo, erstmal danke für die schnellen antwoten, nun das habe ich jetzt gemacht.. jetzt sind die LeD's mal für ne weile aus.. aber an und blinken geht trotzdem nicht? habe ich da jetzt noch was übersehen??
in blinken: int zaehler; zaehler=0; for (uint8_t zaehler=0; zaehler<=3; zaehler++) Du deklarierst zaehler doppelt.. einmal als int (4byte) und einmal als uint8_t (1byte) wundert mich aber, dass der compiler nicht motzt...
mh.. also ich compilier mit Avr Studio, 0 warnings.. aber jetzt wo du es sagst.. dann schmeiß ich mal den int raus.. Jetzt sieht der Quelltext wie folgt aus.. Muss ich die Ports anders ansteuern damit er die Ports richtig freischaltet?? #include <avr/io.h> #include <util/delay.h> #include <stdint.h> void delay_ms(uint16_t ms) { for (uint16_t t=0; t<=ms; t++) _delay_ms(1); } int ebene, tab, turmcd; /* Blinkfunktion beginn */ void blinken() { uint8_t zaehler; zaehler=0; for (zaehler=0; zaehler<=3; zaehler++) { PORTA = tab; PORTB = ebene; PORTD = turmcd; _delay_ms(500); PORTA = 0; PORTB = 0; PORTD = 0; _delay_ms(200); } } /*Blinkfunktion Ende */ //Globalvariablendeklaration //int ebene, tab, turmcd; //Hauptprogramm int main() { //Variablendefinition ebene=1; tab=0; turmcd=0; DDRA=0xFF; // Turm A und B DDRB=0xFF; // Ebene DDRD=0xFF; // Turm C und D for (ebene=1; ebene<=4; ebene++) { for (tab=0; tab<=8; tab++) { blinken(); } for (turmcd=0; turmcd<=8; turmcd++) { blinken(); tab=0; turmcd=0; } } while (1) { PORTA = 0b11111111; PORTB = 0b11111111; PORTD = 0b11111111; delay_ms (10000); PORTA = 0b00001110; PORTB = 0b00111100; PORTD = 0b00111100; delay_ms (500); } return 0; }
Michi schrieb: > Du deklarierst zaehler doppelt.. einmal als int (4byte) und einmal als > uint8_t (1byte) > > wundert mich aber, dass der compiler nicht motzt... wird die erste Variable nicht einfach überdeckt und der zweite zaehler ist nach der for wieder sichtbar? -> C++
Ja also in der Portansteuerung sehe ich jetzt keinen Fehler. Aber mich macht dieser Teil stutzig: for (ebene=1; ebene<=4; ebene++) { for (tab=0; tab<=8; tab++) { blinken(); } for (turmcd=0; turmcd<=8; turmcd++) { blinken(); tab=0; //Warum setzt du jeden durchlauf tab auf 0? turmcd=0; //Deine Bedinung ist, mach solange turmcd <=8 ist. //aber du "resetest" jeden durchgang turmcd -> eine //endlosschleife } }
hmmmmmmm schrieb: > wird die erste Variable nicht einfach überdeckt und der zweite zaehler > ist nach der for wieder sichtbar? > -> C++ Naja der GCC kann doch kein C++ oder? Ich bin mir nicht zu 100% sicher, ob die variable überdeckt wird, aber im zweifelsfall würde ich micht nicht darauf verlassen. Mich wunderts sowieso, dass er for(int i=0; i<8;i++) zulässt, da bei C imho die variable vor der schleife bereits deklariert sein muss
Okay, da hatte ich dann einen denkfehler als ich die geschweiften Klammern gesetzt habe, ich habe grad das Gefühl ich sehe den Wald vor lauter Bäumen nicht mehr. Mh.. ja.. aber was ich mich gerade frage, kann ich einen INT auf einen Port schreiben und er gibt ihn mir dann richtig aus, muss ich da nicht eher eine Binär bzw. Hex Zahl schreiben?? also zum Beispiel for(ebene=0x00; ebene<=0x0F; ebene+0x04) ?? Vielen Dank für die schnellen Antworten.
Michi schrieb: > Naja der GCC kann doch kein C++ oder? http://www.mikrocontroller.net/articles/AVR-GCC 2ter Absatz.
Das macht schon der Compiler für dich. Ob du nun 0x10 oder dezimal 16 schreibst, ist Reh wie Hirsch.
Nö, da dir eh alles umgerechnet wird... wenn du zum beispiel PORTA = 0x3A; schreibst, dann ist es genau das gleiche wie PORTA = 0b00111010; und das ist das genau das gleiche wie PORTA = 58; Da dein Port aber genau 8Bit breit ist (also 1 Byte) werden die oberen 3 Byte deiner INT-Variable (die hat nämlich 4Byte) entweder abgeschnitten, oder es wird der überlauf in deinen Port geschrieben
hmmmmmmm schrieb: > http://www.mikrocontroller.net/articles/AVR-GCC 2ter Absatz. Alles klar. Nur wie gesagt, ich würde mich nicht wetten trauen, das als Fehlerquelle auszuschließen... von der Übersichtlichkeit des Codes ganz zu schweigen
Mh.. also irgendwie komm ich grad nich mehr weiter... scheint so als wär ich zu doof dafür grad.. Ja ich weiß die leserlichkeit.. Irgendwie hab ich da was verplant.. viel stückwerk gewesen.. dachte ich schreib das mal eben schnell un dann wurd es hier nichts und da nichts.. un so hat sich das dann über tage hingezogen.. ergebnis ist ja jetzt zu bewundern.. argh.. naja.. noch irgendwleche Ideen?? wenn er seine Routinen durch hat springt er inzwishcen wieder in die while schleife... nur die LED's wollen nicht angehen
Ja, schreibs dir in Pseudocode auf ein Blatt Papier und übersetze es erst anschließend in c. Also in der Art: main: initialisiere Ports for all x 0...dimX for all y 0...dimY for all z 0...dimZ blinkeLED(x, y, z) rof rof rof blinkeLED(u_int8 x, y, z): for all c 0...3 LED_ON(x, y, z) warte LED_OFF(x, y, z) warte rof
Wie steht es denn um die Genauigkeit des _delay ()? Ist mir gerade nicht im Detail bekannt, muss doch aber mit CPU oder Timer Takt angepasst werden?
Das delay passt, das sholt sich über das makefile den cpu Takt. das ist für die Anwendung hier ausreichend. Werde mich heute nochmal dran setzen und das ganze verushcen neu zu Programmieren. die schleifen und die Inits werden umgemodelt. Und dann wird das ganze nochmal getestet.. Vielen Dank für eure Hilfe
Hallo Bin zwar spät dran, aber
1 | int main() |
2 | {
|
3 | |
4 | //Variablendefinition
|
5 | |
6 | ebene=1; |
7 | tab=0; |
8 | turmcd=0; |
macht zwar korrekterweise die ausführung der schleifen möglich, jedoch kennt deine funktion blinken() meiner Meinung nach die Werte dieser Variablen NICHT. Schreibe dann lieber deine Funktion blinken() um wie folgt:
1 | void blinken(uint8_t tab, uint8_t ebene, uint8_t turmcd) |
2 | {
|
3 | uint8_t zaehler; |
4 | zaehler=0; |
5 | for (zaehler=0; zaehler<=3; zaehler++) |
6 | {
|
7 | PORTA = tab; |
8 | PORTB = ebene; |
9 | PORTD = turmcd; |
10 | _delay_ms(500); |
11 | PORTA = 0; |
12 | PORTB = 0; |
13 | PORTD = 0; |
14 | _delay_ms(200); |
15 | }
|
16 | }
|
und rufe dann
1 | blinken(tab, ebene, turmcd); |
an all den bisherigen vorkommen von blinken() auf Anndere Möglichkeit: Verwende diese Variablen GLOBAL Hoff das bringt dich weiter MFG
AlienX schrieb: > Er wird Folgendermaßen angesteuert, insgesamt laufen 20 Signalleitungen > zu der Platine. > > Diese sind wie folgt belegt, > -16 dieser Leitungen gehen an die verschiedenen Fußpunkte eines LED > Türmchens, d.h. immer 4 LED's übereinander hängen an einem Port > -4 dieser Leitungen schalten die Masse für die verschiedenen Ebenen > durch. Wie sieht deine Verdrahtung konkret aus? Wie ist da der Zusammenhang mit den Portpins? Sind da zb in den Ebenen 8-aus-3-Dekoder drinnen? (Du verwendest 'ebene' bzw damit den PORTB als ob da welche wären) > Ja ich weiß die leserlichkeit.. Dann tu was dagegen! Jammern bringt dich nicht weiter. Das absolute Minimum ist, das deine Einrückungen stimmen. Dass dein Code fehlerverseucht ist, wundert mich kein bischen. Fang nicht damit an gleich mal alle LED nacheinander blinken zu lassen. Fang damit an, 1 LED aufleuchten zu lassen. Wie müssen dann laut deinem Schaltplan die Portbits stehen? Stell sie ein, nimm ein Multimeter und verfolg das in deiner Schaltung. Auch du machst den Kardinalfehler: Du gehst davon aus, dass du ein relativ komplexes Gebilde auf Anhieb fehlerfrei hinkriegst. Und damit meine ich sowohl Hardware als auch Software.
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.