===================================
======= The code wrote by pkar ========
unsigned counter = 0;
unsigned input_data, bit_count;
enum {
Idle,
Start_bit,
Capture_bit
};
char Current_state = Idle;
char got_data = 0;
char Command_code, Device_code;
void interrupt(){
if(INTCON.INTF){
T1CON.TMR1ON =1; //timer1 On
switch (Current_state){
case Idle:
OPTION_REG.INTEDG = 1; //interrupt on rising edge.
counter = 0;
Current_state = Start_bit;
break;
//found the rising edge, check lenght for 2.4ms
case Start_bit:
//correct signal, move on to next state
if(counter==4) {
counter = 0;
bit_count = 0;
input_data = 0;
Current_state = Capture_bit;
} else {
//fault signal, reset to Idle
Current_state = Idle;
}
break;
case Capture_bit:
//check plus length for 0 or 1
if(counter==2){
input_data >>= 1; // add 0 to received data
bit_count++;
}
else if(counter==3){
input_data >>= 1;
input_data |= 0x8000; //add 1 to received data
bit_count++;
}
//complete 12 bit
if(bit_count >= 12){
got_data = 1;
input_data >>= 4;
OPTION_REG.INTEDG = 0; //interrupt on falling edge.
Current_state = Idle;
}
counter = 0;
break;
default: Current_state = Idle;
}
INTCON.INTF = 0; //clear interrupt flag.
}
if(PIR1.TMR1IF){
counter++;
TMR1H = 0xFF; //16bit timer1 register value High order(8bit)
TMR1L = 0x6A; //16bit timer1 register value low order(8bit)
if(counter > 5) {
Current_state = Idle;
counter = 0;
OPTION_REG.INTEDG = 0; //interrupt on falling edge
}
PIR1.TMR1IF = 0; //clear interrupt flag
}
}
//******************************************************************************
// MAIN MAIN MAIN MAIN
//******************************************************************************
void main() {
TRISIO = 0b00001100; //Configure I/O Pin
GPIO = 0x00; //Set all output to 0
ANSEL = 0; //All digital I/O
CMCON = 7; //Disable Comparator
//******************************************************************************
// GP2/INTE interrupt set up
//******************************************************************************
INTCON.INTE = 1; //enable GP2/INT interrupt.
OPTION_REG.INTEDG = 0; //interrupt on falling edge.
//******************************************************************************
// Timer1 interrupt setting, interrupt every 600us timer register value TMR1H = 0xFF; TMR1L = 0x6A;
// Clock source Internal Oscillator 4Mhz
//******************************************************************************
T1CON.T1CKPS1 = 1; //prescaler 1:4
T1CON.T1CKPS0 =0;
PIE1.TMR1IE = 1; //enable timer1 interrupt
//******************************************************************************
// Global interrupt enable
//******************************************************************************
INTCON.PEIE = 1; //enable interrupt
INTCON.GIE = 1; //enable global interrupt
while(1){
if(got_data){
Command_code = input_data & 0x7F;
Device_code = input_data >> 7;
got_data = 0;
if(Device_code == 1){
switch (Command_code){
case 1: GPIO.GP0 = ~GPIO.GP0; break;
case 2: GPIO.GP1 = ~GPIO.GP1; break;
case 3: GPIO.GP4 = ~GPIO.GP4; break;
case 4: GPIO.GP5 = ~GPIO.GP5; break;
}
}
}
asm clrWDT;
}
}