⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ir_light.c

📁 86型家用无线遥控开关程序源代码
💻 C
字号:

/************************************************************
 *	Processer : Microchip PIC16c56							*

 *	Compiler : 	Hi-TECH PICC 8.01 PL3							*

 *	Writer : 	dulingan										*

 *	Description : 							 					*
 *************************************************************/
#include <pic.h>
#include "ir_light.h"




bit ir_key_ok;
bit f_key_release;

bit led1_status;
bit led2_status;
bit led3_status;
bit f_beep;
bit f_power_key_press;

Byte ir_receive_code[3];
Byte ir_receive_buf[3];
Byte all_status;
Word iic_high_code;


void check_power_key(void);
Word Read(Byte address);



void init_all(void)
{
	TRISA = 0x03;//0x00;			// RA0~3为输出脚,控制继电器
    p_led1 = 1;
    p_led2 = 0;
    p_led3 = 0;
	TRISB = 0x41;//0x59;			//01011001b;  6 ir_port:i,5 beep:o, 4 jump:i, 3 detect:i,  2 clk:o, 1 di:o, 0 do:i
	OPTION = 0x04;			// PS2~PS0: 1:32分频,PSA为TMR0,RTE为低电平触发,RTS信号源为内部时钟

//    f_key_release = TRUE;
    all_status = 2;
    led1_status = ON;
    led2_status = OFF;
    led3_status = OFF;

    ir_key_ok = FALSE;
    f_power_key_press=0;
    p_beep=0;
    clrwdt();
}


bit ir_rec_overflow(void)
{
    if(TMR0 >TIME_14A )
    {
       	return TRUE;
    }
    else
    {
        return FALSE;
    }
}

/*****************************************************************

*** 函数说明:接收1位遥控码子程序

*** 出口参数:ir_code有三种状态,  00: 0  , 01:F,  11: 1  10,出错

******************************************************************/

Byte ir_receive_one_bit(void)
{

	Byte ir_code = 0;
	TMR0 = 0;

    TRISB = 0x41;//0x59;   // 重设端口,防止干扰
	while(!ir_port)
    {
		if(ir_rec_overflow())
        	return ERROR_CODE;
	}
	TMR0 = 0;
	while(ir_port)
    {
		if(ir_rec_overflow())
			return ERROR_CODE;
    }

	if( TMR0>TIME_10A )
	{
		ir_code = 1;
	}
	else
	{
		ir_code = 0;
	}
	ir_code <<= 1;

	TMR0 = 0;
	while(!ir_port)
	{
		if(ir_rec_overflow())
			return ERROR_CODE;
	}

	TMR0 = 0;
	while(ir_port)
	{
		if(ir_rec_overflow())
			return ERROR_CODE;
	}
	if( TMR0>TIME_10A )
	{
		ir_code |= (Byte)1;
	}

	return ir_code;
}

bit wait_syn_bit(void)
{
	Byte buf=0;
	TMR0 = 0;
	while(1)
	{
        clrwdt();
		if(!ir_port)
		{
			 if( TMR0>TIME_110A )
			 {
					return TRUE;
			 }
		}
		else
		{
			buf += TMR0;
			TMR0 = 0;
			if(buf>250)
			{
				return FALSE;
			}
		}
	}
}


bit ir_receive(void)
{
	Byte i;
	TMR0 = 0;
    clrwdt();
	if(!wait_syn_bit())
        return NO_KEY;
    clrwdt();
	while(!ir_port)	// 等待同步位结束,即等待0结束
	{
		if( TMR0 > TIME_130A )	// 如果为0的时间大于130a时,表示没有遥控按下,应该退出
		{
			return NO_KEY;
		}
	}

	for(i=0;i<4;i++)			// 后读16位,共24位
	{
		ir_receive_code[0] <<= 2;
		ir_receive_code[0] |= ir_receive_one_bit();
	}

	for(i=0;i<4;i++)			// 后读16位,共24位
	{
		ir_receive_code[1] <<= 2;
		ir_receive_code[1] |= ir_receive_one_bit();
	}

	for(i=0;i<4;i++)			// 后读16位,共24位
	{
		ir_receive_code[2] <<= 2;
		ir_receive_code[2] |= ir_receive_one_bit();
	}
	return HAVE_KEY;
}

bit ir_receive_key(void)
{
    Byte i;
    clrwdt();
	ir_receive_buf[0] = ir_receive_code[0];
	ir_receive_buf[1] = ir_receive_code[1];
	ir_receive_buf[2] = ir_receive_code[2];


	for(i=0;i<4;i++)
	{
		check_power_key();
		if(!ir_receive())
		{
			return NO_KEY;
		}
		if(ir_receive_buf[0] != ir_receive_code[0] || ir_receive_buf[1] != ir_receive_code[1] || ir_receive_buf[2] != ir_receive_code[2])
		{
			return NO_KEY;
		}
	}
    clrwdt();
	return HAVE_KEY;
}


void ir_key_deal(void)
{
    clrwdt();
	if(ir_key_ok )
	{
		if( (iic_high_code>>8)==ir_receive_code[0] && (iic_high_code&0xff)==ir_receive_code[1] )
		{
		  switch(ir_receive_code[2])	// KEYA
          {
            case KEYA:
				if(led1_status)
					led1_status = 0;
				else
					led1_status = 1;
				p_led1 = led1_status ;
				ir_key_ok = FALSE;
                f_beep = TRUE;
                break;

			case KEYB:
				if(led2_status)
					led2_status = 0;
				else
					led2_status = 1;
				p_led2 = led2_status ;
				ir_key_ok = FALSE;
                f_beep = TRUE;
                break;

			case KEYC:
				if(led3_status)
					led3_status = 0;
				else
					led3_status = 1;
				p_led3 = led3_status ;
				ir_key_ok = FALSE;
                f_beep = TRUE;
                break;
			case KEYD:
				if(led1_status || led2_status || led3_status )
				{
					led1_status=OFF;
					led2_status=OFF;
					led3_status=OFF;
				}
				else
				{
					led1_status=ON;
					led2_status=ON;
					led3_status=ON;
				}
				p_led1 = led1_status;
				p_led2 = led2_status;
				p_led3 = led3_status;
				ir_key_ok = FALSE;
                f_beep = TRUE;
                break;
            default:
                ir_key_ok = FALSE;
                break;
		  }
		}
        else
        {
            ir_key_ok = FALSE;
        }

	}
    clrwdt();
}

void beep(void)
{
	if(f_beep )
	{
		p_beep = HIGH;
	}
	else
	{
		p_beep = LOW;
	}
}


void check_power_key(void)
{
     if(f_power_key_press)
     {
         if(all_status==1)
         {
		      p_led1 = ON;
		      p_led2 = OFF;
		      p_led3 = OFF;
              led1_status = ON;
              led2_status = OFF;
              led3_status = OFF;
         }
         else if(all_status==2)
         {
		      p_led1 = ON;
		      p_led2 = ON;
		      p_led3 = OFF;
              led1_status = ON;
              led2_status = ON;
              led3_status = OFF;
         }
         else if(all_status==3)
         {
		      p_led1 = ON;
		      p_led2 = ON;
		      p_led3 = ON;
              led1_status = ON;
              led2_status = ON;
              led3_status = ON;
         }
         all_status++;
         if(all_status>3)
         {
              all_status = 1;
         }
         f_power_key_press = FALSE;
     }
     else
     {
          while(!p_power_off)  // 关掉电
          {
               led1_status = OFF;
               led2_status = OFF;
               led3_status = OFF;
               p_led1 = led1_status;
		       p_led2 = led2_status;
		       p_led3 = led3_status;
               f_power_key_press = TRUE;
               clrwdt();
          }
     }
}

// Write enable must precede all programming modes.
void Ewen(void)
{
	Byte temp,InData;
	CS=0;
	CLK=0;
	CS=1;

    DI = 1;
    CLK = 1;CLK=1;CLK=1;
    nop();nop();nop();
    CLK=0;

	InData=0x30; // 10011XXXXX
	for(temp=0;temp<8;temp++)
	{
        if(InData&0x80)
            DI = 1;
        else
            DI = 0;
		//DI=InData&0x80;
		CLK=1;CLK=1;CLK=1;
		nop();
		nop();
		CLK=0;
		InData<<=1;
	}
	CS=0;
}

// Disables all programming instructions.
void Ewds(void)
{

	Byte temp,InData;
	CS=0;
	CLK=0;
	CS=1;

    DI = 1;
    CLK = 1;CLK=1;CLK=1;
    nop();nop();nop();
    CLK = 0;

	InData=0; // 10000XXXXX
	for(temp=0;temp<8;temp++)
	{
		//DI=InData&0x80;
        if(InData&0x80)
            DI = 1;
        else
            DI = 0;
		CLK=1;CLK=1;CLK=1;
		nop();
		nop();
		CLK=0;
		InData<<=1;
	}
	CS=0;
}

// Reads data stored in memory, at specified address.
Word Read(Byte address)
{
	Byte temp;
	Word result;
	Ewen();
	CS=0;
	CLK=0;
 	nop();
	nop();
	CS=1;

	DI=1; // 110 A5-A0
	CLK=1;CLK=1;CLK=1;
	nop();
	nop();
	CLK=0; // 1

	address=(address&0x3f)|0x80;
	for(temp=0;temp<8;temp++)
	{
		if(address&0x80)
            DI = 1;
        else
            DI = 0;
		CLK=1;CLK=1;CLK=1;
		nop();
		nop();
		CLK=0;
		address<<=1;
	}
	nop();
	nop();

    result = 0;
	for(temp=0;temp<16;temp++)
	{
    	result <<= 1;
		CLK=1;CLK=1;CLK=1;
        nop();nop();nop();
		CLK=0;
        if(DO==1)
            result |= 0x01;
	}
	CS=0;
	Ewds();
	return(result);
}

// Writes memory location An - A0.
void Write(Byte address,Word InData)
{
	Byte temp;
	Ewen();
	CLK=0;
	CS=0;
	nop();
	nop();
	CS=1;


	DI=1; // 101 A5-A0
	CLK=1;CLK=1;CLK=1;
	nop();
	nop();
	CLK=0; // 1

	address=address&0x3f|0x40;
	for(temp=0;temp<8;temp++)
	{
		if(address&0x80)
            DI = 1;
        else
            DI = 0;
		CLK=1;CLK=1;CLK=1;
		nop();
		nop();
		CLK=0;
		address<<=1;
	}

	for(temp=0;temp<16;temp++)
	{
		if(InData&0x8000)
            DI = 1;
        else
            DI = 0;
		CLK=1;CLK=1;CLK=1;
		nop();
		nop();
		CLK=0;
		InData<<=1;
	}
	CS=0;
    TRISB = 0x40;//0x58
    nop();nop();nop();nop();nop();
    DO=1;
    TRISB = 0x41;//0x59;

	nop();
	nop();
	CS=1; CLK=1;
	while(DO==0)
	{ // busy test
		CLK=0;
		nop();
		nop();
		CLK=1;
	}
	CLK=0; CS=0;
	Ewds();
}



//不按遥控时,每个循环时间为100ms,按遥控时300ms
void main(void)
{
    Byte release_time;

	init_all();
    for(release_time=0;release_time<250;release_time++);
    init_all();



    if(!p_jump)
    {
		while(!ir_receive_key())
			continue;

        iic_high_code = ir_receive_code[0];
        iic_high_code<<= 8;
        iic_high_code+= ir_receive_code[1];
		Write(0x10,iic_high_code);				// 高位地址码,共三位

		f_beep = TRUE;
        clrwdt();
    }
    else
    {
	    iic_high_code=Read(0x10);
        nop();
    }


	while(1)
	{
	    iic_high_code=Read(0x10);
        nop();

        if(ir_receive_key())
        {
            if(f_key_release)
            {
                ir_key_ok = TRUE;

                f_key_release = FALSE;
            }
            release_time=0;
        }
        else
        {
            release_time++;
            if(release_time>10 )      // 灵敏度调节
            {
			     f_key_release = TRUE;
                 f_beep = FALSE;
            }
        }

		ir_key_deal();
        check_power_key();
        check_power_key();
		beep();
        clrwdt();
	}
}









⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -