//うたた寝タイマー
//製作者：KK
//2012/7/30

//使用リモコンコード：シャープ


#include<16f716.h>
#fuses HS,NOWDT,NOBROWNOUT,NOPROTECT,NOPUT
#use delay(clock=20000000)		//20MHz//

//ポート定義
#byte RA=5
#byte RB=6

#bit SEN1 = RB.0		//圧力センサ
#bit SEN2 = RB.3		//赤外線受信モジュール
#bit LED1 = RA.0		//赤色LED
#bit LED2 = RA.2		//黄色LED
#bit SW1 = RA.1			//赤色スイッチ
#bit SW2 = RA.3			//黄色スイッチ
#bit IR_LED = RB.4		//赤外線LED
#bit TGSW1 = RA.4		//トグルスイッチ１
#bit TGSW2 = RB.5		//トグルスイッチ２

//関数宣言
void Send_cord(unsigned long);

//定義文
#define	SHAPE1	0x555A		/*メーカーコード前半*/
#define	SHAPE2	0xF148		/*メーカーコード後半*/

#define	POWER	0x688b		/*電源ボタン*/

#define	TGSW	((!TGSW2 << 1) | !TGSW1)

/*実測からの値修正あり*/
#define	READER_H	2150	/*(200ns * 8) * 2150 = 3.44ms*/
#define	READER_L	1013	/*(200ns * 8) * 2150 = 1.7ms*/
#define	H_CORD		775		/*(200ns * 8) * 750 = 1.2ms*/
#define	L_CORD		250		/*(200ns * 8) * 250 = 400us*/
#define	HI_TIM		250		/*(200ns * 8) * 300 = 480us*/

//変数宣言
unsigned long cnt1 = 0;
unsigned int sec_cnt = 0;
unsigned int min_cnt = 0;
unsigned int tim = 0;
unsigned char timer_flag = 0;

/*==========================================*/
/*	メイン関数									*/
/*==========================================*/
void main(void){
	//ポート入出力設定
	set_tris_a(0x1A);
	set_tris_b(0x29);
	
	//TIMER0設定
	setup_timer_0(RTCC_INTERNAL | RTCC_DIV_16);
	set_timer0(100);
	
	//TIMER1設定
	setup_timer_1(T1_INTERNAL | T1_DIV_BY_8);
	set_timer1(0);
	
	//割り込み許可
	enable_interrupts(INT_TIMER0);
	enable_interrupts(GLOBAL);
	
	//初期化
	RA = 0x00;
	RB = 0x00;
	
	while(TRUE){
		
		/*タイマー時間設定 DIPSWにより変化*/
		switch (TGSW & 0x03){
			case 0:tim = 1;break;	/*1分*/
			case 1:tim = 10;break;	/*10分*/
			case 2:tim = 30;break;	/*30分*/
			case 3:tim = 60;break;	/*60分*/
			default:tim = 10;break;
		}
				
		/*うたた寝タイマON/OFF*/
		if (!SW2){
			Delay_ms(20);
			while (!SW2);
			LED2 = ~LED2;
			timer_flag = ~timer_flag;
			Delay_ms(50);
		}	
		LED2 = timer_flag;	/*LED2へモード状態反映*/

		/*カウンタクリア*/
		if (!SW1){
			cnt1 = 0;
			sec_cnt = 0;
			min_cnt = 0;
		}
		
		/*1minカウンタ*/
		if (sec_cnt >= 60){
			sec_cnt = 0;
			min_cnt++;
		}
		
		/*指定時間経過後、蛍光灯消灯*/
		if (min_cnt >= tim){
			min_cnt = 0;
			/*周囲が暗くなるまで信号送信*/
			while (SEN2){
				Send_cord(POWER);
				Delay_ms(500);
			}
			/*うたた寝タイマOFF*/
			timer_flag = 0;
		}
		
		/*タイマー残り時間１分以下でLED1点灯*/
		if ((tim - min_cnt) <= 1){
			LED1 = 1;
		}else{
			LED1 = 0;
		}		
	}
}

/*==========================================*/
/*	リモコン信号送信関数 メーカーコード：シャープ		*/
/*==========================================*/
void Send_cord(unsigned long ext_data)
{
	signed char data_cnt = 0;
	
	/*リーダ部送信*/
	set_timer1(0);
	IR_LED = 1;
	while (get_timer1() <= READER_H){
	}
	
	set_timer1(0);
	IR_LED = 0;
	while (get_timer1() <= READER_L){
	}
	
	set_timer1(0);
	IR_LED = 1;
	while (get_timer1() <= HI_TIM){
	}
	
	/*メーカーコード送信(前半2byte)*/
	for (data_cnt = 15 ; data_cnt >= 0 ; data_cnt--){
		set_timer1(0);
		IR_LED = 0;
		
		if (((SHAPE1 >> data_cnt) & 0x01) != 0){
			
			while (get_timer1() <= H_CORD){
			}
			
		}else{
		
			while (get_timer1() <= L_CORD){
			}
			
		}
		
		set_timer1(0);
		IR_LED = 1;
		while (get_timer1() <= HI_TIM){
		}	
		
	}
	
	/*メーカーコード送信(後半2byte)*/
	for (data_cnt = 15 ; data_cnt >= 0 ; data_cnt--){
		set_timer1(0);
		IR_LED = 0;
		
		if (((SHAPE2 >> data_cnt) & 0x01) != 0){
			
			while (get_timer1() <= H_CORD){
			}
			
		}else{
		
			while (get_timer1() <= L_CORD){
			}
			
		}
		
		set_timer1(0);
		IR_LED = 1;
		while (get_timer1() <= HI_TIM){	
		}	
		
	}
	
	/*データ送信*/
	for (data_cnt = 15 ; data_cnt >= 0 ; data_cnt--){
		set_timer1(0);
		IR_LED = 0;
		
		if (((ext_data >> data_cnt) & 0x01) != 0){
			
			while (get_timer1() <= H_CORD){
			}
			
		}else{
		
			while (get_timer1() <= L_CORD){
			}
			
		}
		
		set_timer1(0);
		IR_LED = 1;
		while (get_timer1() <= HI_TIM){
		}	
		
	}
	
	/*赤外LED OFF*/
	IR_LED = 0;
}

	
/*==========================================*/
/*	タイマ0割り込み 0.5ms						*/
/*==========================================*/
#int_timer0
void tmr0(void)
{
	set_timer0(100);
	
	/*圧力センサ反応　＆　うたた寝タイマON時 タイマー起動*/
	if (timer_flag & !SEN1){
		cnt1++;
		/*1sカウンタ*/
		if (cnt1 >= 2000){
			cnt1 = 0;
			sec_cnt++;
		}	
	}else{
		cnt1 = 0;
		sec_cnt = 0;
		min_cnt = 0;
	}
}

