#include "config.h"
/***********************
infrared.c文件程序源代碼
*************************/
#include <reg51.h>
sbit IR_INPUT = P1^0; //紅外接收引腳
bit irflag = 0; //紅外接收標(biāo)志,收到一幀正確數(shù)據(jù)后置1
unsigned char ircode[4]; //紅外代碼接收緩沖區(qū)
void InitInfrared(void) //紅外功能的初始化函數(shù)
{
TMOD &= 0x0F; //清零T1的控制位
TMOD |= 0x10; //配置T1為模式1
TR1 = 0; //停止T1計(jì)數(shù)
ET1 = 0; //禁止T1中斷
IT1 = 1; //設(shè)置INT1為負(fù)邊沿觸發(fā)
EX1 = 1; //使能INT1中斷
}
unsigned int GetHighTime(void) //獲取高電平時間
{
TH1 = 0; //清零T1計(jì)數(shù)初值
TL1 = 0;
TR1 = 1; //啟動T1計(jì)數(shù)
while (IR_INPUT) //紅外輸入引腳為1時循環(huán)檢測等待,變?yōu)?時則結(jié)束本循環(huán)
{
if (TH1 >= 0x40)
{ //當(dāng)T1計(jì)數(shù)值大于0x4000,即高電平持續(xù)時間超過約18ms時,
break; //強(qiáng)制退出循環(huán),是為了避免信號異常時,程序假死在這里。
}
}
TR1 = 0; //停止T1計(jì)數(shù)
return (TH1*256 + TL1); //返回T1的計(jì)數(shù)值
}
unsigned int GetLowTime(void) //獲取低電平時間
{
TH1 = 0; //清零T1計(jì)數(shù)初值
TL1 = 0;
TR1 = 1; //啟動T1計(jì)數(shù)
while (!IR_INPUT) //紅外輸入引腳為0時循環(huán)檢測等待,變?yōu)?時則結(jié)束本循環(huán)
{
if (TH1 >= 0x40)
{ //當(dāng)T1計(jì)數(shù)值大于0x4000,即低電平持續(xù)時間超過約18ms時,
break; //強(qiáng)制退出循環(huán),是為了避免信號異常時,程序假死在這里。
}
}
TR1 = 0; //停止T1計(jì)數(shù)
return (TH1*256 + TL1); //返回T1的計(jì)數(shù)值
}
void EXINT1_ISR() interrupt 2 //INT1中斷服務(wù)函數(shù),執(zhí)行紅外接收及解碼
{
unsigned char i, j;
unsigned char byt;
unsigned int time;
//接收并判定引導(dǎo)碼的9ms低電平
time = GetLowTime();
if ((time<7833) || (time>8755)) //時間判定范圍為8.5~9.5ms,
{ //超過此范圍則說明為誤碼,直接退出
IE1 = 0; //退出前清零INT1中斷標(biāo)志
return;
}
//接收并判定引導(dǎo)碼的4.5ms高電平
time = GetHighTime();
if ((time<3686) || (time>4608)) //時間判定范圍為4.0~5.0ms,
{ //超過此范圍則說明為誤碼,直接退出
IE1 = 0;
return;
}
//接收并判定后續(xù)的4字節(jié)數(shù)據(jù)
for (i=0; i<4; i++) //循環(huán)接收4個字節(jié)
{
for (j=0; j<8; j++) //循環(huán)接收判定每字節(jié)的8個bit
{
//接收判定每bit的560us低電平
time = GetLowTime();
if ((time<313) || (time>718)) //時間判定范圍為340~780us,
{ //超過此范圍則說明為誤碼,直接退出
IE1 = 0;
return;
}
//接收每bit高電平時間,判定該bit的值
time = GetHighTime();
if ((time>313) && (time<718)) //時間判定范圍為340~780us,
{ //在此范圍內(nèi)說明該bit值為0
byt >>= 1; //因低位在先,所以數(shù)據(jù)左移,高位為0
}
else if ((time>1345) && (time<1751)) //時間判定范圍為1460~1900us,
{ //在此范圍內(nèi)說明該bit值為1
byt >>= 1; //因低位在先,所以數(shù)據(jù)左移,
byt |= 0x80; //高位置1
}
else //不在上述范圍內(nèi)則說明為誤碼,直接退出
{
IE1 = 0;
return;
}
}
ircode[ i] = byt; //接收完一個字節(jié)后保存到緩沖區(qū)
}
irflag = 1; //接收完畢后設(shè)置標(biāo)志
IE1 = 0; //退出前清零INT1中斷標(biāo)志
}
|