Code:
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <stdlib.h>
#include "uart.h"
#include <avr/interrupt.h>
#include <stdint.h>
#include <avr/pgmspace.h>
#define UART_BAUD_RATE 9600
volatile uint16_t motor1=0;
volatile uint16_t motor2=0;
//absolute direction in degree (-180 to 180, -90 to 90)
volatile int16_t xpos = 0;
volatile int16_t ypos = 0;
#define speed 400
#define deframp 200
#define rf 2
const unsigned char halfstep[8]={5,1,9,8,10,2,6,4};
void init()
{
DDRA = 0b00000011;
DDRB = 0b11111111;
DDRD = 0b00000100;
PORTA=0b00000000;
uart_init( UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU) );
sei();
//Bluetooth module config
PORTD |= (1<<2);
uart_puts_P("AT+NAME=MiniPanoBot_BT\r\n");
uart_puts_P("AT+PSWD=0815\r\n");
uart_puts_P("AT+UART=9600,0,0\r\n");
uart_puts_P("AT+RESET\r\n");
PORTD &= ~(1<<2);
}
void _vdelay_us(int delay)
{
int cnt;
for (cnt=0;cnt<delay;cnt++)
{
_delay_us(1);
}
}
void _vdelay_ms(int delay)
{
int cnt;
for (cnt=0;cnt<delay;cnt++)
{
_delay_ms(1);
}
}
void step_x(int dir)
{
motor1 = motor1 + dir;
PORTB = (halfstep[(motor1 & 7)])| (PORTB & (0b11110000));
_vdelay_us(speed);
}
void step_y(int dir)
{
motor2 = motor2 + dir;
PORTB = (halfstep[(motor2 & 7)]) << 4| (PORTB & (0b00001111));
_vdelay_us(speed);
}
/* signum function */
int sgn(int x){
return (x > 0) ? 1 : (x < 0) ? -1 : 0;
}
void line(int xstart,int ystart,int xend,int yend)
/*--------------------------------------------------------------
* Bresenham-Algorithmus: Linien auf Rastergeräten zeichnen
*
* Eingabeparameter:
* int xstart, ystart = Koordinaten des Startpunkts
* int xend, yend = Koordinaten des Endpunkts
*
* Ausgabe:
* void SetPixel(int x, int y) setze ein Pixel in der Grafik
* (wird in dieser oder aehnlicher Form vorausgesetzt)
*---------------------------------------------------------------
*/
{
int x, y, t, dx, dy, incx, incy, pdx, pdy, ddx, ddy, es, el, err;
int rampe=deframp;
int shortramp=0;
/* 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;
if (el<(rampe*2))
{
shortramp=rampe-(el/2);
rampe= el/2;
}
else
shortramp=0;
PORTA |= ((1<<0)&(1<<1)); //Motortreiber aktivieren
//SetPixel(x,y);
/* 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;
step_x(ddx);
step_y(ddy);
} else
{
/* Schritt in schnelle Richtung, Parallelschritt */
x += pdx;
y += pdy;
step_x(pdx);
step_y(pdy);
}
if (t<=rampe) //start
{
_vdelay_us((rampe-t+shortramp)*rf);
}
if (t>(el-rampe)) //stop
{
_vdelay_us((t-(el-rampe-shortramp))*rf);
}
//SetPixel(x,y);
}
PORTA &= ~((1<<0)&(1<<1));
} /* gbham() */
void moveto(int x,int y)
{
line(xpos,ypos,x,y);
xpos=x;
ypos=y;
}
unsigned char serialin(void)
{
unsigned int c;
c = uart_getc();
while ( c & UART_NO_DATA )
c = uart_getc();
return c;
}
void remote_move()
{
int16_t x,y;
x=serialin()+(serialin()<<8);
y=serialin()+(serialin()<<8);
uart_putc(1);
moveto(x,y);
xpos = x;
ypos = y;
uart_putc(0);
}
void remote(void)
{
unsigned int c;
c = uart_getc();
if ( c & UART_NO_DATA )
{
/*
* no data available from UART
*/
}
else
{
/*
* new data available from UART
* check for Frame or Overrun error
*/
if ( c & UART_FRAME_ERROR )
{
/* Framing Error detected, i.e no stop bit detected */
//uart_puts_P("UART Frame Error: ");
}
if ( c & UART_OVERRUN_ERROR )
{
/*
* Overrun, a character already present in the UART UDR register was
* not read by the interrupt handler before the next character arrived,
* one or more received characters have been dropped
*/
//uart_puts_P("UART Overrun Error: ");
}
if ( c & UART_BUFFER_OVERFLOW )
{
/*
* We are not reading the receive buffer fast enough,
* one or more received character have been dropped
*/
//uart_puts_P("Buffer overflow error: ");
}
//doing commands
switch(c)
{
case 0: //status
uart_putc(0);
break;
case 1: //moveto(x,y)
remote_move();
break;
case 2: //power motors on hold
PORTA = 0b00000011;
uart_putc(0);
break;
case 3: //unpower motors on hold
PORTA = 0b00000000;
uart_putc(0);
break;
case 4: //shoot
PORTA = 0b00000000;
uart_putc(0);
break;
}
}
}
int main(void)
{
init();
while (1)
{
remote();
}
}
Der Compiler sagt :
Lesezeichen