红外解码程序

#include
#include
#define nop() _nop_()
#define DIGI P0 //宏定义,将P0口定义为数码管
#define SELECT P2 //宏定义,将P2定义为数码管选择口
#define TIME 1640
int numsys,numobj,flag,err;
unsigned char IRCode[4],IRCon,IRCon2,tl_1,th_1;
unsigned char digivalue[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};
//显示的数字数组,依次为0,1,..,9
unsigned char digiwel[]={0xff,0x89,0x86,0xc7,0xc7,0xc0,0xff};
unsigned char select[]={0xfd,0xfb,0xf7,0xef}; //选择数码管数组,依次选择1,2,3,4
unsigned char code_sys_rc5,code_use_rc5,code_sys_neca,code_sys_necb,code_use_neca,code_use_necb;
//收到的RC5系统码、数据码,收到的NEC系统码(1,2)及其反码,用户码及其反码,flag为码标志,0为RC5码,为NEC码

unsigned char i=0,k=0,temp;
char j=0;
sbit b0=B^0;
sbit P2_0 =P2^0;
sbit P3_2 =P3^2;

void delay_890()// i us定时,供中断程序使用
{
TMOD=0x10;
TL1=0x86;
TH1=0xfc;
TR1=1;
while(~TF1);
TF1=0;
TR1=0;
}
void delay1() //200us延时,主程序使用
{
unsigned char ii=200;
while(ii--);

}

void delay_412() //412us延时,中断程序使用
{
TMOD=0x10;
TL1=0x66;
TH1=0xfe;
TR1=1;
while(~TF1);
TF1=0;

}

void delay_280() //280us延时,中断程序使用
{
TMOD=0x10;
TL1=0xe7;
TH1=0xfe;
TR1=1;
while(~TF1);
TF1=0;
}

void delay_1125() //1125us延时,中断程序使用
{
TMOD=0x10;
TL1=0x9a;
TH1=0xfb;
TR1=1;
while(~TF1);
TF1=0;
}

void delay_4500() //4500us延时,中断程序使用
{
TMOD=0x10;
TL1=0x6b;
TH1=0xee;
TR1=1;
while(~TF1);
TF1=0;
}
int wait()//等待电平发生跃变
{
err=0;
if(P3_2==0) while(P3_2==0) {err++;if(err>400) return -1;} //当P3.2为低电平时,等待高电平出现,等待时间超过1200us时,报错返回
else if(P3_2==1) while(P3_2==1) {err++;if(err>400) return -1;} //当P3.2为高电平时,等待低电平出现,等待时间超过1200us时,报错返回
return 0;
}
int decode_rc5(unsigned char *p)
{
//wait();
delay_890();
err=wait();
if(err) return;
delay_412();
(*p)=(*p)<<1;
(*p)=(*p)|(~P3_2);
return 0;
}
int decode_nec(unsigned char *p)
{
//delay_1125();
while(P3_2==0);
delay_412();
delay_412();
(*p)=(*p)|(P3_2);
temp=(*p)&1;
(*p)=(*p)>>1;
temp<<=7;
(*p)=(*p)|temp;
if(P3_2==1)
{
delay_412();
delay_412();
while(P3_2==1);
//delay_1125(); //等待低电平出现
//
}
else;
return 0;
}
int check_code_nec() //利用NEC码的原始码和反吗来检测数据是否正确
{
if(IRCon2==0)
{
temp=code_sys_neca+code_sys_necb;
if(temp!=0xff) return -1;
}
else if(IRCon2==1)
{
temp=code_use_neca+code_us

e_necb;
if(temp!=0xff) return -1;
}
return 0;
}
main()
{
unsigned char i=0,k;
char j;
EA=0;
for(j=-3;j<7;j++)
{
for(k=0;k<30;k++)
{
for(i=0;i<4;i++) //4个数码管轮流显示
{
SELECT=select[i]; //选择第i个数码管
if(i+j<0) DIGI=digiwel[0]; //显示hello
else if((i+j)>6) DIGI=digiwel[6];
else DIGI=digiwel[i+j];
delay1();
}
}
}
code_sys_rc5=0;
code_use_rc5=0;
code_sys_neca=0;
code_sys_necb=0;
code_use_neca=0;
code_use_necb=0;
ET0=0;
ET1=0;
EX0=1;
IT0=1;
P2_0=1;
EA=1;
while(1)
{
for(i=0;i<4;i++) //4个数码管轮流显示
{

SELECT=select[i]; //选择第i个数码管

switch(i)
{
case 0:k=IRCode[0];
k=k>>4;
break;
case 1:k=IRCode[0];
k&=0xf;
break;
case 2:k=IRCode[1];
k=k>>4;
break;
case 3:k=IRCode[1];
k&=0xf;
break;
default:break;
}
DIGI=digivalue[k];
delay1();

}
}
}

void int0() interrupt 0 using 0
{
int b;
EA=0;
flag=0;
IRCon=0;
IRCon2=0;
P2_0=1;
nop();
code_sys_rc5=0;
code_use_rc5=0;
code_sys_neca=0;
code_sys_necb=0;
code_use_neca=0;
code_use_necb=0;
for(b=3;b>0;b--) //判断是否为RC5码,flag=0表示RC5码
{
delay_412();
switch(b)
{
case 3:if(P3_2==1) {flag=1;break;} //起始位
delay_890();
if(P3_2==0) {flag=1;break;} //判断是否为NEC码
wait();
break;
case 2:if(P3_2==1) {flag=1;break;} //起始位
delay_890();
wait();
break;
case 1: //状态位
break;
default:break;
}
if(flag==1) break;
}
if(flag==1) //flag=1表示NEC码
{
if(P3_2==1) goto out;
b=8;
while((b--)>0&flag) //判断是否是9ms低电平
{
delay_890();
if(P3_2==1) goto out; //P3_2=1,说明来的红外信号是抖动
}
while(P3_2==0);
b=4;
while((b--)>0&flag) //判断是否是4.5ms高电平
{
delay_890();
if(P3_2==0) goto out; //若果P3_2变高,说明接收到的是NEC码,否则为C5码
}
while(P3_2==1) if(b++>4500) goto out; //若果P3_2变高,说明接收到的是NEC码,否则为C5码
}
/************接收系统码*****************/
switch(flag)
{
case 0:for(IRCon=0;IRCon<5;IRCon++) {err=decode_rc5(&code_sys_rc5);if(err) goto out;}
break;
case 1:for(IRCon=0;IRCon<8;IRCon++) {err=decode_nec(&code_sys_neca);if(err) goto out;}
for(IRCon=0;IRCon<8;IRCon++) {err=decode_nec(&code_sys_necb);if(err) goto out;}
err=check_code_nec();
if(err) goto out;
break;
default:break;
}
IRCon2++;//用作指示系统码和用户码

/************接收

用户码*****************/
switch(flag)
{
case 0:for(IRCon=0;IRCon<6;IRCon++) {err=decode_rc5(&code_use_rc5);if(err) goto out;}
break;
case 1:for(IRCon=0;IRCon<8;IRCon++) {err=decode_nec(&code_use_neca);if(err) goto out;}
for(IRCon=0;IRCon<8;IRCon++) {err=decode_nec(&code_use_necb);if(err) goto out;}
err=check_code_nec();
if(err) goto out;
break;
default:break;
}
P2_0=0;
/************保存接收码*****************/
switch(flag)
{
case 0:IRCode[0]=code_sys_rc5;
IRCode[1]=code_use_rc5;
break;
case 1:IRCode[0]=code_sys_neca;
IRCode[1]=code_use_neca;
break;
default:break;
}
out:nop();
//P2_0=1;
EA=1;
}








相关文档
最新文档