// INTERRUPT-DRIVEN serial code
//used as an example in the serial communication doc.
#include <mega32.h>
#include <stdio.h>
//timeout values for each task
#define t1 10 // samples at 0.1 milliseconds
#define t2 50 //set this to 50 -->
recognizes the pattern at 0.5 milliseconds / bit
//I like these definitions
#define begin {
#define end }
//the subroutines
void task1(void); //some task for serial port
void task3(void); // tests if button is
pushed --> state machine
void task4(void); // after sampling
complete, processes button press
void gets_int(void); //starts getting a string from serial line
void puts_int(void); //starts a send to serial line
void initialize(void); //all the usual mcu stuff
unsigned int time1, /*time2*/ ; //task scheduling timeout counters
unsigned int time3, time4; //time for task 3
and 4
unsigned long time;
unsigned int v;
//option selector from serial port
//eeprom variables
eeprom int a; //dummy
eeprom int rbuttons[26]; //this one stores the opcodes for the buttons
int buttons[26] = {16447, 8287, 24607, 4207, 20527, 12367, 28687, 2167, 18487,
127, 10327, 29707, 11347, 15427, 9307, 1147, 21547, 31747, 27667, 17467, 25627,
7267, 23587, 30727, 14407, 19507};
int buttons2[26]; //buttons is default buttons for remote 1; button2 is used for
comparison
//RXC ISR variables
unsigned char r_index; //current string index
unsigned char r_buffer[16]; //input string
unsigned char r_ready; //flag for receive done
unsigned char r_char; //current character
//TX empth ISR variables
unsigned char t_index; //current string index
unsigned char t_buffer[16]; //output string
unsigned char t_ready; //flag for transmit done
unsigned char t_char; //current character
char IR=0; //this variable is 0 / 1
depending on IR signal
int count=0; //this variable keeps track of how many
ones in each pulse
int trak = 0; //this variable does 'trak'ing of the array
keep[70]
int fl = 0; //this is the state variable
int previous = 0;
int va;
int keep[70]; //128 bit number --> reduced to 32 integer array
pattern (store in an array of 70)
//variables used elsewhere
int menu;
//menu selection
int lpvar; //loop
variable
int update_key_var; //keeps track of button numbers
int last;
//one behind update_key_var
//**********************************************************
//timer 0 overflow ISR
interrupt [TIM0_COMP] void timer0_compare(void)
begin
time++;
//Decrement the three times if they are not already zero
if (time1>0) --time1;
// if (time2>0) --time2;
if (time3>0) --time3;
if (time4>0) --time4;
end
//**********************************************************
//**********************************************************
//UART character-ready ISR
interrupt [USART_RXC] void uart_rec(void)
begin
r_char=UDR; //get a char
UDR=r_char; //then print it
//build the input string
if (r_char != '\r') r_buffer[r_index++]=r_char;
else
begin
putchar('\n'); //use putchar to avoid overwrite
r_buffer[r_index]=0x00; //zero terminate
r_ready=1; //signal cmd processor
UCSRB.7=0; //stop rec ISR
end
end
/**********************************************************/
//UART xmit-empty ISR
interrupt [USART_DRE] void uart_send(void)
begin
t_char = t_buffer[++t_index];
if (t_char == 0)
begin
UCSRB.5=0; //kill isr
t_ready=1; //transmit done
end
else UDR = t_char ; //send the char
end
/**********************************************************/
//**********************************************************
//Entry point and task scheduler loop
void main(void)
begin
initialize();
//main task scheduler loop -- never exits!
while(1)
begin
if (PINA==0x01)
{
PORTC=0x00; //initiates PORTC to output at 0 --> no
signal
}
//runs the tasks
if (time1==0) task1();
// if (time2==0) task2();
if(trak<34)
if (time3==0) task3();
if(trak==34)
if (time4==0) task4();
//this below is menu options for serial port
communication with Atmel MEGA32
menu = v;
switch(menu) //menu selection
{
case 1: //this case loading default
values back into the system
{
for(lpvar = 0; lpvar < 26; lpvar++)
{
rbuttons[lpvar] = buttons[lpvar];
}
v = 5;
}
break;
case 2: //this case allows you to reprogram
all the buttons
{
if(update_key_var == 9999)
{
putsf("Enter a remote key for each appearing button\r\n");
for(lpvar = 0; lpvar < 26; lpvar++)
{
buttons2[lpvar] = 0;
}
last = update_key_var;
update_key_var = 0;
}
//prompts user for each button type to get
if((update_key_var != last) && (update_key_var != 26))
{
if(update_key_var < 9)
{
sprintf(t_buffer, "%i\r", update_key_var+1);
puts(t_buffer);
}
else if(update_key_var == 10)
putsf("channel down\r");
else if(update_key_var == 9)
putsf("0\r");
else if(update_key_var == 11)
putsf("channel up\r");
else if(update_key_var == 12)
putsf("volume up\r");
else if(update_key_var == 13)
putsf("volume down\r");
else if(update_key_var == 14)
putsf("POWER\r");
else if(update_key_var == 15)
putsf("button below POWER\r");
else if(update_key_var == 16)
putsf("TV-FM Toggle\r");
else if(update_key_var == 17)
putsf("return\r");
else if(update_key_var == 18)
putsf("reverse\r");
else if(update_key_var == 19)
putsf("point left\r");
else if(update_key_var == 20)
putsf("point right\r");
else if(update_key_var == 21)
putsf("mute\r");
else if(update_key_var == 22)
putsf("minimise\r");
else if(update_key_var == 23)
putsf("camera\r");
else if(update_key_var == 24)
putsf("camcorder\r");
else if(update_key_var == 25)
putsf("source\r");
last = update_key_var;
}
if(update_key_var==26)
//shoves the new op codes into the system
{
for(lpvar = 0; lpvar < 26; lpvar++)
{
rbuttons[lpvar] = buttons2[lpvar];
}
update_key_var = 9999;
v = 5;
}
}break;
case 3: // this button
allows you to program just the number buttons
{
if(update_key_var == 9999)
{
putsf("Enter a remote key for each appearing button\r\n");
for(lpvar = 0; lpvar < 26; lpvar++)
{
buttons2[lpvar] = 0;
}
last = update_key_var;
update_key_var = 0;
}
//prompts the user for each number button to get
if((update_key_var != last) && (update_key_var != 26))
{
if(update_key_var < 9)
{
sprintf(t_buffer, "%i\r", update_key_var+1);
puts(t_buffer);
}
else if(update_key_var == 9)
putsf("0\r");
last = update_key_var;
}
if(update_key_var==10) //shoves
the new opcodes into the system
{
for(lpvar = 0; lpvar < 26; lpvar++)
{
rbuttons[lpvar] = buttons2[lpvar];
}
update_key_var = 9999;
v = 5;
}
}break;
case 5:
//prints the menu
{
putsf("\r\nIR Remote Control Menu:\r\n");
putsf("[1] Set / Reset Default Keys: \r\n");
putsf("[2] Re-Program All Keys: \r\n");
putsf("[3] Re-Program Number Keys: \r\n");
putsf("[4] Test Keys \r\n");
putsf("[5] Menu \r\n");
v = 0;
}break;
default:
{
}break;
}
end
end
//**********************************************************
//**Simple State Machine for Sampling**////////////////////
int tog = 0;
void task3(void)
{
time3=t1;
IR = PINB & 0b00000001;
if (fl==0)
{
if (IR==0) //state triggers if
first enormous zero dip detected
{
fl=1;
count = 0;
}
}
else
//remains in this state until signal is gotten
{
if (IR==1)
{
count++;
}
else
{
if((count > 38) && (count < 50)) //this detects start
sequence ~42 to 47 counts
tog = 1;
if(tog == 1) //update track
{
keep[trak] = count;
if(count != 0 ) //this throws away the zero and keeps
the ones
trak++;
}
count = 0;
}
}
}
int tt=0; //this variable is a tracking variable for the array keep
int num = 0; //this variable is a conversion of the 33 integer array into a
16-bit integer
void task4(void)
{
//putsf("success\r\n");
time4=t2;
//if (trak == 34 && tt != 34)
//if(tt>15 && tt < 32)
//sprintf(t_buffer, "%i, %i\r", keep[tt], tt);
//puts(t_buffer);
tt++;
if(tt == 34) //if count hits 34 we do pattern matching to discover
button
{
//putsf("stop!");
//sprintf(t_buffer, "%i", num);
//puts(t_buffer);
trak = 0; //reset trak variable to 0
tt = 0; //reset another trak-like variable to 0
fl = 0; //reset state machine for sampling
//the following code is repetitive but slightly different
//PORTC sends out a signal for which button was pressed
//if(v==4) then a display is sent for what button is pressed
//on to the serial port terminal
if(num == rbuttons[0])
{
if(v == 0)
PORTC = 0x01;
if(v == 4)
putsf("1\r\n");
}
else if(num == rbuttons[1])
{
if(v == 0)
PORTC = 0x02;
if(v == 4)
putsf("2\r\n");
}
else if(num == rbuttons[2])
{
if(v == 0)
PORTC = 0x03;
if(v == 4)
putsf("3\r\n");
}
else if(num == rbuttons[3])
{
if(v == 0)
PORTC = 0x04;
if(v == 4)
putsf("4\r\n");
}
else if(num == rbuttons[4])
{
if(v == 0)
PORTC = 0x05;
if(v == 4)
putsf("5\r\n");
}
else if(num == rbuttons[5])
{
if(v == 0)
PORTC = 0x06;
if(v == 4)
putsf("6\r\n");
}
else if(num == rbuttons[6])
{
if(v == 0)
PORTC = 0x07;
if(v == 4)
putsf("7\r\n");
}
else if(num == rbuttons[7])
{
if(v == 0)
PORTC = 0x08;
if(v == 4)
putsf("8\r\n");
}
else if(num == rbuttons[8])
{
if(v == 0)
PORTC = 0x09;
if(v == 4)
putsf("9\r\n");
}
else if(num == rbuttons[10])
{
if(v == 0)
PORTC = 0x0A;
if(v == 4)
putsf("Channel Down\r\n");
}
else if(num == rbuttons[9])
{
if(v == 0)
PORTC = 0x0B;
if(v == 4)
putsf("0\r\n");
}
else if(num == rbuttons[11])
{
if(v == 0)
PORTC = 0x0C;
if(v == 4)
putsf("Channel Up\r\n");
}
else if(num == rbuttons[12])
{
if(v == 0)
PORTC = 0x0D;
if(v == 4)
putsf("Volume Up\r\n");
}
else if(num == rbuttons[13])
{
if(v == 0)
PORTC = 0x0E;
if(v == 4)
putsf("Volume Down\r\n");
}
else if(num == rbuttons[14])
{
if(v == 0)
PORTC = 0x0F;
if(v == 4)
putsf("POWER\r\n");
}
else if(num == rbuttons[15])
{
if(v == 0)
PORTC = 0x10;
if(v == 4)
putsf("TV-FM Toggle\r\n");
}
else if(num == rbuttons[16])
{
if(v == 0)
PORTC = 0x11;
if(v == 4)
putsf("Button below POWER\r\n");
}
else if(num == rbuttons[17])
{
if(v == 0)
PORTC = 0x12;
if(v == 4)
putsf("Return\r\n");
}
else if(num == rbuttons[18])
{
if(v == 0)
PORTC = 0x13;
if(v == 4)
putsf("Reverse\r\n");
}
else if(num == rbuttons[19])
{
if(v == 0)
PORTC = 0x14;
if(v == 4)
putsf("Point Left\r\n");
}
else if(num == rbuttons[20])
{
if(v == 0)
PORTC = 0x15;
if(v == 4)
putsf("Point Right\r\n");
}
else if(num == rbuttons[21])
{
if(v == 0)
PORTC = 0x16;
if(v == 4)
putsf("Mute\r\n");
}
else if(num == rbuttons[22])
{
if(v == 0)
PORTC = 0x17;
if(v == 4)
putsf("Minimise\r\n");
}
else if(num == rbuttons[23])
{
if(v == 0)
PORTC = 0x18;
if(v == 4)
putsf("Camera-Snap\r\n");
}
else if(num == rbuttons[24])
{
if(v == 0)
PORTC = 0x19;
if(v == 4)
putsf("Camcorder-Record\r\n");
}
else if(num == rbuttons[25])
{
if(v == 0)
PORTC = 0x1A;
if(v == 4)
putsf("Source\r\n");
}
else
{
if((v != 2) && (v !=3))
putsf("Invalid Entry\n\r");
}
//the following if statement checks if a previous button has
already been programmed/registered in the system
if((v == 2) || (v == 3))
{
if((buttons2[0] == num )|| (buttons2[1] == num
)||(buttons2[2] == num )||(buttons2[3] == num )||(buttons2[4] == num )||
(buttons2[5] == num )||(buttons2[6] == num )||(buttons2[7] ==
num )||(buttons2[8] == num )||(buttons2[9] == num )||
(buttons2[10] == num )||(buttons2[11] == num )||(buttons2[12]
== num )||(buttons2[13] == num )||(buttons2[14] == num )||
(buttons2[15] == num )||(buttons2[16] == num )||(buttons2[17]
== num )||(buttons2[18] == num )||(buttons2[19] == num )||
(buttons2[20] == num )||(buttons2[21] == num )||(buttons2[22]
== num )||(buttons2[23] == num )||(buttons2[24] == num )||
(buttons2[25] == num ))
previous = 1;
if(previous == 0)
{
buttons2[update_key_var] = num;
update_key_var++;
}
else
putsf("You have already programmed this key!\n\r");
}
previous = 0;
tog = 0;
num = 0;
}
//this part changes a 33 bit number into a 16 bit int
//we throw away the first 16 bit because they are the same for all buttons
if((tt>15) && (tt < 32)){
if(keep[tt] < 10)
{
num = num << 1;
//putsf("less than 10\r");
}
if(keep[tt] > 10)
{
num = num << 1;
num = num + 0x0001;
//putsf("greater than 10\r");
}
}
}
//Task 1 input a string and print it
void task1(void)
begin
time1=t1; //reset the task timer
//print ad get another serial string
if (r_ready )
begin
sscanf(r_buffer,"%d",&v);
gets_int();
end
end
void gets_int(void)
begin
r_ready=0;
r_index=0;
UCSRB.7=1;
end
//**********************************************************
// -- nonblocking print: initializes ISR-driven
// transmit. This routine merely sets up the ISR, then
//send one character, The ISR does all the work.
void puts_int(void)
begin
t_ready=0;
t_index=0;
if (t_buffer[0]>0)
begin
putchar(t_buffer[0]);
UCSRB.5=1;
end
end
//**********************************************************
//Set it all up
void initialize(void)
begin
//serial setop for debugging using printf, etc.
UCSRB = 0x18 ;
UBRRL = 103 ;
DDRC = 0xFF;
DDRA = 0x00;
PORTC=0x00;
putsf("\r\nRemote Control Menu:\r\n");
putsf("[1] Set / Reset Default Keys: \r\n");
putsf("[2] Re-Program All Keys: \r\n");
putsf("[3] Re-Program Number Keys: \r\n");
putsf("[4] Test Keys \r\n");
putsf("[5] Menu \r\n");
//set up timer 0
OCR0=20; //0.01 mSec /20 --> x
10 = 0.1 mSec
TIMSK=2; //turn on timer 0 cmp-match ISR
TCCR0=0b00001010; //prescalar to 8 and Clr-on-match
//GICR = 0b10000000;
// MCUCR = 0b00001100;
//init the task timers
time1=t1;
// time2=t2;
time3 = t1;
time4 = t2;
r_ready=0;
t_ready=1;
trak = 0;
menu = 0;
lpvar = 0;
update_key_var = 9999;
last = 0;
// gettime = 0;
// sendout = 0;
//crank up the ISRs
#asm
sei
#endasm
gets_int();
end