Complete code.

 

/* This is the file for the final project

Author: Greg Larchev */

 

#include <io.h>

#include <interrupt.h>

#include <signal.h>

 

typedef unsigned char u08;

typedef unsigned short u16;

 

#define MAXLEN 75

#define MAXREC  4

 

static volatile short changes1[MAXREC][MAXLEN];

static volatile u08 emitVal = 0x00;

static volatile u08 emitHigh = 0x00;

static volatile int recNum = 1;

static volatile u08 recFull = 0x00;

 

 

void pause30 (void)

{

register u08 counter = 255;

while (counter)

          {

          counter--;

          }

}

 

 

void pause1650 (void)

{

register u08 counter = 70;

while (counter)

          {

          counter--;

          pause30();

          }

}

 

 

void pause6k (void)

{

register u08 counter = 8;

while (counter)

          {

          counter--;

          pause1650();

          }

}

 

 

 

void  lcdCommand (u08 comm)

/* send specifed command to the lcd  */

{

register u08 tmpr1;

 

outp (0, DDRC);                       /* D input */

tmpr1 = inp(PINC);                  /* read values of port D */

tmpr1 &= 0xe7;              /* zero out rs and rw 11100111*/

outp (0xff, DDRC);                  /* D output */

outp (tmpr1, PORTC);             /* set rs and rw to 0 */

pause30();

tmpr1 |= 0x04;                 /* set E bit 00000100*/

outp (tmpr1, PORTC);             /* output E bit */

pause30();

outp (0xff, DDRB);                   /* B output */

outp (comm, PORTB);             /* send command to the data lines */

pause30();

tmpr1 &= 0xfb;               /* clear E bit 11111011*/

outp (tmpr1, PORTC);             /* output cleared E bit */

outp (0, DDRB);                       /* B input */

pause30();

}

 

 

 

void  lcdPrint (u08 address, u08 data)

/* write specified data to specified address */

{

register u08 tmpr1;

 

outp (0, DDRC);                       /* port D is input */

tmpr1 = inp(PINC);                  /* read values of port D */

outp (0xff, DDRC);                  /* port D is an output */

/* first we need to send the address */

tmpr1 &= 0xe7;              /* zero out rs and rw 11100111*/

outp (tmpr1, PORTC);             /* set rs and rw to 0 */

pause30();

tmpr1 |= 0x04;                 /* set E bit 00000100*/

outp (tmpr1, PORTC);             /* output E bit */

pause30();

outp (0xff, DDRB);                   /* B output */

address |= 0x80;              /* make sure it's Dram address   10000000*/

outp (address, PORTB);           /* put address on the lines */

pause30();

tmpr1 &= 0xfb;               /* clear E bit 11111011*/

outp (tmpr1, PORTC);             /* output cleared E bit */

pause30();

/* now we need to send the data */

tmpr1 |= 0x10;                 /* set rs 00010000*/

outp (tmpr1, PORTC);             /* output rs and rw  */

pause30();

tmpr1 |= 0x04;                 /* set E bit 00000100*/

outp (tmpr1, PORTC);             /* output E bit */

pause30();

outp (data, PORTB);                /* put data onto the lines */

pause30();

tmpr1 &= 0xfb;               /* clear E bit 11111011*/

outp (tmpr1, PORTC);             /* output cleared E bit */

pause30();

outp (0, DDRB);                       /* B input */

}

 

void lcdPrintNum (int num, u08 address)

{

register u08 tmp0;

tmp0 = (u08) num;

tmp0 = tmp0 + 0x30;

outp (~address, PORTA);

lcdPrint (address, tmp0);

}

 

 

 

void lcdPrintString (char *str, u08 address)

{

char tmp0;

tmp0 = *str;

while (tmp0 != 0)

          {

          lcdPrint (address, tmp0);

          address++;

          str++;

          tmp0 = *str;

          }

}

 

 

void printRecord (void)

{

register u08 tmp0 = recFull;

 

lcdPrintString ("FUNCTION", 0x40);

lcdPrintNum (recNum, 0x49);

tmp0 &= (1<<recNum);

if (tmp0)

          {

          lcdPrintString ("     ", 0x4b);

          }

else

          {

          lcdPrintString ("CLEAR", 0x4b);

          }

}

 

 

 

void incrementRec (void)

{

recNum++;

if (recNum > MAXREC)

          {

          recNum = 1;

          }

printRecord();

lcdPrintString("          ", 0x00);

}

 

 

 

 

int whichButton (register u08 code)

{

register u08 newstate;

 

 

pause6k();                       /* debounce */

newstate = inp(PIND);              /* wait for the button to be released */

newstate = ~newstate;

newstate &= 0x23;

while (newstate)

          {

          newstate = inp(PIND);              /* wait for the button to be released */

          newstate = ~newstate;

          newstate &= 0x23;

          }

pause6k();                       /* debounce */

switch (code)

          {

          case (0x01):  {return 0;}

          case (0x02):  {return 1;}

          case (0x04):  {return 2;}

          case (0x08):  {return 3;}

          case (0x10):  {return 4;}

          case (0x20):  {return 5;}

          case (0x40):  {return 6;}

          case (0x80):  {return 7;}

          }

return 8;

}

 

 

void readDetector(void)

{

register u08 tmpr0 = inp(PIND);

register u08 tmpr1;

register u08 tmpr2;

register u08 tmpr3;

int i;

short value;

 

lcdPrintString ("Recording", 0x00);

recFull |= (1<<recNum);

printRecord();

//outp (0xfe, PORTB);              // turn one led on

tmpr0 |= 0x08;

outp (tmpr0, PORTD);             // turn on test LED

tmpr0 = ~tmpr0;                       // check to see if we are getting signal

tmpr0 &= 0x04;                        // erase everything except bit 2

while (tmpr0 == 0)

          {

          tmpr0 = inp (PIND);

          tmpr0 = ~tmpr0;              // keep checking for IR detect signal

          tmpr0 &= 0x04;

          }

// now we have got a signal

outp (0x00, TCNT1H);

outp (0x00, TCNT1L);              // zero out timer 1

i = 0;                               // we will be reading in the first element

tmpr0 = inp (PIND);

tmpr0 &= 0xf7;                        // make bit 3 zero

outp (tmpr0, PORTD);             // turn LED off

tmpr0 = inp (PIND);

tmpr0 &= 0x04;                        // mask out IR input

for (;;)

          {

          tmpr1 = inp (PIND);        // check for IR input change

          tmpr1 &= 0x04;

          if (tmpr1 != tmpr0) // IR input changes

                   {

                   tmpr0 = tmpr1;      // assign new value to tmpr0

                   tmpr2 = inp(TCNT1L);

                   tmpr3 = inp(TCNT1H);   // read out values of the counter

                   value = ((short) tmpr3)<<8;  // value is high byte

                   //value = value*256;         // shift value left by 8

                   value |= (short) tmpr2; // get full value of the counter

                   outp (0x00, TCNT1H);

                   outp (0x00, TCNT1L);              // zero out timer 1

                   changes1[recNum-1][i] = (short) value;         // write new value into array

                   i++;             // increment i

                   if (i == MAXLEN)

                             {

                             tmpr0 = (char) i;

                             //outp (~tmpr0, PORTB);

                             lcdPrintString ("DONE      ", 0x00);

                             return;

                             }  // if reached the end of the array, done

                   }

          tmpr2 = inp(TIFR);                   // check for overflow

          tmpr2 &= 0x04;                        // isolate TOV1 bit

          }

}

 

 

void writeEmitter(void)

{

short tempVal;

short timerVal;

register u08 tmp0;

register u08 tmp1;

int i;

 

 

lcdPrintString ("          ", 0x00);

sei();                               // enable interrupts

outp (0x00, TCNT1H);

outp (0x00, TCNT1L);              // zero out timer 1

i = 0;

emitVal = 0xff;                          // we are emitting 'high'

tmp0 = inp(PIND);         

tmp0 |= 0x10;                           // write one to bit 4

outp (tmp0, PORTD);               // output bit 4

tempVal = changes1[recNum-1][i];

for (;;)

          {

          tmp0 = inp(TCNT1L);

          tmp1 = inp(TCNT1H);    // read out values of the counter

          timerVal = (short) tmp1;  // value is high byte

          timerVal = timerVal*256; // shift value left by 8

          timerVal |= (short) tmp0; // get full value of the counter

          if (timerVal == tempVal)  // reached the new transition

                   {

                   if (emitVal)

                             {

                             emitVal = ~emitVal;         // flip the flag

                             tmp0 = inp(PIND);

                             tmp0 &= 0xef;                // make bit 4 zero

                             outp (tmp0, PORTD);

                             }

                   else

                             {

                             emitVal = ~emitVal;

                             }

                   i++;                       // incrememt i

                   outp (0x00, TCNT1H);

                   outp (0x00, TCNT1L);

                   if (i == MAXLEN)

                             {

                             emitVal = 0x00;

                             cli();                      // disable interrupts

                             return;

                             }

                   tmp0 = (char) i;

                   tempVal = changes1[recNum-1][i];

                   }

          }

}

 

 

SIGNAL (SIG_OUTPUT_COMPARE2)

{

register u08 tmp0;

 

if (emitVal)

          {

          if (emitHigh)

                   {

                   emitHigh = ~emitHigh;

                   tmp0 = inp(PIND);

                   tmp0 &= 0xef;                // make bit 4 zero

                   outp (tmp0, PORTD);

                   }

          else

                   {

                   emitHigh = ~emitHigh;

                   tmp0 = inp(PIND);         

                   tmp0 |= 0x10;                           // write one to bit 4

                   outp (tmp0, PORTD);               // output bit 4

                   }

          }

}

 

 

int main(void)

{

register u08 tmpr0 = inp (TCCR1B);

register u08 buttons;

int      pressed;

 

outp(0x18, DDRD);                  // port D is input, except pins 3, 4, 5

outp(0x00, PORTD);

outp(0x00, DDRB);                  /* port B is initially input (lcd data) */

outp(0xff, DDRC);                   /* port D is output (lcd control) */

 

outp (0, PORTC);           /* zero out lcd command port */

outp(0xff, DDRA);                   // port B is output

outp(0xff, PORTA);                 // initially leds are 0

 

outp(0x09, TCCR2);                 // prescale timer 0 to ck, and reset on compare match

outp(0x00, TCNT2);

outp(0x00, TCCR1A);              // write zeros to tccr1a

tmpr0 |= 0x03;

outp(tmpr0, TCCR1B);             // prescale timer 1 to ck/64

outp(0, TCNT1H);

outp(0, TCNT1L);          // clear timer 1

//outp((1<<TOIE1), TIMSK);   /* enable overflow interrupt on timer1 */

outp((1<<OCIE2), TIMSK);               // enable overflow on timer 2 compare

outp((0<<TOV1), TIFR);                   // set overflow flag to zero

outp (100, OCR2);          // set output compare register 2 to 100 (for 40khz signal)

 

lcdCommand (0x38);                /* 8bit, 2 lines, 5x7 font 00111000*/

lcdCommand (0x06);                /* entry mode set 00000110*/

lcdCommand (0x0C);               /* display on, cursor off, no blinking 00001100*/

lcdCommand (0x01);                /* clear display */

pause1650();

lcdCommand (0x00);                /* nop */

 

cli();                      // enable interrupts (might need later)

printRecord();

 

for (;;)

{

buttons = inp(PIND);

buttons = ~buttons;

buttons &= 0x23;

if (buttons)

          {

          pressed = whichButton (buttons);

          switch (pressed)

                   {

                   case (0): 

                             {

                            

                             readDetector();

                             break;

                             }

                   case (1): 

                             {

                             writeEmitter();

                             break;

                             }

                   case (5):

                             {

                             incrementRec();

                             break;

                             }

                   }

          }

}

}