Hilfe beim Programmieren eines LED Cubes Atmega16

Gast #1869791
Lesenswert?

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;
}
Gast #1869810
Lesenswert?

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??
Gast #1869815
Lesenswert?

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...
Gast #1869825
Lesenswert?

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;
}
Gast #1869829
Lesenswert?

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++
Gast #1869830
Lesenswert?

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
   }
}
Gast #1869837
Lesenswert?

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
Gast #1869840
Lesenswert?

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.
Gast #1869848
Lesenswert?

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
Gast #1869859
Lesenswert?

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
Gast #1869873
Lesenswert?

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
Gast #1870047
Lesenswert?

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
Gast #1881861
Lesenswert?

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
#1882046
Lesenswert?

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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren