We did that for Sony and the code for 16F84@4MHz written with CC5XFree
follows. see if u can figure it :-)
//=============cut--here=================================
/*
* IR reception
* 05/Sep/1999 JLS & CAE
* jls@certi.ufsc.br
* cae@certi.ufsc.br
* CC5xFree v3.0E (www.bknd.com)
*/
/*
Sony Data format: 12 bits
Bit zero:
400
+--+ +...
| | |
+ +---+
800
Bit one:
400
+--+ +...
| | |
+ +------+
1400
Frame:
400 400
--+
+--+ +--+ +--+
| &nbs
p;
| | | | | |
+---2600---+ +---+ +------+
+...
800 1400
Decoding algorithm:
- Detect 2600us pulse,
- measure next high pulse as P1 (400us)
- measure next low pulse as P2 (800/1400us)
- store min(P1)
- store max(P2)
After all measurements:
- calculate mean = (max-min)/2 + min
- For all (P1,P2) measured:
. Add P1+P2=P3
. If P3< mean => bit is zero
. If P3>=mean => bit is one
Measures with Timer0 & Prescaler:16
2600us = 162
1400us = 87
800us = 50
400us = 25
400+800 = 25+50 = 75
400+1400 = 25+87 = 112
mean ~= (112-75)/2+75 = 18+75 = 93
*/
#define _16f84_
#include <16f84.h>
#ifdef _12C508_
bit
_TxOUT @ GP0;
bit
RxD_pin @ GP1;
bit
IR_input @ GP2;
#else
#define RP0
STATUS.5
#pragma update_RP 0 &nbs
p;
/* OFF */
#define DEF_TRISA
0
#define DEF_TRISB
6
bit
Rele
@ PORTA.1;
bit
IR_input @ PORTB.1;
bit
RxD_pin @ PORTB.2;
bit
_TxOUT @ PORTB.3;
bit
LED
@ PORTB.4;
#endif
unsigned char size,x,y,med,min,max,rxBuf;
unsigned char r[4];
unsigned char buff[32];
void TxSerial (unsigned char txBuf);
/*-----------------------------------------------------------------------
---*/
void TxEnter (void) {
/*----------------------------------------------------------------------
----*/
TxSerial(0xD);
TxSerial(0xA);
}
/*-----------------------------------------------------------------------
---*/
void TxHexAscii (unsigned char in) {
/*----------------------------------------------------------------------
----*/
unsigned char Hex;
tt>
Hex = swap(in); &nb
sp;  
;
// upper nibble
Hex &= 0x0F;
if (Hex<10) Hex +=
0x30;
else Hex += 0x37;
TxSerial(Hex);
Hex = in & 0x0F;
if (Hex<0x0A) Hex
+= 0x30;
else Hex += 0x37;
TxSerial(Hex);
}
/*-----------------------------------------------------------------------
---*/
void Delay_uSeg (unsigned char timeout) {
/*----------------------------------------------------------------------
----*/
// delay = 3*timeout
+ 7uS (including call and return)
while (1) {
timeout--;
if (timeout==0) {
nop();
nop();
return;
}
}
}
/*-----------------------------------------------------------------------
---*/
void TxSerial (unsigned char txBuf) {
/*----------------------------------------------------------------------
----*/
/*
;-----------------------------------------------------------------
----------*
; Transmit 1 start bit Lo, 8 data bits and 1 stop bit Hi
at 9600 bps
; No Parity
; Byte time = 1.040 mS
; Bit time = 104 uS (0.16% erro w/4.00 Mhz Internal
RC)
; Input : W = byte to be transmitted
; Output: byte transmitted by serial pin
;-----------------------------------------------------------------
----------*
*/
char idx;
while (1)
{
Carry = 0; &nbs
p;
// start bit
for (idx=10; idx; idx--) // 3us
{
_TxOUT = Carry; // 4us
Delay_uSeg(28); // 91us
(28*3+7)
Carry = 1; &nbs
p;
// 1us
txBuf = rr(txBuf); // 1us
nop(); &n
bsp;
// 1us
} &
nbsp; &nb
sp;
// 3us
return;
}
}
/*-----------------------------------------------------------------------
---*/
void RxSerial (void) {
/*----------------------------------------------------------------------
----*/
/*
;-----------------------------------------------------------------
----------*
; Receives 1 start bit Lo, 8 data bits and 1 stop bit Hi
at 9600 bps
; No Parity
; Byte time = 1.040 mS
; Bit time = 104 uS (0.16% erro w/4.00 Mhz Internal
RC)
;
; False start bit check
;
; Start bit hunting timeout = 4*1.283ms
;
; Input : none
; Output : Carry = 1 => success
; rxBuf
= input byte
; Carry
= 0 => error (timeout or stop bit=0)
;-----------------------------------------------------------------
----------*
*/
char idx;
rxBuf = 4; &n
bsp; &nbs
p;
// 5.135 ms timeout
idx = 0;
while (1)
{
while (RxD_pin)  
;
// input "high"
{
if ((-- idx)==0)
{
&n
bsp;
if ((-- rxBuf)==0)
&n
bsp;
{
&n
bsp; &nbs
p;
Carry = 0;
&n
bsp; &nbs
p;
return;
&n
bsp;
}
}
}
&
nbsp;
Delay_uSeg(14);  
;
// 1/2 bit delay (14*3+7)
if (RxD_pin)
continue;  
;
// false start bit detection
&
nbsp;
rxBuf = 0x80; &
nbsp;
// 8 bits counter and reception buffer
nop();
nop(); &n
bsp;
// timming adjustment
&
nbsp;
do
{
Delay_uSeg(30); // (30*3+7)us
Carry = RxD_pin; // bit read
rxBuf = rr(rxBuf); // store and count
}
while (Carry==0);
Delay_uSeg(30);  
;
// 1 bit delay
nop(); &n
bsp;
// timming adjustment
Carry = RxD_pin; &nbs
p;
// stop bit read
return; &
nbsp;
// 100 us availiable
}
}
/*-----------------------------------------------------------------------
---*/
void main (void) {
/*----------------------------------------------------------------------
----*/
#ifdef _12C508_
// OSCCAL = W; &nbs
p;
&n
bsp;
// OscCal Value - OTP part
OSCCAL = 0xB0; &nb
sp;  
; &
nbsp;
// OscCal Value - Windowed part
GPIO
= 0x00;
TRIS
= 0x08; &
nbsp; &nb
sp;
// GP3 input
OPTION = 0b11000011;&nb
sp;  
;
// Prescaler Timer0 1:16
#else
INTCON = 0;
&n
bsp; &nbs
p;
// no interrupts
PCLATH = 0;
&n
bsp; &nbs
p;
// bank 0
PORTA =
0;
PORTB =
0;
RP0
= 1; &nbs
p;
// RAM bank 1
TRISA =
DEF_TRISA;
TRISB =
DEF_TRISB;
OPTION = 0b11000011;&nb
sp;  
;
// Prescaler Timer0 1:16
RP0
= 0; &nbs
p;
// RAM bank 0
#endif
while (1)
{
/* set vars to start */
&
nbsp;
FSR = buff; &nb
sp;  
;
// pointer to buffer
x = 12; &
nbsp; &nb
sp;
// only 12 bits
size = 0;  
; &
nbsp;
// word size in bits
min = 255; &nbs
p;
// min period
max = 0;
&n
bsp;
// max period
& nbsp; /* start bit management */
&
nbsp;
while (IR_input==1);
// wait for 0
/* 2600us start bit */
while (IR_input==0);
// wait for 1
&
nbsp;
TMR0 = 0;  
; &
nbsp;
// start counter
do
{
/* measure high pulse */
&
nbsp;
INDF = 0;  
;
// period: default to zero
while (TMR0==0); &nbs
p;
// wait TMR0 advance
while (IR_input==1) &
nbsp;
// wait for 0
{
&n
bsp;
if (TMR0==0)
// timer overflow (4096us) ?
&n
bsp; &nbs
p;
goto frame_end; // yes, exit
}
INDF = TMR0; &n
bsp;
// store period
TMR0 = 0;  
;
// start counter
med = INDF; &nb
sp;
// save high period
FSR++; &n
bsp;
// bump pointer
INDF = 0;  
;
// period: default to zero
size++; &
nbsp;
// inc bit counter
& nbsp; /* measure low pulse */
&
nbsp;
while (TMR0==0); &nbs
p;
// wait TMR0 advance
while (IR_input==0);
// wait for 1
INDF = TMR0; &n
bsp;
// store period
TMR0 = 0;  
;
// start counter
med += INDF; &n
bsp;
// total period
if (med>=max) max = med; // find
max
if (med<min) min = med;
// find min
FSR++; &n
bsp;
// bump pointer
size++; &
nbsp;
// inc period counter
x--; &nbs
p;
// dec max bits
}
while (x);
frame_end:
LED = 1;
med = max - min;
med /= 2;
med += min;
&
nbsp;
r[0] = 0;
r[1] = 0;
r[2] = 0;
r[3] = 0;
&
nbsp;
FSR = buff;
FSR += size;
x = size/2;
do
{
Carry = 0;
r[3] = rl(r[3]);
r[2] = rl(r[2]);
r[1] = rl(r[1]);
r[0] = rl(r[0]);
FSR--;
max = INDF;
FSR--;
max += INDF;
if (max>=med) r[3]++;
} while (--x);
&
nbsp;
/* now r[0],r[1],r[2], r[3] has the frame */
/* Tx the periods and the encoded word */
&
nbsp;
TxHexAscii(size);
TxSerial(0x20);
TxHexAscii(med);
TxEnter();
&
nbsp;
for(x=0;x<size; x++)
{
TxHexAscii(buff[x]);
TxSerial(0x20);
}
TxEnter();
&
nbsp;
TxHexAscii(r[0]);
TxHexAscii(r[1]);
TxHexAscii(r[2]);
TxHexAscii(r[3]);
&
nbsp;
TxEnter();
LED = 0;
}
}