Franky55555
06.01.2011, 01:11
Hi!
ich habe mir einen 3x3x3-LED-Cube gebaut und programmiert. Funktioniert auch ganz gut.
Hier der Quellcode:
/*
################################################## ###
pin D0-7:LED1-8
pin C0: Led9
pin C1-3: ebene 1-3
led_cube_3x3x3_v5
4bit-helligkeitsstufen (16, 0-15)
Erklärung:
wenn die jeweilige ebene aktiv ist, dann wird jede led der ebene so lange eingeschltet, wie es der helligkeit im array entspricht
Ebene aktiv: ________----------________----------________----------________----------________----------
led: 100% ________----------________----------________----------________----------________----------
led: 80%: __________--------__________--------__________--------__________--------__________--------
led: 50%: _____________-----_____________-----_____________-----_____________-----_____________-----
led: 20%: ________________--________________--________________--________________--________________--
led: 0%: __________________________________________________ ________________________________________
################################################## ###
*/
#include <avr\io.h>
#include <avr\interrupt.h>
#include <stdint.h>
#include <stdio.h>
#define outp(a,b) b=a;
#define F_CPU 8000000UL //zum testen
#include <util/delay.h> //zum testen
//ich will uint8_t oder besser was mit 4bit
int zaehler_helligkeit=15;
int ebene=0;
//ich will uint8_t oder besser was mit 4bit, aber es geht nicht
int led[3][9]= {{15, 15, 15, 15, 15, 15, 15, 15, 15}, //Array in dem die Helligkeiten der leds gespeichert sind, Die 3 zeilen sind die 3 ebenen im würfel, und die 9 spalten die 9 türme. 0=dunkel, 15=hell
{15, 15, 15, 15, 15, 15, 15, 15, 15},
{15, 15, 15, 15, 15, 15, 15, 15, 15}};
int portd=0;
int portc=0;
int i; //zählervariable
void init(void)
{
DDRD = 0b11111111;
DDRC = 0b11111111;
DDRB = 0b11111111;
//Timer-Einstellungen
outp((1<<TOV0), TIMSK); //Timer Overflow Interrupt einschalten
TCNT0=0x00; //Zähler-Startwert setzen
outp((1<<CS00), TCCR0); //vorteiler: 1
sei(); //Interrupts einschalten
}
ISR(TIMER0_OVF_vect) /*Interrupt-Routine*/
{
//ebenen-multiplex-frequenz=interrupt-frequenz/(16*3)
//zählt 15-0_15-0
if(zaehler_helligkeit==0) //wenn der durchlauf fertig ist...
{
zaehler_helligkeit=15; //..., dann wieder von vorne beginnen und
if (ebene==2) //wenn alle ebenen dran waren...
{
ebene=0; //..., dannn wieder von vorne beginnen
}
else //wenn noch nichd alle dran waren, dann...
{
ebene++; //...nächste ebene aktivieren
}
}
else
{
zaehler_helligkeit--; //wenn der durchlauf noch nicht fertig ist, dann runterzählen
}
//ebene_? aktivieren, die anderen deaktivieren
portc=(1 << (ebene+1));
portd=0;
for(i=0;i<8;i++) //für jeden led ausgang machen, bis auf den letzten
{
if(led[ebene][i]>zaehler_helligkeit)
{
portd=portd | (1 << i);
}
}
if(led[ebene][8]>zaehler_helligkeit) //letzter led-ausgang auf anderem port (c statt d)
{
portc=portc | 0b00000001;
}
PORTC=portc;
PORTD=portd;
}
int main(void)
{
init(); //init() starten
while (1)
{
//Hier kommt was hin, das immer neue werte in das array schreibt, um die leds zu verändern, um Muster zu erzeugen
PORTB = 0b00000001; //test
_delay_ms(500);
PORTB = 0b00000000; //test
_delay_ms(500);
}
}
ich habe jetzt 2 Probleme:
1. Ich habe zu Testzwecken eine LED an B0, die ich mit der _delay_ms() Funktion blinken lassen will (f=1Hz). In Wirklichkeit dauert das blinken aber ca. 260 Mal länger. Wieso? Kann es daran liegen, dass die _delay_ms() Funktion dauernd vom Interrupt unterbrochen wird, und so nicht weiterkommt? Oder woran kann es sonst noch liegen?
2. Ich will für manche Variablen ein uint8_t statt einem int verwenden, da ein int Speicherverschwendung ist. Wenn ich aber die Variable als uint8_t deklariere, dann wird das uint8_t irgendwie nicht erkannt, dh. nicht blau gefärbt, wie z.B. int. Wieso nicht?
Und gibt es vllt. einen Datentyp mit nur 4bit? dann könnte ich noch mehr Speicher sparen...
ich hoffe, ihr könnt mir helfen.
MfG
ich habe mir einen 3x3x3-LED-Cube gebaut und programmiert. Funktioniert auch ganz gut.
Hier der Quellcode:
/*
################################################## ###
pin D0-7:LED1-8
pin C0: Led9
pin C1-3: ebene 1-3
led_cube_3x3x3_v5
4bit-helligkeitsstufen (16, 0-15)
Erklärung:
wenn die jeweilige ebene aktiv ist, dann wird jede led der ebene so lange eingeschltet, wie es der helligkeit im array entspricht
Ebene aktiv: ________----------________----------________----------________----------________----------
led: 100% ________----------________----------________----------________----------________----------
led: 80%: __________--------__________--------__________--------__________--------__________--------
led: 50%: _____________-----_____________-----_____________-----_____________-----_____________-----
led: 20%: ________________--________________--________________--________________--________________--
led: 0%: __________________________________________________ ________________________________________
################################################## ###
*/
#include <avr\io.h>
#include <avr\interrupt.h>
#include <stdint.h>
#include <stdio.h>
#define outp(a,b) b=a;
#define F_CPU 8000000UL //zum testen
#include <util/delay.h> //zum testen
//ich will uint8_t oder besser was mit 4bit
int zaehler_helligkeit=15;
int ebene=0;
//ich will uint8_t oder besser was mit 4bit, aber es geht nicht
int led[3][9]= {{15, 15, 15, 15, 15, 15, 15, 15, 15}, //Array in dem die Helligkeiten der leds gespeichert sind, Die 3 zeilen sind die 3 ebenen im würfel, und die 9 spalten die 9 türme. 0=dunkel, 15=hell
{15, 15, 15, 15, 15, 15, 15, 15, 15},
{15, 15, 15, 15, 15, 15, 15, 15, 15}};
int portd=0;
int portc=0;
int i; //zählervariable
void init(void)
{
DDRD = 0b11111111;
DDRC = 0b11111111;
DDRB = 0b11111111;
//Timer-Einstellungen
outp((1<<TOV0), TIMSK); //Timer Overflow Interrupt einschalten
TCNT0=0x00; //Zähler-Startwert setzen
outp((1<<CS00), TCCR0); //vorteiler: 1
sei(); //Interrupts einschalten
}
ISR(TIMER0_OVF_vect) /*Interrupt-Routine*/
{
//ebenen-multiplex-frequenz=interrupt-frequenz/(16*3)
//zählt 15-0_15-0
if(zaehler_helligkeit==0) //wenn der durchlauf fertig ist...
{
zaehler_helligkeit=15; //..., dann wieder von vorne beginnen und
if (ebene==2) //wenn alle ebenen dran waren...
{
ebene=0; //..., dannn wieder von vorne beginnen
}
else //wenn noch nichd alle dran waren, dann...
{
ebene++; //...nächste ebene aktivieren
}
}
else
{
zaehler_helligkeit--; //wenn der durchlauf noch nicht fertig ist, dann runterzählen
}
//ebene_? aktivieren, die anderen deaktivieren
portc=(1 << (ebene+1));
portd=0;
for(i=0;i<8;i++) //für jeden led ausgang machen, bis auf den letzten
{
if(led[ebene][i]>zaehler_helligkeit)
{
portd=portd | (1 << i);
}
}
if(led[ebene][8]>zaehler_helligkeit) //letzter led-ausgang auf anderem port (c statt d)
{
portc=portc | 0b00000001;
}
PORTC=portc;
PORTD=portd;
}
int main(void)
{
init(); //init() starten
while (1)
{
//Hier kommt was hin, das immer neue werte in das array schreibt, um die leds zu verändern, um Muster zu erzeugen
PORTB = 0b00000001; //test
_delay_ms(500);
PORTB = 0b00000000; //test
_delay_ms(500);
}
}
ich habe jetzt 2 Probleme:
1. Ich habe zu Testzwecken eine LED an B0, die ich mit der _delay_ms() Funktion blinken lassen will (f=1Hz). In Wirklichkeit dauert das blinken aber ca. 260 Mal länger. Wieso? Kann es daran liegen, dass die _delay_ms() Funktion dauernd vom Interrupt unterbrochen wird, und so nicht weiterkommt? Oder woran kann es sonst noch liegen?
2. Ich will für manche Variablen ein uint8_t statt einem int verwenden, da ein int Speicherverschwendung ist. Wenn ich aber die Variable als uint8_t deklariere, dann wird das uint8_t irgendwie nicht erkannt, dh. nicht blau gefärbt, wie z.B. int. Wieso nicht?
Und gibt es vllt. einen Datentyp mit nur 4bit? dann könnte ich noch mehr Speicher sparen...
ich hoffe, ihr könnt mir helfen.
MfG