PICで赤外線の送受信

#include <pic.h>

__CONFIG(
	MCLRDIS
  & PWRTEN
  & BORDIS
  & UNPROTECT
  & WDTDIS
  & LVPDIS
  & INTIO
  );

__IDLOC(628A);

#define _XTAL_FREQ 8000000

#define IR_SW GPIO0
#define IR_IN GPIO2
#define IR_OUT GPIO4
#define IR_LED GPIO5

#define IR_MAX 16
unsigned char ir_sig[IR_MAX];
unsigned char ir_readh;
unsigned char ir_readl;
unsigned char ir_turn;
unsigned char ir_sigh;
unsigned char ir_sigl;

//SCT TX Emulator
#define SCI_TX GPIO1
#define SCI_TM 206 //1200bps@8MHz
#define SCI_TX_BN 11
#define debug(s,d) \
  puts(s); \
  putui(d,3); \
  putch('\n')
unsigned char tx_bit;
unsigned char tx_buf;
bit tx_next;

void putch(char c) {
 tx_next = 0;
 tx_buf = c;
 tx_bit = SCI_TX_BN;	
 do{
	 while(TMR1L < SCI_TM);
	 SCI_TX = tx_next;
	 TMR1L = 0;
	 tx_next = tx_buf & 1;
	 tx_buf = (tx_buf >> 1) | 0x80;
	} while (--tx_bit);
}	

void puts(const unsigned char *s) {
	while(*s) putch(*s++);
}

void puthc(unsigned char d){
  const unsigned char hc[] =
  {
    '0','1','2','3',
    '4','5','6','7',
    '8','9','A','B',
    'C','D','E','F'
   };
  putch(hc[d >> 4]);
  putch(hc[d & 0b00001111]);
}		

void putui(unsigned int ui, unsigned char d) {
	  unsigned char i;
	  unsigned char buf[5];
	  for(i=0;i<5;i++)
		  buf[i] = ' ';

      i = 4;
      do {
	      buf[i] = (ui % 10) + '0';
	      ui = ui / 10;
	      i--;
	  } while(ui > 0);
	  
	  for(i = (5-d); i< 5; i++)
		  putch(buf[i]);
}

void ir_shot(unsigned int t){
	while(t--){
		IR_OUT = 1;
		if(ir_readh < 100)
		  _delay(15); //37.9kHz 48.8%
		else 
		  _delay(8); //37.9kHz 33.4%
		IR_OUT = 0;
		if(if_readh < 100)
		  _delay(1);
		else
		  _delay(10);
	}
	TMR0 = 0;
}		  
	  
void main(void){
	unsigned char i;
	unsigned char bn;
	unsigned char sn;
	unsigned char sp;
	unsigned char tl,ts;
	unsigned char hl,hs;
	unsigned char ll,ls;
	unsigned int cu;
	
	OSCCON = 0b01110000; //8MHz
	OSCTUNE = 0;
	CMCON0 = 0b00000111;
	ANSEL = 0;
	
	//IR initialize
	OPTION = 0b00000110; // 1/128
    WPU = 0b00000111;
    TRISIO0 = 1; //SW
    TRISIO2 = 1; //IN
    TRISIO4 = 0; //OUT
    TRISIO5 = 0; //LED
    
	IR_LED = 1;
	IR_OUT = 0;
	tl = 0; ts = 255;
	hl = 0; hs = 255;
	ll = 0; ls = 255;
	for(i=0;i<IR_MAX;i++)
	  ir_sig[i] = 0;
	
	//SCI initialize
	T1CON = 0b00110001;// 1/8
	TRISIO1 = 0; // SCI TX
	SCI_TX = 1;
	
	if(IR_SW == 0){
	 //Display for debug
	 puts("\nIR catch ready..\n");
	 
	 //Reader detect
	 TMR0 = 0;
	 while(TMR0 < 40)
	   if(IR_IN) TMR0 = 0;
	 while(IR_IN == 0);
	 ir_readh = TMR0;
 	 
     TMR0 = 0;
     while(IR_IN);
     ir_readl = TMR0;
     OPTION = 0b00000011; // 1/16
     
     //Signal analize
     for(i=0;i<IR_MAX;i++){
	     for(bn = 0;bn<8;bn++){
		     TMR0 = 0;
		     while(IR_IN == 0);
		     ir_turn = TMR0;
		     TMR0 = 0;
		     if(ir_turn > tl) tl = ir_turn;
		     else if(ir_turn < ts) ts = ir_turn;
		     
		     while(IR_IN && (TMR0 < 240));
		     sp = TMR0;
		     if(sp >= 240) break;
		     ir_sig[i] << 1;
		     if(sp > 100) {
			     ir_sig[i] |= 1;
			     if(sp > hl) hl = sp;
			     else if(sp < hs) hs = sp;
			 } else {
			   if(sp > ll) ll = sp;
			   else if(sp < ls) ls = sp;
			 }
		  }
		     
		  if(sp >= 240) break; 
		 }
		sn = i;
		ir_turn = (tl + ts) >> 1;
		ir_sigh = (hl + hs) >> 1;
		ir_sigl = (ll + ls) >> 1;
		
		IR_LED = 0; //LED ON
		
		//Output for debug
		puts("Format = ");
		if(ir_readh < 100)
		  puts("Kaden kyokai\n");
		else 
		  puts("NEC\n");
		debug("Signal count = ",sn);
		debug("Reader H/8 = ",ir_readh);
		debug("Reader L/8 = ",ir_readl);
		debug("Tern max = ",tl);
		debug("Tern min = ",ts);
		debug("Tern avg = ", ir_turn);
		debug("Signal H max = ",hl);
		debug("Signal L max = ",hs);
		debug("Signal H avg = ",ir_sigh);
		debug("Signal L max = ",ll);
		debug("Signal L min = ",ls);
		debug("Signal L avg = ",ir_sigl);
		for(i = 0;i < sn;i++){
			puts("Data");
			putui(i,2);
			puts(" = ");
			puthc(ir_sig[i]);
			putch('\n');
		}
		
		//EEPROM write
		eeprom_write(0,sn);
		eeprom_write(1,ir_readh);
		eeprom_write(2,ir_readl);
		eeprom_write(3,ir_turn);
		eeprom_write(4,ir_sigh);
		eeprom_write(5,ir_sigl);
		for(i = 0;i < sn;i++)
		  eeprom_write(i + 6,ir_sig[i]);
		  
		IR_LED = 1; //LED OFF
      }
      
      while(IR_SW == 0);
      
      //EEPROM read
      sn = eeprom_read(0);
      ir_readh = eeprom_read(1);
      ir_readl = eeprom_read(2);
      ir_turn = eeprom_read(3);
      ir_sigh = eeprom_read(4);
      ir_sigl = eeprom_read(5);
      for(i=0;i<sn;i++)
        ir_sig[i] = eeprom_read(i+6);
      
      OPTION = 0b00000011; // 1/16
      
      //Calculation
      cu = ir_readh * 623;
      ir_readh = cu >> 8;
      cu = ir_turn * 78;
      ir_turn = cu >> 8;
      
      while(1) {
	      while(IR_SW == 0);
	      while(IR_SW);
	      
	      //Make reader
	      ir_shot(ir_readh);
	      while(TMR0 < ir_readl);
	      
	      //Make signal
	      for(i=0;i<sn;i++){
		    for(bn=0;bn<8;bn++){ 
		      ir_shot(ir_turn);
		      if( (ir_sig[i] &(0x80 >> bn) ) > 0)
           		 while(TMR0< ir_sigh);
		      else
		         while(TMR0 < ir_sigl);
		     }
		   }
       }
}