RC5 Philips on PIC18 using C18

Status
Not open for further replies.

haxan

New Member
Hi,

After long trying with SIRC (sony protocol) and not successful, i am trying out RC5 protocol by Philips.

The following code was written for another compiler and PIC16. I want to port it for PIC18 using C18 compiler. The code written below is not working as yet. Can someone please help me with this.

Code:
#include <p18cxxx.h>
#include <delays.h>

#pragma config WDT = OFF, LVP = OFF, OSC = XT, DEBUG = OFF

#define IR_pin PORTBbits.RB0
#define TIME_MIN  (5)
#define TIME_MAX  (11)
#define TIME_STEP (2)
#define LED0 PORTCbits.RC0
#define LED1 PORTCbits.RC1
#define LED2 PORTCbits.RC2
#define LED3 PORTCbits.RC3
#define LED4 PORTCbits.RC4

int RC5_receive(unsigned int *, unsigned int *);
void Delay100Us(unsigned char);
void applyIR(void);

void Delay100Us(unsigned char time)
{
	char x;
	for(x=0;x<time;x++)
		Delay10TCYx(9);
}

unsigned int IR_addr, IR_data = 0;

void applyIR(void)
{
	switch(IR_data)
	{
		case 0: LED0 ^= 1;break;
		case 1: LED1 ^= 1;break;
		case 2: LED2 ^= 1;break;
		case 3: LED3 ^= 1;break;		
		case 4: LED4 ^= 1;break;
	}
}	

void main(void)
{
	ADCON1 = 0x0F;
	TRISB = 0x01;
	TRISA = 0x00;
	PORTB = 0x00;
	TRISC = TRISD = TRISE = 0x00;
	PORTA = PORTC = PORTD = PORTE = 0x00;
	PORTC = 0x55;
	while(1)
	{
		RC5_receive(&IR_addr, &IR_data);
		applyIR();
	}
}

int RC5_receive(unsigned int * RC5addr, unsigned int * RC5data) 
{
    int           OffTime, OnTime, DevTime, DiTime, i, j, k;
    unsigned int  data = 0, addr = 0;
    unsigned int  bit_mask;

    if(!IR_pin)
    {
		for(OffTime = 0; !IR_pin && OffTime < TIME_MAX; OffTime += TIME_STEP){Delay100Us(TIME_STEP);}
		if (OffTime > TIME_MAX) return -1;
		if (OffTime < TIME_MIN) return -1;

		for(OnTime = 0; IR_pin && OnTime < TIME_MAX; OnTime += TIME_STEP){Delay100Us(TIME_STEP);}
		if (OnTime > TIME_MAX) return -1;
		if (OnTime < TIME_MIN) return -1;


		//* skip token
        DevTime = (2 * OffTime + OnTime + OffTime / 2);

        for (k = 0; k < DevTime; k += TIME_STEP){Delay100Us(TIME_STEP);}
	
		//* get address and data
		DiTime  = (OffTime + OnTime);
	
		for (i = 0; i < 5; i++)
		{
		    if(IR_pin) {addr <<= 1;} else{addr <<= 1; addr |= 1;}
		    for (k = 0; k < DiTime; k += TIME_STEP){Delay100Us(TIME_STEP);}
		}
		for (i = 0; i < 6; i++)
		{
		    if(IR_pin){data <<= 1;}else{data <<= 1; data |= 1;}
		    for (k = 0; k < DiTime; k += TIME_STEP){Delay100Us(TIME_STEP);}
		}
	
		*RC5data = data;
		*RC5addr = addr;
		return 0;
    }
    return -1;
}
 
Last edited:
RC5 Decoder with PIC Microcontroller

This thread is quite old, but still it might be usefull for someone ...

I have written a RC5 decoder in C language which can be compiled with CCS C compiler and Microchip C18 compiler. You can get the code and further information regarding the required hardware at the following link:
http://www.picprojects.net/rc5_decoder/index.html
 
I'm nearly complete with Nigel's SIRC code for the pi16... the delays are critical... What frequency are you clocking at... The code you posted was for a 20mhz crystal...
When I converted the assembled code. I found that due to the latency in C coding I had to adjust the delays extensively.... Nigel used 6 nop's (6us) for a pulse and 14 (14us) for the space, due to the overhead in C I had to reduce the delays to 4us and 7us to maintain 38khz.

Just a question... Why does the IR receive function accept pointers when the actual values are global?
 

I like it Jason...

My version of the SIRC decoder is non-blocking and runs in the ISR or in a main loop at 100 us intervals. It also has a 250 ms repeat timer which is plenty long enough to reject the two or three extra commands you get with even the quickest button press on a Sony remote...

Code:
  /*
   *  Mike McLaren's SIRC decoder (100-usec intervals)
   */
   if(irpin == 0)               // if IR pin lo
   { count++;                   // inc 100-usec counter
   }
   else                         // if IR pin hi
   { if(count)                  // if new bit received
     { if(bitctr)               // if rx-in-progress
       { sirc >>= 1;            // make room for new bit
         sirc.12 = 0;           // set new bit to '0'
         if(count > 9)          // if a '1' bit (>900-us)
           sirc.12 = 1;         // set new bit to '1'
         if(--bitctr == 0)      // if last bit
         { if(reptmr == 0)      // if repeat timer timed out
           { if(sirc == Key1)   // if sony remote '1' key
               flags.0 = 1;     // set "up" switch flag
             if(sirc == Key2)   // if sony remote '2' key
               flags.1 = 1;     // set "down' switch flag
             if(sirc == Key3)   // if sony remote '3' key
               flags.2 = 1;     // set "mute' switch flag
             reptmr = 2500;     // reset for 250-msecs
           }                    //
         }                      //
       }                        //
       else                     // not rx-in-progress so
       { if(count > 20)         // if new 'start' bit (>2000-us)
           bitctr = 12;         // set rx-in-progress flag
       }
       count = 0;               // clear 100-usec counter
     }
   }
   if(reptmr) reptmr--;         // if running, dec 250 ms timer
 
Last edited:
Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…