可以参考下下面的代码,定时器1里面定时检测接收,接收到后把数据保存在RxDataBuf
/*************************************************************
// 函数名 :void Timer1()interrupt 3
// 功能 :定时器1中断服务函数
// 参数 :无
// 返回值 :无
// 备注 :检测红外通讯,并获取通讯内容
*************************************************************/
void Timer1()interrupt 3
{
INT8U bitdata=0;
if(Timer60msFlag)
{
Timer60ms++;
if(Timer60ms>65)
{
Timer60ms = 0;
Timer60msFlag = 0;
}
}
else
{
PraState=NowState;
NowState=Infrared;
if(DownUpFlag==0) //还没有检测到下降沿,进行下降沿的检测
{
TH1=(8192-4000)/32;
TL1=(8192-4000)%32; //4000*0.25us=1MS中断一次
if(PraState&!NowState)
{
_nop_();
_nop_();
if(!Infrared){bitdata++;}
_nop_();
_nop_();
if(!Infrared){bitdata++;}
_nop_();
_nop_();
if(!Infrared){bitdata++;}
if(bitdata>>1) //确定是下降沿,置起下降沿标志
{
DownUpFlag = 1;
HighLevelCount = 0; //将高电平个数清0
LowLevelCount = 0; //低电平个数清零
return;
}
}
}
else if(DownUpFlag==1) //检测到下降沿以后检测低电平时间长度
{
TH1=(8192-4000)/32;
TL1=(8192-4000)%32; //4000*0.25us=1MS中断一次
if(!Infrared){bitdata++;}
_nop_();
_nop_();
if(!Infrared){bitdata++;}
_nop_();
_nop_();
if(!Infrared){bitdata++;}
if(bitdata>>1) //确定是低电平
{
LowLevelCount++;
if(LowLevelCount>=6) //如果检测到6MS以上的低电平就认为是起始信号
{
HighLevelCount = 0; //将高电平个数清0
LowLevelCount = 0; //低电平个数清零
DownUpFlag = 2;
return;
}
}
else //如果是高电平
{
HighLevelCount++;
if(HighLevelCount>=2) //如果在检测到下降沿以后,6次低电平之前检测到2次高电平,则本次下降沿就作废
{
HighLevelCount = 0; //将高电平个数清0
LowLevelCount = 0; //低电平个数清零
DownUpFlag = 0;
return;
}
}
}
else if(DownUpFlag==2) //如果DownUpFlag等于2就说明9MS低电平检测成功,开始检测上升沿
{
TH1=(8192-4000)/32;
TL1=(8192-4000)%32; //4000*0.25us=1MS中断一次
if(!PraState&NowState)
{
_nop_();
_nop_();
if(Infrared){bitdata++;}
_nop_();
_nop_();
if(Infrared){bitdata++;}
_nop_();
_nop_();
if(Infrared){bitdata++;}
if(bitdata>>1) //确定是上升沿,置起上升沿标志
{
DownUpFlag = 3; // DownUpFlag = 3
HighLevelCount = 0; //将高电平个数清0
LowLevelCount = 0; //低电平个数清零
return;
}
}
}
else if(DownUpFlag==3) //检测到上升沿以后检测高电平时间长度
{
TH1=(8192-4000)/32;
TL1=(8192-4000)%32; //4000*0.25us=1MS中断一次
if(Infrared){bitdata++;}
_nop_();
_nop_();
if(Infrared){bitdata++;}
_nop_();
_nop_();
if(Infrared){bitdata++;}
if(bitdata>>1) //确定是高电平
{
HighLevelCount++;
if(HighLevelCount>=3) //如果检测到2MS以上的低电平就认为是起始信号
{
HighLevelCount = 0; //将高电平个数清0
LowLevelCount = 0; //低电平个数清零
DownUpFlag = 4;
TH1=(8192-400)/32;
TL1=(8192-400)%32; //400*0.25us=100uS中断一次
return;
}
}
else //如果是高电平
{
LowLevelCount++;
if(LowLevelCount>=1) //如果在检测到下降沿以后,2次低电平之前检测到1次高电平,则本次上升沿就作废
{
HighLevelCount = 0; //将高电平个数清0
LowLevelCount = 0; //低电平个数清零
DownUpFlag = 0;
return;
}
}
}
else if(DownUpFlag==4) //DownUpFlag==4说明起始信号检测成功,准备检测0,1信号
{
TH1=(8192-400)/32;
TL1=(8192-400)%32; //400*0.25us=100uS中断一次
if(PraState&!NowState) //检测下降沿
{
_nop_();
_nop_();
if(!Infrared){bitdata++;}
_nop_();
_nop_();
if(!Infrared){bitdata++;}
_nop_();
_nop_();
if(!Infrared){bitdata++;}
if(bitdata>>1) //确定是下降沿
{
DownCount ++;
return;
}
}
if(DownCount==2)
{
DownCount = 1;
RxDataBuf = RxDataBuf<<1;
if(UpToDownCount>16) //两次下降沿时间大于1.6ms,说明数据为1
{
RxDataBuf ++;
}
BitCount++;
UpToDownCount = 0;
if(BitCount>32) //接收完32bit数据
{
BitCount = 0;
RxDataOverFlag = 1;
DownUpFlag = 0;
TR1=0; //关掉定时器
return ;
}
}
else if(DownCount==1)
{
UpToDownCount++;
}
}
}
}
主程序检测到接收一帧,处理数据
if(RxDataOverFlag) //如果红外接收完一帧数据,就进行数据处理
{
RxDataOverFlag = 0;
if(((RxDataBuf>>16)==0x01fe)&&((((RxDataBuf&0x0000ff00)>>8)+(RxDataBuf&0x000000ff))==0xff))
{
switch(RxDataBuf)
{
case 0x01FE48B7: exKeyValue = 1;break;
case 0x01FE7887: exKeyValue = 6;break;
case 0x01FE20DF: exKeyValue = 5;break;
case 0x01FE609F: exKeyValue = 2;break;
case 0x01FE50AF: exKeyValue = 3;break;
case 0x01FEF807: exKeyValue = 4;break;
}
UpdateLcdBufFunc();
}
TH1=(8192-4000)/32;
TL1=(8192-4000)%32; //4000*0.25us=1MS中断一次
Timer60msFlag = 1;
TR1=1; //打开定时器
}
|