- void IR_IN() interrupt 0 using 0 //采用12MHz晶振
- {
- unsigned char j,k,N=0;
- EX0 = 0; //初始化,关闭外中断
- delay(15);
- if (IRIN==1) //没有脉冲到来高电平
- { EX0 =1; //默认状态下开中断,寻找9ms引导脉冲
- return;
- }
- //确认IR信号出现
- while (!IRIN) //等IR变为高电平,跳过9ms的前导低电平信号。
- {delay(1);} //单片机接收电平与遥控器电平完全相反,delay(1)延时0.14ms
-
- for (j=0;j<4;j++) //收集四组数据
- {
- for (k=0;k<8;k++) //每组数据有8位
- {
- while (IRIN) //等 IR 变为低电平,跳过4.5ms的前导高电平信号。
- {delay(1);}
- while (!IRIN) //等 IR 变为高电平(0.56ms)
- {delay(1);}
- while (IRIN) //计算IR高电平时长
- {
- delay(1);
- N++;
- if (N>=14) //大于1.685ms高电平长度,为了保证可靠性N=14
- { EX0=1; //(2.25/0.14=16,1.685/0.14=12,0.565/0.14=4)
- return;} //0.14ms计数过长自动离开,重新判断。
- } //高电平计数完毕
- IRCOM[j]=IRCOM[j] >> 1; //数据最高位补“0”
- if (N>=6) {IRCOM[j] = IRCOM[j] | 0x80;} //大于0.565ms高电平长度,N=6,7,8(1.685/2)都行,判断为“1”,数据最高位补“1”
- N=0;
- }//end for k
- }//end for j
-
- if (IRCOM[2]!=~IRCOM[3]) 数据码与数据反码相反,继续执行,否则,数据出错。返回,重新判断。
- { EX0=1;
- return; }
-
- IRCOM[5]=IRCOM[2] & 0x0F; //取键码的低四位
- IRCOM[6]=IRCOM[2] >> 4; //右移4次,高四位变为低四位
-
- if(IRCOM[5]>9)
- { IRCOM[5]=IRCOM[5]+0x37;} //转换成相应的ASCII码,送1602显示。
- else
- IRCOM[5]=IRCOM[5]+0x30;
-
- if(IRCOM[6]>9)
- { IRCOM[6]=IRCOM[6]+0x37;}
- else
- IRCOM[6]=IRCOM[6]+0x30;
-
- lcd_pos(0x4b);
- lcd_wdat(IRCOM[6]); //第一位数显示
- lcd_pos(0x4c);
- lcd_wdat(IRCOM[5]); //第二位数显示
-
- beep();
- EX0 = 1; //开中断,继续判断
- }
|