Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

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.

Latest threads

New Articles From Microcontroller Tips

Back
Top