#define IR_STATUS_LOCK 0X01 //紅外鎖定
#define IR_STATUS_RECEIVE_OK 0X02 //紅外接收完成
#define IR_STATUS_KEY_UP 0X04 //紅外釋放
/*聯(lián)合體+結構體*/
typedef union
{
u8 Buf[4];
struct
{
u8 User0;//用戶碼
u8 User1;//用戶碼反碼
u8 Key0;//按鍵碼
u8 Key1;//按鍵碼反碼
}IR_Data;
}IR_Type;
/*中斷內(nèi)變量建議使用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內(nèi)調(diào)用
void IR_Receive()
{
if(IR_Status & IR_STATUS_LOCK)
{
IR_Free_Time++;
if(IR_Free_Time >= 1000)//1000=125ms檢測不到引導信號或重發(fā)信號,認為紅外釋放
{
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;//接收到引導碼或重復碼,清除紅外釋放計數(shù),
IR_Receive_Bit = 0;
if(IR_H_Time >= 30)//3750us
{
//進入此處表示接收到引導碼
IR_Map = 0;//映射按鍵處理方式,為了支持按鍵快速處理
}
}
else if(IR_H_Time >= 24)
{
IR_Receive_Bit = 0;//減小干擾導致進入接收到32位數(shù)據(jù)(例如手指碰觸接收頭塑料)
}
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;
}
}
}
//功能:紅外按鍵碼的功能處理,調(diào)用方式:建議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協(xié)議,進行用戶碼反碼校驗,不通過,退出
}
if((IR_Code.IR_Data.Key0 ^ IR_Code.IR_Data.Key1) != 0xff)
{
return;//按照NEC協(xié)議,進行按鍵碼反碼校驗,不通過,退出
}
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;
// }
}
} |