//LAB 7 CODE - Receiver
//Michael Jardin
//Nick Liu
//Monday, 7:30-10:30 Lab
#include <Mega163.h>
//timeout values for each task
#define t1 20
#define max 255
//value that the PWM wave counts up to
#define foward 0x08
//signal for each going in the foward direction
#define idle 128
//PWM value used for engines off
#define off 0x08
//transmission byte indicating hovercraft should be off
//the subroutines
void task1(void);
//Parses receive byte into voltages for motors
void initialize(void);
//sets up the mcu
void gets_int(void);
//nonblocking receive interrupt scheme
//define variables
unsigned char reload;
//timer 0 reload to set 1 mSec
unsigned char time1;
//keeps track of current time of task
unsigned char signal;
//temporary variable that is parsed to correct values for motors
unsigned char r_ready;
//flag for receive done receive interrupt
unsigned char r_char;
//current byte that is received
unsigned char rightD, rightV, leftD, leftV;//variables used to store direction
and voltage of respective motors
//Lookup table to determine correct voltage for
motors
flash float voltages[16]=
{7*(max/14), 6*(max/14), 5*(max/14), 4*(max/14), 3*(max/14),
2*(max/14), (max/14), 0, 7*(max/14), 8*(max/14), 9*(max/14),
10*(max/14), 11*(max/14), 12*(max/14), 13*(max/14),
14*(max/14)};
//**********************************************************
//timer 0 overflow ISR
interrupt [TIM0_OVF] void timer0_overflow(void)
{
TCNT0=reload;
//reload to force 1 mSec overflow
if (time1>0) --time1;
//Decrement the three times if they are not already zero
}
//**********************************************************
//UART character-ready ISR
interrupt [UART_RXC] void uart_rec(void)
{
r_char=UDR;
//get a char
signal=r_char;
UCSRB.7=0;
//stop rec ISR
}
//**********************************************************
//Entry point and task scheduler loop
void main(void)
{
initialize();
while(1)
//main task scheduler loop -- never exits
if (time1==0) task1();
}
//**********************************************************
void task1(void)
{
time1=t1;
PORTB = signal;
//for debugging
if (signal == off){
//when transmitter turns hovercraft off, will constantly send off signal
PORTC.0 = 0x00;
//make sure the hovercraft is off
OCR1A = idle;
//set both motors to idle
OCR1B = idle;
}
else {
PORTC.0 = 0xff;
//make sure hovercraft is on
rightV = (signal & 0x07);
//right voltage magnitude = bits 0-3
rightD = (signal & 0x08);
//right direction = bit 4 (1-foward, 0-reverse)
signal >>= 4;
//shift bits 4-7 right so now bits 0-3
leftV = (signal & 0x07);
//left voltage magnitude = bits 0-3
leftD = (signal & 0x08);
//left direction = bit 4 (1-foward, 0-reverse)
if (rightD == foward)
//if right motor is forward
OCR1A =
voltages[8+rightV]; //read off voltage from 2nd half of table
else
OCR1A =
voltages[rightV]; //else read from first half of table
if (leftD == foward)
//repeat for left engine
OCR1B =
voltages[8+leftV];
else
OCR1B =
voltages[leftV];
}
signal = off;
//signal will go back on only when transmitter is TXing
r_ready=1;
//ready to receive another data byte
if (r_ready ) gets_int();
//start receive interrupt
}
//**********************************************************
// -- non-blocking keyboard check initializes ISR-driven
// receive. This routine merely sets up the ISR, which then
//does all the work of getting a command.
void gets_int(void)
{
r_ready=0;
UCSRB.7=1;
//turn on transmit interrupt
}
//**********************************************************
//Set it all up
void initialize(void)
{
//Set UART communication
UCSRB = 0x10;
UBRR = 255;
//set up the ports
DDRD=0xfc;
// PORT D.0 and D.1 are inputs, rest are outputs
DDRC=0xff;
// PORT C is an ouput (power)
PORTC.0=0x00;
// hovercraft is initally off
//set up timer 0
reload=256-62;
//value for 1 Msec
TCNT0=reload;
//preload timer 1 so that is interrupts after 1 mSec.
TCCR0=3;
//prescalar to 64
TIMSK=1;
//turn on timer 0 overflow ISR
//set up timer 1
TCCR1B = 1;
//disable timer 1
TCNT1 = 0;
//and zero the timer
TCCR1A = 0b10100001;
//page 43 - PWM stuff
OCR1A=idle;
//right motor off
OCR1B=idle;
//left motor off
//init the task timers
time1=t1;
signal = off;
//keep the hovercraft in the off state
r_ready = 1;
//start receiving signal from transmitter
//crank up the ISRs
#asm
sei
#endasm
}