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:
Code:
/************************************************************************
* 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);
}
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 ATmega
groß sein!
Kann jemand etwas entdecken, warum das wegoptimiert wird?
Lesezeichen