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;
}
}
}
}
}