Sending code. It was tested on PIC16f628 with 4.433619Mhz. Connect IR diode to hardware PWM output. Don't forget to put 130ms delay after sending code (but maybe it could work without that, I didn't tested that).
Code: Select all
void IR1() {
PWM_Stop();
delay_us(864);
PWM_Start();
delay_us(864);
}
void IR0() {
PWM_Start();
delay_us(864);
PWM_Stop();
delay_us(864);
}
void RC5_Send(short toggle, short adress, short command) {
short i1;
IR1();
IR1();
if(toggle) IR1();
else IR0();
for (i1 = 0; i1 <= 4; i1++) {
if (adress & (1 << i1)) IR1();
else IR0();
}
for (i1 = 0; i1 <= 4; i1++) {
if (command & (1 << i1)) IR1();
else IR0();
}
PWM_Stop();
}
void main() {
TRISB.F3 = 0;
PWM_Init(36000);
PWM_Change_Duty(127);
PWM_Stop();
while (1) {
RC5_Send(1,29,5); // for example
delay_ms(130);
}
}
Receiving code. It was tested on PIC16F871 with 14.31818Mhz. Connect TSOP17xx to RB0. It use RB0 interrupt and timer0. U need to enter uc clock in MHz (without anything after dot), its required to calculate prescaler for timer0.
Code: Select all
unsigned short adr, comm, togg, count, error;
short RC5Len;
short check_byte() {
unsigned short old;
delay_us(1296);
old = PORTB.F0;
TMR0 = 0;
INTCON.T0IF = 0;
while (PORTB.F0 == old) {
if (TMR0 > (RC5Len + 10)) return 127;
}
if (TMR0 < (RC5Len - 10)) return 127;
return old;
}
short check_start_byte(char status) {
TMR0 = 0;
INTCON.T0IF = 0;
while (PORTB.F0 == status) {
if (TMR0 > ((RC5Len * 2) + 10)) return 127;
}
if (TMR0 < ((RC5Len * 2) - 10)) return 127;
return 1;
}
unsigned short read_rc5(short *toggle, short *adress, short *command) {
short tmp;
short i1;
*toggle = 0;
*adress = 0;
*command = 0;
tmp = check_start_byte(0);
if (tmp == 127) goto err1;
tmp = check_start_byte(1);
if (tmp == 127) goto err1;
tmp = check_byte();
if (tmp == 127) goto err1;
if (tmp) *toggle = 1;
for (i1 = 0; i1 <= 4; i1++) {
tmp = check_byte();
if (tmp == 127) goto err1;
if (tmp) *adress = *adress | (1<<i1);
}
for (i1 = 0; i1 <= 5; i1++) {
tmp = check_byte();
if (tmp == 127) goto err1;
if (tmp) *command = *command | (1<<i1);
}
err1:
INTCON.T0IF = 0;
if (tmp == 127) return 1;
else return 0;
}
short rc5_init(short clock) {
if (clock < 9) OPTION_REG = 0b10000100;
else if (clock > 15) OPTION_REG = 0b10000110;
else OPTION_REG = 0b10000101;
INTCON.GIE = 1;
INTCON.INTE = 1;
INTCON.T0IE = 1;
INTCON.T0IF = 0;
TMR0 = 0;
delay_us(432);
return TMR0 - 2;
}
void interrupt() {
if (INTCON.T0IF) {
count++;
if (count == 200) count = 0;
TMR0 = 0;
INTCON.T0IF = 0;
INTCON.T0IE = 1;
}
if (INTCON.INTF) {
error = read_rc5(&togg, &adr, &comm);
count = 0;
INTCON.INTF = 0;
}
}
void main() {
RC5Len = rc5_init(14);
TRISB.F0 = 1;
while (1) {
if (adr == 0) {
if (togg) {
//some code
if (count > 60) comm = 0;
}
else {
// again some code
}
}
if (error) {
error = 0;
// error handling
}
}
}