PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Lauflicht mit timer ... vereinfachen



klucky
05.11.2004, 18:23
Ich hab mal nen Lauflicht mit Timer geschrieben und dachte mit jetzt dass muss doch auch kürzer gehen ... hier erstmal das orginale Programm:




#include <avr/io.h>
#include <inttypes.h>
#include <avr/interrupt.h>
#include <avr/signal.h>

typedef unsigned char BYTE;
typedef unsigned short WORD;

volatile BYTE byte_timer;

void timer_init(void)
{
/*Output Compare Match Interupt Enable (Initialwert des Bits ist 0)
Wenn dieses Bit gesetzt ist wird beim erreichen des Vergleichswertes ein Interupt ausgelöst.*/
TIMSK|=(1<<OCIE1A);

/*Output Compare Register beschreiben*/
cli();
OCR1A=7812.5;

/*Timer Datenregister zurrücksetzen*/
TCNT1=0;
byte_timer=0;
sei();

/*Clear Timer on Compare Match (Initialwert des Bits ist 0)
Wenn dieses Bit gesetzt ist wird nach Übereinstimmung des Datenregisters mit dem
Vergleichswert das Datenregister auf 0 gesetzt.

Clock Select Bits (Intitialwerte der Bits sind alle 0)
Diese 3 Bits bestimmen die Quelle für den Timer
CS10(Bit 0) CS11(Bit 1) CS12(Bit 2) Aktion
0 0 0 Timer wird angehalten
1 0 0 CPU-Takt
0 1 0 CPU-Takt/8
1 1 0 CPU-Takt/64
0 0 1 CPU-Takt/256
1 0 1 CPU-Takt/1024
0 1 1 Externer Pin T0, fallende Flanke
1 1 1 Externer Pin T0, steigende Flanke*/
TCCR1B|=(1<<CS10)|(1<<CS12)|(1<<WGM12);
}

SIGNAL(SIG_OUTPUT_COMPARE1A)
{
/*Timer anhalten*/
TCCR1B&=~((1<<CS10)|(1<<CS12));
byte_timer=1;
}

int main(void)
{
/*Alle LEDs als Ausgänge*/

DDRA=0xFF;
DDRB=0xFF;
DDRC=0xFF;
DDRD=0xFF;
DDRE=0xFF;
DDRF=0xFF;
DDRG=0xFF;

PORTA=0x0;
PORTB=0x0;
PORTC=0x0;
PORTD=0x0;
PORTE=0x0;
PORTF=0x0;
PORTG=0x0;

while(1)
{
timer_init();
while(byte_timer==0){}
cli();
PORTG=0x0;
PORTA|=(1<<DDA0);

timer_init();
while(byte_timer==0){}
cli();
PORTA&=~(1<<DDA0);
PORTA|=(1<<DDA1);

timer_init();
while(byte_timer==0){}
cli();
PORTA&=~(1<<DDA1);
PORTA|=(1<<DDA2);

timer_init();
while(byte_timer==0){}
cli();
PORTA&=~(1<<DDA2);
PORTA|=(1<<DDA3);

timer_init();
while(byte_timer==0){}
cli();
PORTA&=~(1<<DDA3);
PORTA|=(1<<DDA4);

timer_init();
while(byte_timer==0){}
cli();
PORTA&=~(1<<DDA4);
PORTA|=(1<<DDA5);

timer_init();
while(byte_timer==0){}
cli();
PORTA&=~(1<<DDA5);
PORTA|=(1<<DDA6);

timer_init();
while(byte_timer==0){}
cli();
PORTA&=~(1<<DDA6);
PORTA|=(1<<DDA7);

timer_init();
while(byte_timer==0){}
cli();
PORTA&=~(1<<DDA7);
PORTB|=(1<<DDB0);

timer_init();
while(byte_timer==0){}
cli();
PORTB&=~(1<<DDB0);
PORTB|=(1<<DDB1);

timer_init();
while(byte_timer==0){}
cli();
PORTB&=~(1<<DDB1);
PORTB|=(1<<DDB2);

timer_init();
while(byte_timer==0){}
cli();
PORTB&=~(1<<DDB2);
PORTB|=(1<<DDB3);

timer_init();
while(byte_timer==0){}
cli();
PORTB&=~(1<<DDB3);
PORTB|=(1<<DDB4);

timer_init();
while(byte_timer==0){}
cli();
PORTB&=~(1<<DDB4);
PORTB|=(1<<DDB5);

timer_init();
while(byte_timer==0){}
cli();
PORTB&=~(1<<DDB5);
PORTB|=(1<<DDB6);

timer_init();
while(byte_timer==0){}
cli();
PORTB&=~(1<<DDB6);
PORTB|=(1<<DDB7);

timer_init();
while(byte_timer==0){}
cli();
PORTB&=~(1<<DDB7);
PORTC|=(1<<DDC0);

timer_init();
while(byte_timer==0){}
cli();
PORTC&=~(1<<DDC0);
PORTC|=(1<<DDC1);

timer_init();
while(byte_timer==0){}
cli();
PORTC&=~(1<<DDC1);
PORTC|=(1<<DDC2);

timer_init();
while(byte_timer==0){}
cli();
PORTC&=~(1<<DDC2);
PORTC|=(1<<DDC3);

timer_init();
while(byte_timer==0){}
cli();
PORTC&=~(1<<DDC3);
PORTC|=(1<<DDC4);

timer_init();
while(byte_timer==0){}
cli();
PORTC&=~(1<<DDC4);
PORTC|=(1<<DDC5);

timer_init();
while(byte_timer==0){}
cli();
PORTC&=~(1<<DDC5);
PORTC|=(1<<DDC6);

timer_init();
while(byte_timer==0){}
cli();
PORTC&=~(1<<DDC6);
PORTC|=(1<<DDC7);

timer_init();
while(byte_timer==0){}
cli();
PORTC=0x0;
PORTD=0x1;

timer_init();
while(byte_timer==0){}
cli();
PORTD=0x2;

timer_init();
while(byte_timer==0){}
cli();
PORTD=0x4;

timer_init();
while(byte_timer==0){}
cli();
PORTD=0x8;

timer_init();
while(byte_timer==0){}
cli();
PORTD=0x10;

timer_init();
while(byte_timer==0){}
cli();
PORTD=0x20;

timer_init();
while(byte_timer==0){}
cli();
PORTD=0x40;

timer_init();
while(byte_timer==0){}
cli();
PORTD=0x80;

timer_init();
while(byte_timer==0){}
cli();
PORTD=0x0;
PORTE=0x1;

timer_init();
while(byte_timer==0){}
cli();
PORTE=0x2;

timer_init();
while(byte_timer==0){}
cli();
PORTE=0x4;

timer_init();
while(byte_timer==0){}
cli();
PORTE=0x8;

timer_init();
while(byte_timer==0){}
cli();
PORTE=0x10;

timer_init();
while(byte_timer==0){}
cli();
PORTE=0x20;

timer_init();
while(byte_timer==0){}
cli();
PORTE=0x40;

timer_init();
while(byte_timer==0){}
cli();
PORTE=0x80;

timer_init();
while(byte_timer==0){}
cli();
PORTE=0x0;
PORTF=0x1;

timer_init();
while(byte_timer==0){}
cli();
PORTF=0x2;

timer_init();
while(byte_timer==0){}
cli();
PORTF=0x4;

timer_init();
while(byte_timer==0){}
cli();
PORTF=0x8;

timer_init();
while(byte_timer==0){}
cli();
PORTF=0x10;

timer_init();
while(byte_timer==0){}
cli();
PORTF=0x20;

timer_init();
while(byte_timer==0){}
cli();
PORTF=0x40;

timer_init();
while(byte_timer==0){}
cli();
PORTF=0x80;

timer_init();
while(byte_timer==0){}
cli();
PORTF=0x0;
PORTG=0x1;

timer_init();
while(byte_timer==0){}
cli();
PORTG=0x2;

timer_init();
while(byte_timer==0){}
cli();
PORTG=0x4;

timer_init();
while(byte_timer==0){}
cli();
PORTG=0x8;

timer_init();
while(byte_timer==0){}
cli();
PORTG=0x10;
}

}


Naja jetzt habe ich das ganze mit einer Schleife und einem Array vereinfacht ... aber jetzt geht garnix mehr und ich nix wissen warum ... hier der neue Code:



#include <avr/io.h>
#include <inttypes.h>
#include <avr/interrupt.h>
#include <avr/signal.h>

typedef unsigned char BYTE;
typedef unsigned short WORD;

volatile BYTE byte_timer;
volatile WORD byte_ports[7][9];
volatile int a;
volatile int b;

void timer_init(void)
{
/*Output Compare Match Interupt Enable (Initialwert des Bits ist 0)
Wenn dieses Bit gesetzt ist wird beim erreichen des Vergleichswertes ein Interupt ausgelöst.*/
TIMSK|=(1<<OCIE1A);

/*Output Compare Register beschreiben*/
cli();
OCR1A=7812.5;

/*Timer Datenregister zurrücksetzen*/
TCNT1=0;
byte_timer=0;
sei();

/*Clear Timer on Compare Match (Initialwert des Bits ist 0)
Wenn dieses Bit gesetzt ist wird nach Übereinstimmung des Datenregisters mit dem
Vergleichswert das Datenregister auf 0 gesetzt.

Clock Select Bits (Intitialwerte der Bits sind alle 0)
Diese 3 Bits bestimmen die Quelle für den Timer
CS10(Bit 0) CS11(Bit 1) CS12(Bit 2) Aktion
0 0 0 Timer wird angehalten
1 0 0 CPU-Takt
0 1 0 CPU-Takt/8
1 1 0 CPU-Takt/64
0 0 1 CPU-Takt/256
1 0 1 CPU-Takt/1024
0 1 1 Externer Pin T0, fallende Flanke
1 1 1 Externer Pin T0, steigende Flanke*/
TCCR1B|=(1<<CS10)|(1<<CS12)|(1<<WGM12);
}

SIGNAL(SIG_OUTPUT_COMPARE1A)
{
/*Timer anhalten*/
TCCR1B&=~((1<<CS10)|(1<<CS12));
byte_timer=1;
}

int main(void)
{
/*Alle LEDs als Ausgänge*/

DDRA=0xFF;
DDRB=0xFF;
DDRC=0xFF;
DDRD=0xFF;
DDRE=0xFF;
DDRF=0xFF;
DDRG=0xFF;

PORTA=0x0;
PORTB=0x0;
PORTC=0x0;
PORTD=0x0;
PORTE=0x0;
PORTF=0x0;
PORTG=0x0;

byte_ports[0][0]=PORTA;
byte_ports[0][1]=DDA0;
byte_ports[0][2]=DDA1;
byte_ports[0][3]=DDA2;
byte_ports[0][4]=DDA3;
byte_ports[0][5]=DDA4;
byte_ports[0][6]=DDA5;
byte_ports[0][7]=DDA6;
byte_ports[0][8]=DDA7;
byte_ports[1][0]=PORTB;
byte_ports[1][1]=DDB0;
byte_ports[1][2]=DDB1;
byte_ports[1][3]=DDB2;
byte_ports[1][4]=DDB3;
byte_ports[1][5]=DDB4;
byte_ports[1][6]=DDB5;
byte_ports[1][7]=DDB6;
byte_ports[1][8]=DDB7;
byte_ports[2][0]=PORTC;
byte_ports[2][1]=DDC0;
byte_ports[2][2]=DDC1;
byte_ports[2][3]=DDC2;
byte_ports[2][4]=DDC3;
byte_ports[2][5]=DDC4;
byte_ports[2][6]=DDC5;
byte_ports[2][7]=DDC6;
byte_ports[2][8]=DDC7;
byte_ports[3][0]=PORTD;
byte_ports[3][1]=DDD0;
byte_ports[3][2]=DDD1;
byte_ports[3][3]=DDD2;
byte_ports[3][4]=DDD3;
byte_ports[3][5]=DDD4;
byte_ports[3][6]=DDD5;
byte_ports[3][7]=DDD6;
byte_ports[3][8]=DDD7;
byte_ports[4][0]=PORTE;
byte_ports[4][1]=DDE0;
byte_ports[4][2]=DDE1;
byte_ports[4][3]=DDE2;
byte_ports[4][4]=DDE3;
byte_ports[4][5]=DDE4;
byte_ports[4][6]=DDE5;
byte_ports[4][7]=DDE6;
byte_ports[4][8]=DDE7;
byte_ports[5][0]=PORTF;
byte_ports[5][1]=DDF0;
byte_ports[5][2]=DDF1;
byte_ports[5][3]=DDF2;
byte_ports[5][4]=DDF3;
byte_ports[5][5]=DDF4;
byte_ports[5][6]=DDF5;
byte_ports[5][7]=DDF6;
byte_ports[5][8]=DDF7;
byte_ports[6][0]=PORTG;
byte_ports[6][1]=DDG0;
byte_ports[6][2]=DDG1;
byte_ports[6][3]=DDG2;
byte_ports[6][4]=DDG3;
byte_ports[6][5]=DDG4;
byte_ports[6][6]=0;
byte_ports[6][7]=0;
byte_ports[6][8]=0;

while(1)
{
for(a=0;a<=6;a++)
{
for(b=1;b<=7;b++)
{
if(b>1)
{
byte_ports[a][0]&=~(1<<byte_ports[a][b-1]);
if(byte_ports[a][b]==0)
{
break;
}
timer_init();
while(byte_timer==0){}
cli();
byte_ports[a][0]|=(1<<byte_ports[a][b]);
}
else if(b==1)
{
byte_ports[a-1][0]&=~(1<<byte_ports[a-1][8]);
if(byte_ports[a][b]==0)
{
break;
}
timer_init();
while(byte_timer==0){}
cli();
byte_ports[a][0]|=(1<<byte_ports[a][b]);
}
}
}
}

}


Kann mir irgendwer von euch sagen warum das so nicht funktioniert? Es sind keine einfachen Syntax fehler drin, das Programm lässt sich also ohne Fehlermeldungen kompilieren ... also muss irgendwo ein funktioneller Fehler sein! Hoffe ihr könnt mir beim finden des Fehlers oder der Fehler helfen! Danke schonmal im vorraus!

bluebrother
07.11.2004, 11:21
Hi,

du scheinst da ja (nachdem ich das mal kurz überflogen habe) im Original eine riesige Schleife zu haben. Mein Gedanke dazu:
- nimm einen Timer und lass den beim Überlauf einen Interrupt auslösen
- der IRQ-Handler setzt dann einen neuen Startwert für die gewünschte Zeit für den Überlauf
- im IRQ: lies den Status von PINA bis PINC. Dann schauen wo ein Bit gesetzt ist (also PINx > 0). Mit dem Wert einen shift nach links (oder rechts, falls du die andere Richtung willst) machen. Bei Überlauf in den nächsten PORTx reinschieben. Fertig.

so mal als Gedanke. In Code hab ich das aber nicht formuliert ;-)

Viel Erfolg,
bluebrother