#define IR_STATUS_LOCK 0X01 //红外锁定
#define IR_STATUS_RECEIVE_OK 0X02 //红外接收完成
#define IR_STATUS_KEY_UP 0X04 //红外释放
/*联合体+结构体*/
typedef union
{
u8 Buf[4];
struct
{
u8 User0;//用户码
u8 User1;//用户码反码
u8 Key0;//按键码
u8 Key1;//按键码反码
}IR_Data;
}IR_Type;
/*中断内变量建议使用IDATA*/
idata IR_Type IR_Code;
idata u8 IR_Status;
idata u8 IR_Receive_Bit;
idata u8 IR_Receive_Data[4];
idata u8 IR_L_Time;
idata u8 IR_H_Time;
idata u16 IR_Free_Time;
idata u16 IR_Map;
//中断125us内调用
void IR_Receive()
{
if(IR_Status & IR_STATUS_LOCK)
{
IR_Free_Time++;
if(IR_Free_Time >= 1000)//1000=125ms检测不到引导信号或重发信号,认为红外释放
{
IR_Status ^= (IR_STATUS_LOCK | IR_STATUS_KEY_UP);
}
}
if(IR_IO)
{
IR_H_Time++;
}
else
{
IR_L_Time++;
if(IR_H_Time)
{
if(IR_L_Time >= 60)
{
IR_Free_Time = 0;//接收到引导码或重复码,清除红外释放计数,
IR_Receive_Bit = 0;
if(IR_H_Time >= 30)//3750us
{
//进入此处表示接收到引导码
IR_Map = 0;//映射按键处理方式,为了支持按键快速处理
}
}
else if(IR_H_Time >= 24)
{
IR_Receive_Bit = 0;//减小干扰导致进入接收到32位数据(例如手指碰触接收头塑料)
}
else if(IR_L_Time >= 2)
{
IR_Receive_Data[IR_Receive_Bit >> 3] >>= 1;
if(IR_H_Time >= 9)
{
IR_Receive_Data[IR_Receive_Bit >> 3] |= 0x80; //logic 1
}
IR_Receive_Bit++;
if(IR_Receive_Bit == 32)
{
IR_Receive_Bit = 0;
IR_Status |= (IR_STATUS_RECEIVE_OK | IR_STATUS_LOCK);
IR_Code.Buf[0] = IR_Receive_Data[0];
IR_Code.Buf[1] = IR_Receive_Data[1];
IR_Code.Buf[2] = IR_Receive_Data[2];
IR_Code.Buf[3] = IR_Receive_Data[3];
//BEEP_IO = !BEEP_IO;//测试接收代码点
}
}
IR_H_Time = 0;
IR_L_Time = 0;
}
}
}
//功能:红外按键码的功能处理,调用方式:建议Main中10毫秒处理一次
void IR_Key_Handle()
{
//红外按键释放,一般不用处理
if(IR_Status & IR_STATUS_KEY_UP)
{
IR_Status ^= IR_STATUS_KEY_UP;
IR_Map = 0;//红外按键释放,清除映射
}
//红外按键处理-映射到普通按键处理
if(IR_Status & IR_STATUS_RECEIVE_OK)
{
IR_Status ^= IR_STATUS_RECEIVE_OK;//清除IR接收成功标志
if(IR_Code.IR_Data.User0 != 0x00)
{
return;//用户码判断,如无判断,易被其他遥控误操作
}
if((IR_Code.IR_Data.User0 ^ IR_Code.IR_Data.User1) != 0xff)
{
return;//按照NEC协议,进行用户码反码校验,不通过,退出
}
if((IR_Code.IR_Data.Key0 ^ IR_Code.IR_Data.Key1) != 0xff)
{
return;//按照NEC协议,进行按键码反码校验,不通过,退出
}
IR_Map = KEY_POWER;
// switch(IR_Code.IR_Data.Key0)
// {
// case 0X00F://开关
// IR_Map = KEY_POWER;
// break;
// case 0x40://摇头
// IR_Map = KEY_LR_SWING;
// break;
// case 0x20://+
// IR_Map = KEY_INC;
// break;
// case 0x60://-
// IR_Map = KEY_DEC;
// break;
// case 0x10://定时
// IR_Map = KEY_TIMING;
// break;
// }
}
} |