This is the second attempt to write the AVR code based on a technique based on the autonomous vehicle project described at
http://instruct1.cit.cornell.edu/courses/ee476/FinalProjects/s1999/gurnee/index.htm
Code
/*---------------------------------------------------------------------------------13.c
$Revision: 1.2 $
Author: Donald Delmar Davis
Date: 08feb03
Purpose: port of sketchy to avrgcc.
Credits: AVR-GCC test program #4 (Author: Volker Oth) / Autonomous car program.
*/
//#if defined (__ATmega163__)
//#define __AVR_ATmega163__ 1
#define __AVR_ATmega8__ 1
//#endif
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>
#define ETRIM -200
#define STRIM -100
#define F_CPU 8000000 /* 8Mhz */
#define PULSESPACE 0xFFFF - 20000
#define PULSECENTER (1900 + PULSESPACE)
#define SDLY(DEG) (1000+(11*(DEG))+PULSESPACE)
#define EDLY(DEG) (1000+(10*(DEG))+PULSESPACE)
#ifdef __AVR_AT_Mega8__
/* switch defines for dt107 */
#define SERVOPORTPINS PORTB
#define SERVOPORTDDR DDRB
#define E_SERVO PINB1
#define S_SERVO PINB2
#else
/* switch defines for sim100 */
#define SERVOPORTPINS PORTB
#define SERVOPORTDDR DDRB
#define E_SERVO PINB1
#define S_SERVO PINB0
#endif
//#define UART_BAUD_RATE 9600 /* 9600 baud */
//#define UART_BAUD_SELECT (F_CPU/(UART_BAUD_RATE*16l)-1)
typedef unsigned char u08;
typedef char s08;
typedef unsigned short u16;
typedef short s16;
typedef struct _todolist {
u16 shoulder;
u16 elbow;
u16 duration;
struct _todolist *next;
} todolist;
/* uart globals */
static volatile u08 *uart_data_ptr;
static volatile u08 uart_counter;
unsigned char led;
static volatile u16 sservo,eservo;
static volatile u16 duration;
static volatile todolist stufftodo[]={
{ SDLY(-50), EDLY(0), 2500, (todolist *) &(stufftodo[4]) }, /* when right front hits back right tire */
{ SDLY(0), EDLY(-50), 2500, (todolist *) &(stufftodo[4]) }, /* when left front hits back left tire */
{ SDLY(50), EDLY(0), 2500, (todolist *) &(stufftodo[4]) }, /* when right rear hits fwd right tire */
{ SDLY(0), EDLY(50), 2500, (todolist *) &(stufftodo[4]) }, /* when left rear hits fwd left tire */
{ SDLY(00),EDLY(45),800, (todolist *) &(stufftodo[5]) },
{ SDLY(10),EDLY(45),100, (todolist *) &(stufftodo[6]) },
{ SDLY(20),EDLY(45),100, (todolist *) &(stufftodo[7]) },
{ SDLY(30),EDLY(45),100, (todolist *) &(stufftodo[8]) },
{ SDLY(40),EDLY(45),100, (todolist *) &(stufftodo[9]) },
{ SDLY(50),EDLY(45),100, (todolist *) &(stufftodo[10]) },
{ SDLY(60),EDLY(45),100, (todolist *) &(stufftodo[11]) },
{ SDLY(70),EDLY(45),100, (todolist *) &(stufftodo[12]) },
{ SDLY(80),EDLY(45),100, (todolist *) &(stufftodo[13]) },
{ SDLY(90),EDLY(45),800, (todolist *) &(stufftodo[14]) },
{ SDLY(90),EDLY(50),100, (todolist *) &(stufftodo[15]) },
{ SDLY(90),EDLY(40),100, (todolist *) &(stufftodo[16]) },
{ SDLY(90),EDLY(45),800, (todolist *) &(stufftodo[17]) },
{ SDLY(80),EDLY(45),100, (todolist *) &(stufftodo[18]) },
{ SDLY(70),EDLY(45),100, (todolist *) &(stufftodo[19]) },
{ SDLY(60),EDLY(45),100, (todolist *) &(stufftodo[20]) },
{ SDLY(50),EDLY(45),100, (todolist *) &(stufftodo[21]) },
{ SDLY(40),EDLY(45),100, (todolist *) &(stufftodo[22]) },
{ SDLY(30),EDLY(45),100, (todolist *) &(stufftodo[23]) },
{ SDLY(20),EDLY(45),100, (todolist *) &(stufftodo[24]) },
{ SDLY(10),EDLY(45),100, (todolist *) &(stufftodo[25]) },
{ SDLY(00),EDLY(45),800, (todolist *) &(stufftodo[26]) },
{ SDLY(00),EDLY(50),100, (todolist *) &(stufftodo[27]) },
{ SDLY(00),EDLY(40),100, (todolist *) &(stufftodo[4]) }
};
#define RFSWITCHTODO ( (todolist *) &(stufftodo[0]) )
#define LFSWITCHTODO ( (todolist *) &(stufftodo[1]) )
#define RRSWITCHTODO ( (todolist *) &(stufftodo[2]) )
#define LRSWITCHTODO ( (todolist *) &(stufftodo[3]) )
static volatile todolist *thingtodo=&(stufftodo[4]);
/*;**********************Timer 1 overflow**************
*;brings two servo lines hi, reloads servo position values
*;
*;_______|-|____
*; /
*; |
*; overflow here
*/
SIGNAL(SIG_OVERFLOW1)
{
sbi(SERVOPORTPINS,E_SERVO);
sbi(SERVOPORTPINS,S_SERVO);
outw(TCNT1,PULSESPACE);
outw(OCR1A,eservo);
outw(OCR1B,sservo);
}
SIGNAL(SIG_OUTPUT_COMPARE1A)
{
cbi(SERVOPORTPINS,E_SERVO);
}
SIGNAL(SIG_OUTPUT_COMPARE1B)
{
cbi(SERVOPORTPINS,S_SERVO);
}
SIGNAL(SIG_OVERFLOW2)
{
outb(TCNT2,0); /*(i dunno if this is necissary )*/
if ((--duration)<=0) {
thingtodo=thingtodo->next;
} else {
return;
}
sservo=thingtodo->shoulder+STRIM;
eservo=thingtodo->elbow+ETRIM;
duration=thingtodo->duration;
}
void main(void)
{
outb(TIMSK,(_BV(TOIE2)|_BV(TOIE1)|_BV(OCIE1A)|_BV(OCIE1B))); /* enable TCNT overflow */
outw(TCNT1,0xFF00); // idea is to start with an interupt (not sure if this wil work).
outb(TCCR1A,0);
outb(TCCR1B,2); // ck/8
duration=10;
cbi(ASSR,AS2);
outb(TCNT2,0x00);
outb(TCCR2,3); // ck/1024
eservo=PULSECENTER+ETRIM;
sservo=PULSECENTER+STRIM;
outb(SERVOPORTDDR,0xff); /* servoport = output */
outb(SERVOPORTPINS,0x00); /* switch outputs off */
sei(); /* enable interrupts */
}