//클럭을 22.1184MHz를 사용하여 리모콘 신호를 만들었습니다. 
#include <reg51.h> 

#define LED P0	//LED가 연결되어 있는 8051의 포트를 설정

sbit IR_LED = P3^7;	// 리모콘 LED를 제어하기 위한 변수 
sbit BUZZ = P2^0;	//부져를 제어하기 위한 변수 

//삼성 TV 리모콘 숫자키(0~9)에 대한 헥사코드 , 데이터 포맷 참조
//이값들은 변하지 않는 값이기 때문에 Flash  메모리에 저장될 수 있도록 code 로 선언
code unsigned char ir_num_data[10]={0x11, 0x04, 0x05, 0x06, 0x08, 0x09, 0x0A, 0x0C, 0x0D, 0x0E};  

unsigned char ir_tx_data[4];//송신하기 위한 리모콘 데이터 

unsigned char i, j;

void delay( unsigned int d_cnt )
{
	while(d_cnt--);
}

//4.5msec 동안 High를 송신하고 4.5msec 동안 Low를 송신
void ir_lead_code(void)
{
	//주파수 37.91kHz(주기: 26.378usec)로 신호 전송
	for(i=0; i<172; i++){//4.5msec
		IR_LED = 1;// 주파수를 맞추기 위하여 1을 반복했다. 
		IR_LED = 1;// 반복하여 8.79usec
		IR_LED = 1;
		IR_LED = 1;
		IR_LED = 1;
		IR_LED = 1;
		IR_LED = 1;
		IR_LED = 1;
		IR_LED = 1;
		IR_LED = 1;
		IR_LED = 1;
		IR_LED = 1;
		IR_LED = 1;
		IR_LED = 1;
		IR_LED = 1;
		IR_LED = 1;
		IR_LED = 0;// 주파수를 맞추기 위하여 0을 반복했다. 
		IR_LED = 0;
		IR_LED = 0;
		IR_LED = 0;
		IR_LED = 0;
		IR_LED = 0;
		IR_LED = 0;
		IR_LED = 0;
		IR_LED = 0;
		IR_LED = 0;
		IR_LED = 0;
		IR_LED = 0;
		IR_LED = 0;
		IR_LED = 0;
		IR_LED = 0;
		IR_LED = 0;
		IR_LED = 0;
		IR_LED = 0;
		IR_LED = 0;
		IR_LED = 0;
		IR_LED = 0;
		IR_LED = 0;
		IR_LED = 0;
		IR_LED = 0;
	}
	//신호가 Low 인 경우 
	delay(690);//4.5msec
}

//ir singal end
void ir_end_code(void)
{
	//주파수 37.91kHz(주기: 26.378usec)로 신호 전송
	for(i=0; i<20; i++){ 
		IR_LED = 1;// 주파수를 맞추기 위하여 1을 반복했다. 
		IR_LED = 1;// 반복하여 8.79usec
		IR_LED = 1;
		IR_LED = 1;
		IR_LED = 1;
		IR_LED = 1;
		IR_LED = 1;
		IR_LED = 1;
		IR_LED = 1;
		IR_LED = 1;
		IR_LED = 1;
		IR_LED = 1;
		IR_LED = 1;
		IR_LED = 1;
		IR_LED = 1;
		IR_LED = 1;
		IR_LED = 0;// 주파수를 맞추기 위하여 0을 반복했다. 
		IR_LED = 0;
		IR_LED = 0;
		IR_LED = 0;
		IR_LED = 0;
		IR_LED = 0;
		IR_LED = 0;
		IR_LED = 0;
		IR_LED = 0;
		IR_LED = 0;
		IR_LED = 0;
		IR_LED = 0;
		IR_LED = 0;
		IR_LED = 0;
		IR_LED = 0;
		IR_LED = 0;
		IR_LED = 0;
		IR_LED = 0;
		IR_LED = 0;
		IR_LED = 0;
		IR_LED = 0;
		IR_LED = 0;
		IR_LED = 0;
		IR_LED = 0;
	}
}

//0일때 0.56msec High, 0.56msec Low
//1일때 0.56msec High, 1.69msec Low
void ir_byte_tx(unsigned char ir_data)
{
	unsigned char bit_cnt;
	
	for(bit_cnt=0; bit_cnt<8; bit_cnt++)
	{
		//주파수 37.91kHz(주기: 26.378usec)로 신호 전송
		for(i=0; i<21; i++){//0.56msec 
		IR_LED = 1;// 주파수를 맞추기 위하여 1을 반복했다. 
		IR_LED = 1;// 반복하여 8.79usec
		IR_LED = 1;
		IR_LED = 1;
		IR_LED = 1;
		IR_LED = 1;
		IR_LED = 1;
		IR_LED = 1;
		IR_LED = 1;
		IR_LED = 1;
		IR_LED = 1;
		IR_LED = 1;
		IR_LED = 1;
		IR_LED = 1;
		IR_LED = 1;
		IR_LED = 1;
		IR_LED = 0;// 주파수를 맞추기 위하여 0을 반복했다. 
		IR_LED = 0;
		IR_LED = 0;
		IR_LED = 0;
		IR_LED = 0;
		IR_LED = 0;
		IR_LED = 0;
		IR_LED = 0;
		IR_LED = 0;
		IR_LED = 0;
		IR_LED = 0;
		IR_LED = 0;
		IR_LED = 0;
		IR_LED = 0;
		IR_LED = 0;
		IR_LED = 0;
		IR_LED = 0;
		IR_LED = 0;
		IR_LED = 0;
		IR_LED = 0;
		IR_LED = 0;
		IR_LED = 0;
		IR_LED = 0;
		IR_LED = 0;
		}
		//신호가 Low 인 경우 
		delay(84);//0.56msec 

		if(ir_data&0x01) delay(170); // 비트가 1일때 시간 지연을 더한다.
		ir_data >>= 1;
	}	
}

// 리모콘 데이터를 송신한다. 
void ir_data_tx(unsigned char ir_num)
{
	ir_lead_code();
	ir_byte_tx(0x07);	//삼성 TV 리모콘 custom code0
	ir_byte_tx(0x07);	//삼성 TV 리모콘 custom code1	
	ir_byte_tx(ir_num);	//data code0	
	ir_byte_tx(~ir_num);//data code1, data code0의 비트 반전된 데이터이다.
	ir_end_code();	//리모콘 데이터의 마지막을 표시하기 위해
}


void main(void)
{
	unsigned char i_cnt, ir_temp;
	
	IR_LED = 0;//리모콘은 초기에 Off 되어 있어야 한다. 
	BUZZ = 0;
	
	while(1)
	{
		//리모콘 0~9까지의 버튼을 순서대로 보내는 프로그램
		for(ir_temp=0;ir_temp<10;ir_temp++){   
			LED = ir_temp;//보낼 데이터를 LED로 표시합니다.
			BUZZ = 1;
			ir_data_tx(ir_num_data[ir_temp]);//리모콘 데이터를 전송 	
			BUZZ = 0;

			//리모콘 신호를 한번 보낼때 마다 시간 지연
			for(i_cnt=0; i_cnt<7; i_cnt++) delay(60000);
		}//end of for
	}//end of while(1)
}


