// Mega1284 version
#define F_CPU 16000000UL
#include
#include
#include
#include
#include
// serial communication library
//#include "uart.h"
#define countMS 62 //ticks/mSec
//timeout values for each task
#define t1 28 //6ms between triggers
#define t2 12 //1ms between echo detection
#define t4 8 //4ms for motor on/off.
#define begin {
#define end }
// eeprom defines addressee
#define eeprom_true 0
#define eeprom_data 1
void motor_on_off(void);
void initialize(void); //all the usual mcu stuff
void send_trigger(void);
volatile char count;
volatile unsigned int time, time1, time3; //timeout counters
volatile unsigned int left, center, right; //Use this to start the millisecond counters.
volatile long int width_left, width_center, width_right;
volatile unsigned long int left_start, left_end;
volatile unsigned int center_start, center_end;
volatile unsigned int right_start, right_end;
unsigned int thres = 30;
// UART file descriptor
// putchar and getchar are in uart.c
//FILE uart_str = FDEV_SETUP_STREAM(uart_putchar, uart_getchar, _FDEV_SETUP_RW);
//*****************************************************************
// --- external interrupt ISR ------------------------
ISR (INT0_vect) {
if (!(EICRA & 0x1)) //So if its set to falling edge and you're in the ISR get width.
{
width_left = TCNT1-left_start;
}
if (EICRA & 0x1)
{
left_start = TCNT1;
}
//toggle the edge somehow.
EICRA ^= (1 <0) --time1;
if (time3>0) --time3;
end
//**********************************************************
//Entry point and task scheduler loop
int main(void)
begin
initialize();
//main task scheduler loop
while(1)
begin
send_trigger();
motor_on_off();
end
end
//**********************************************************
//Turn on UltraSonic trigger
void send_trigger(void) // runs every 6 ms
begin
//TCNT1 = 0;
PORTC = 0x1;
time3=1;
while (time3 != 0) {}
PORTC = 0x00;
time3=12;
while (time3 != 0) {}
TCNT1 = 0;
PORTC = 0x2;
time3=1;
while (time3 != 0) {}
PORTC = 0x00;
time3=8;
while (time3 != 0) {}
TCNT1 = 0;
PORTC = 0x4;
time3=1;
while (time3 != 0) {}
PORTC = 0x00;
time3=12;
end
//**********************************************************
//Task sets the H-Bridge control bits, which
//should be set everytime accordingly from either of the ISRs
void motor_on_off(void)
begin
if (width_left < 40 && width_left > 0)
{
PORTB = 1;
}
else if (width_right < 40 && width_right > 0)
{
PORTB = 2;
}
else if (width_center < 35 && width_center > 0)
{
PORTB = 0;
}
//else PORTB =0;
end
//**********************************************************
//Set it all up
void initialize(void)
begin
//PWM stuff
//set up Timer 0 PWM stuff
//set up INT0
EIMSK |= 1<
Ancilliary Code Used
UART.C
/*
* ----------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42):
* wrote this file. As long as you retain this notice you
* can do whatever you want with this stuff. If we meet some day, and you think
* this stuff is worth it, you can buy me a beer in return. Joerg Wunsch
* ----------------------------------------------------------------------------
*
* Stdio demo, UART implementation
*
* $Id: uart.c,v 1.1 2005/12/28 21:38:59 joerg_wunsch Exp $
*
* Mod for mega644 BRL Jan2009
*/
/* CPU frequency */
#define F_CPU 16000000UL
/* UART baud rate */
#define UART_BAUD 9600
#include
#include
#include
#include "uart.h"
/*
* Initialize the UART to 9600 Bd, tx/rx, 8N1.
*/
void
uart_init(void)
{
#if F_CPU < 2000000UL && defined(U2X)
UCSR0A = _BV(U2X); /* improve baud rate error by using 2x clk */
UBRR0L = (F_CPU / (8UL * UART_BAUD)) - 1;
#else
UBRR0L = (F_CPU / (16UL * UART_BAUD)) - 1;
#endif
UCSR0B = _BV(TXEN0) | _BV(RXEN0); /* tx/rx enable */
}
/*
* Send character c down the UART Tx, wait until tx holding register
* is empty.
*/
int
uart_putchar(char c, FILE *stream)
{
if (c == '\a')
{
fputs("*ring*\n", stderr);
return 0;
}
if (c == '\n')
uart_putchar('\r', stream);
loop_until_bit_is_set(UCSR0A, UDRE0);
UDR0 = c;
return 0;
}
/*
* Receive a character from the UART Rx.
*
* This features a simple line-editor that allows to delete and
* re-edit the characters entered, until either CR or NL is entered.
* Printable characters entered will be echoed using uart_putchar().
*
* Editing characters:
*
* . \b (BS) or \177 (DEL) delete the previous character
* . ^u kills the entire input buffer
* . ^w deletes the previous word
* . ^r sends a CR, and then reprints the buffer
* . \t will be replaced by a single space
*
* All other control characters will be ignored.
*
* The internal line buffer is RX_BUFSIZE (80) characters long, which
* includes the terminating \n (but no terminating \0). If the buffer
* is full (i. e., at RX_BUFSIZE-1 characters in order to keep space for
* the trailing \n), any further input attempts will send a \a to
* uart_putchar() (BEL character), although line editing is still
* allowed.
*
* Input errors while talking to the UART will cause an immediate
* return of -1 (error indication). Notably, this will be caused by a
* framing error (e. g. serial line "break" condition), by an input
* overrun, and by a parity error (if parity was enabled and automatic
* parity recognition is supported by hardware).
*
* Successive calls to uart_getchar() will be satisfied from the
* internal buffer until that buffer is emptied again.
*/
int
uart_getchar(FILE *stream)
{
uint8_t c;
char *cp, *cp2;
static char b[RX_BUFSIZE];
static char *rxp;
if (rxp == 0)
for (cp = b;;)
{
loop_until_bit_is_set(UCSR0A, RXC0);
if (UCSR0A & _BV(FE0))
return _FDEV_EOF;
if (UCSR0A & _BV(DOR0))
return _FDEV_ERR;
c = UDR0;
/* behaviour similar to Unix stty ICRNL */
if (c == '\r')
c = '\n';
if (c == '\n')
{
*cp = c;
uart_putchar(c, stream);
rxp = b;
break;
}
else if (c == '\t')
c = ' ';
if ((c >= (uint8_t)' ' && c <= (uint8_t)'\x7e') ||
c >= (uint8_t)'\xa0')
{
if (cp == b + RX_BUFSIZE - 1)
uart_putchar('\a', stream);
else
{
*cp++ = c;
uart_putchar(c, stream);
}
continue;
}
switch (c)
{
case 'c' & 0x1f:
return -1;
case '\b':
case '\x7f':
if (cp > b)
{
uart_putchar('\b', stream);
uart_putchar(' ', stream);
uart_putchar('\b', stream);
cp--;
}
break;
case 'r' & 0x1f:
uart_putchar('\r', stream);
for (cp2 = b; cp2 < cp; cp2++)
uart_putchar(*cp2, stream);
break;
case 'u' & 0x1f:
while (cp > b)
{
uart_putchar('\b', stream);
uart_putchar(' ', stream);
uart_putchar('\b', stream);
cp--;
}
break;
case 'w' & 0x1f:
while (cp > b && cp[-1] != ' ')
{
uart_putchar('\b', stream);
uart_putchar(' ', stream);
uart_putchar('\b', stream);
cp--;
}
break;
}
}
c = *rxp++;
if (c == '\n')
rxp = 0;
return c;
}
UART.H
/*
* ----------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42):
* wrote this file. As long as you retain this notice you
* can do whatever you want with this stuff. If we meet some day, and you think
* this stuff is worth it, you can buy me a beer in return. Joerg Wunsch
* ----------------------------------------------------------------------------
*
* Stdio demo, UART declarations
*
* $Id: uart.h,v 1.1 2005/12/28 21:38:59 joerg_wunsch Exp $
*/
/*
* Perform UART startup initialization.
*/
void uart_init(void);
/*
* Send one character to the UART.
*/
int uart_putchar(char c, FILE *stream);
/*
* Size of internal line buffer used by uart_getchar().
*/
#define RX_BUFSIZE 80
/*
* Receive one character from the UART. The actual reception is
* line-buffered, and one character is returned from the buffer at
* each invokation.
*/
int uart_getchar(FILE *stream);