/* * IR reception * 05/Sep/1999 JLS & CAE * jls at certi.ufsc.br * cae at certi.ufsc.br * CC5xFree v3.0E (www.bknd.com) * use CC1B for SX */ /* Sony Data format: 12 bits Bit zero: 400 +--+ +... | | | + +---+ 800 Bit one: 400 +--+ +... | | | + +------+ 1400 Frame: 400 400 --+ +--+ +--+ +--+ | | | | | | | +---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 _sx28_ #include #ifdef _12C508_ bit _TxOUT @ GP0; bit RxD_pin @ GP1; bit IR_input @ GP2; #else #define RP0 STATUS.5 #pragma update_RP 0 /* 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 #ifdef _sx28_ unsigned char x,y; bank0 unsigned char r[4]; bank0 unsigned char med,min,max,rxBuf; bank1 unsigned char buff[16]; bank2 unsigned char buff2[16]; #else unsigned char x,y,med,min,max,rxBuf; unsigned char r[4]; unsigned char buff[16]; unsigned char buff2[16]; #endif void TxSerial (unsigned char txBuf); /*--------------------------------------------------------------------------*/ void TxEnter (void) { /*--------------------------------------------------------------------------*/ TxSerial(0xD); TxSerial(0xA); } /*--------------------------------------------------------------------------*/ void TxHexAscii (unsigned char in) { /*--------------------------------------------------------------------------*/ unsigned char Hex; Hex = swap(in); // 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; // start bit for (idx=10; idx; idx--) // 3us { _TxOUT = Carry; // 4us Delay_uSeg(28); // 91us (28*3+7) Carry = 1; // 1us txBuf = rr(txBuf); // 1us nop(); // 1us } // 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; // 5.135 ms timeout idx = 0; while (1) { while (RxD_pin) // input "high" { if ((-- idx)==0) { if ((-- rxBuf)==0) { Carry = 0; return; } } } Delay_uSeg(14); // 1/2 bit delay (14*3+7) if (RxD_pin) continue; // false start bit detection rxBuf = 0x80; // 8 bits counter and reception buffer nop(); nop(); // timming adjustment 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(); // timming adjustment Carry = RxD_pin; // stop bit read return; // 100 us availiable } } /*--------------------------------------------------------------------------*/ void main (void) { /*--------------------------------------------------------------------------*/ #ifdef _12C508_ // OSCCAL = W; // OscCal Value - OTP part OSCCAL = 0xB0; // OscCal Value - Windowed part GPIO = 0x00; TRIS = 0x08; // GP3 input #endif #ifdef _sx28_ #pragma config &= 0b11010011 // reg 1 = RTCC, no int on RTCC, RTCC internal, prescale, 1:16 PORTA = 0; PORTB = 0; DDRA = DEF_TRISA; DDRA = DEF_TRISB; PA0 = 0; PA1 = 0; PA2 = 0; #endif #ifdef _16f84_ INTCON = 0; // no interrupts PCLATH = 0; // bank 0 PORTA = 0; PORTB = 0; TRISA = DEF_TRISA; TRISB = DEF_TRISB; RP0 = 1; // RAM bank 1 RP0 = 0; // RAM bank 0 #endif while (1) { /* set vars to start */ min = 255; // min period max = 0; // max period y = 0; // pointer to buffer x = 12; // only 12 bits /* start bit management */ while (IR_input==1); // wait for 0 /* 2600us start bit */ while (IR_input==0); // wait for 1 TMR0 = 0; // start counter do { // buff[y] = 0; // buff2[y] = 0; /* measure high pulse */ while (TMR0==0); // wait TMR0 advance while (IR_input==1) // wait for 0 { if (TMR0==0) // timer overflow (4096us) ? goto frame_end ; // yes, exit } buff[y] = TMR0; // store period med = TMR0; // save high period TMR0 = 0; // start counter /* measure low pulse */ while (TMR0==0); // wait TMR0 advance while (IR_input==0); // wait for 1 buff2[y] = TMR0; // store period med += TMR0; // total period TMR0 = 0; // start counter if (med>=max) max = med; // find max if (med=med) r[3]++; } while (y); /* now r[0],r[1],r[2], r[3] has the frame */ /* Tx the periods and the encoded word */ TxHexAscii(x*2); //size TxSerial(0x20); TxHexAscii(med); TxEnter(); for(y=0;y