Ok,
dank dem Stichwort von Netzman (danke nochmal, das war genau das Richtige!) habe ich jetzt etwas mit dem Bresenham gebastelt. Den Algorithmus hab ich von hier http://de.wikipedia.org/wiki/Bresenham-Algorithmus abgeguckt:
Allerdings fürchte ich, dass mein Compiler (AVR Studio 4) da irgendwie den Großteil wegoptimiert (-Os eingestellt), denn dieses Programm kann doch unmöglich nur 526 Bytes (nur 6,4% von ATmegaCode:/************************************************************************ * Fräsensoftware 1.0 * * Autor: Jacob Seibert * * Datum: 22.03.2010 * * IDE: AVR Studio 4.16 * * * * Mit Bresenham-Algorithmus (abgeleitet von Wikipedia) * *************************************************************************/ #include <avr/io.h> #define F_CPU 1000000UL /* Quarz mit 1 MHz (intern)*/ #include <util/delay.h> /*Define-Teil*/ #define _FULLSTEPMODUS 1 #define _ENABLED 1 #define _WAIT_MS 3 #define _X_MOTOR 1 #define _Y_MOTOR 2 #define _Z_MOTOR 0 int akt_x = 1000, akt_y = 1000;/*aktuelle Koordinaten*/ /*Funktion zur Generation eines Schrittes. Parameter: Motor und Richtung*/ void step (uint8_t motor, uint8_t direction) { switch(motor)/*Motor wählen*/ { case _Z_MOTOR: if(direction == 1)/*Richtung wählen*/ { PORTC |= (1<<PC1); } else { PORTC &= ~(1<<PC1); } PORTC &= ~(1<<PC0); _delay_ms(_WAIT_MS); PORTC |= (1<<PC0); break; case _X_MOTOR: if(direction == 1)/*Richtung wählen*/ { PORTB |= (1<<PB1); } else { PORTB &= ~(1<<PB1); } PORTB &= ~(1<<PB0); _delay_ms(_WAIT_MS); PORTB |= (1<<PB0); break; case _Y_MOTOR: if(direction == 1)/*Richtung wählen*/ { PORTB |= (1<<PB4); } else { PORTB &= ~(1<<PB4); } PORTB &= ~(1<<PB3); _delay_ms(_WAIT_MS); PORTB |= (1<<PB3); } }; /*Signum (Mathematik)*/ int sgn (int x) { return (x > 0) ? 1 : (x < 0) ? -1 : 0; }; /*-------------------------------------------------------------- * Bresenham-Algorithmus: Linien auf Raster zeichnen * * Eingabeparameter: * int xstart, ystart = Koordinaten des Startpunkts * int xend, yend = Koordinaten des Endpunkts * * Ausgabe: * void step() *--------------------------------------------------------------- */ void abs_koo (uint16_t xstart, uint16_t ystart, uint16_t xend, uint16_t yend) { int x, y, t, dx, dy, incx, incy, pdx, pdy, ddx, ddy, es, el, err; /* Entfernung in beiden Dimensionen berechnen */ dx = xend - xstart; dy = yend - ystart; /* Vorzeichen des Inkrements bestimmen */ incx = sgn(dx); incy = sgn(dy); if(dx<0) { dx = -dx; } if(dy<0) { dy = -dy; } /* feststellen, welche Entfernung größer ist */ if (dx>dy) { /* x ist schnelle Richtung */ pdx=incx; pdy=0; /* pd. ist Parallelschritt */ ddx=incx; ddy=incy; /* dd. ist Diagonalschritt */ es =dy; el =dx; /* Fehlerschritte schnell, langsam */ } else { /* y ist schnelle Richtung */ pdx=0; pdy=incy; /* pd. ist Parallelschritt */ ddx=incx; ddy=incy; /* dd. ist Diagonalschritt */ es =dx; el =dy; /* Fehlerschritte schnell, langsam */ } /* Initialisierungen vor Schleifenbeginn */ x = xstart; y = ystart; err = el/2; /* Pixel berechnen */ for(t=0; t<el; ++t) /* t zaehlt die Pixel, el ist auch Anzahl */ { /* Aktualisierung Fehlerterm */ err -= es; if(err<0) { /* Fehlerterm wieder positiv (>=0) machen */ err += el; /* Schritt in langsame Richtung, Diagonalschritt */ x += ddx; y += ddy; if (xend>xstart)/*X-Richtung ist positiv*/ { step(_X_MOTOR, 1); } else/*Y_Richtung ist negativ*/ { step(_X_MOTOR, 0); } if(yend>ystart)/*Y_Richtung ist positiv*/ { step(_Y_MOTOR, 1); } else/*Y_Richtung ist negativ*/ { step(_Y_MOTOR, 0); } } else { /* Schritt in schnelle Richtung, Parallelschritt */ x += pdx; y += pdy; if(dx>dy)/*X ist schnelle Richtung*/ { if (xend>xstart)/*X-Richtung ist positiv*/ { step(_X_MOTOR, 1); } else/*Y_Richtung ist negativ*/ { step(_X_MOTOR, 0); } } else/*Y ist schnelle Richtung*/ { if(yend>ystart)/*Y_Richtung ist positiv*/ { step(_Y_MOTOR, 1); } else/*Y_Richtung ist negativ*/ { step(_Y_MOTOR, 0); } } } } }; int main (void) { /*Initialisierungen*/ DDRC |= (1<<PC1) | (1<<PC2) | (1<<PC0); /*1 - EN/CW-CCW/CLK*/ DDRD |= (1<<PD7); /*HALF/FULL*/ DDRB |= (1<<PB0) | (1<<PB1) | (1<<PB2) | (1<<PB3) | (1<<PB4) | (1<<PB5);/*2/3 - EN/CW-CCW/CLK*/ if(_FULLSTEPMODUS == 1) { PORTD &= ~(1<<PD7); /*FULLstep-Modus*/ } else { PORTD |= (1<<PD7); /*HALFstep-Modus*/ } if(_ENABLED == 1) { PORTC |= (1<<PC2); /*1 - EN set*/ PORTB |= (1<<PB2) | (1<<PB5); /*2/3 - EN set*/ } else { PORTC &= ~(1<<PC2); /*1 - EN clear*/ PORTB &= ~((1<<PB2) | (1<<PB5)); /*2/3 - EN clear*/ } /*Main-Teil*/ abs_koo(akt_x, akt_y, 2000, 2000); }groß sein!
Kann jemand etwas entdecken, warum das wegoptimiert wird?







Zitieren
Lesezeichen