您好,欢迎访问三七文档
当前位置:首页 > 电子/通信 > 综合/其它 > 红外遥控器软件解码原理和程序 - 21IC中国电子网
红外遥控器软件解码原理和程序红外一开始发送一段13.5ms的引导码,引导码由9ms的高电平和4.5ms的低电平组成,跟着引导码是系统码,系统反码,按键码,按键反码,如果按着键不放,则遥控器则发送一段重复码,重复码由9ms的高电平,2.25ms的低电平,跟着是一个短脉冲,本程序经过试用,能解大部分遥控器的编码!#includeat89x52.h#defineNULL0x00//数据无效#defineRESET0X01//程序复位#defineREQUEST0X02//请求信号#defineACK0x03//应答信号,在接收数据后发送ACK信号表示数据接收正确,也位请求信号的应答信号#defineNACK0x04//应答信号,表示接收数据错误#defineBUSY0x05//忙信号,表示正在忙#defineFREE0x06//空闲信号,表示处于空闲状态#defineREAD_IR0x0b//读取红外#defineSTORE_IR0x0c//保存数据#defineREAD_KEY0x0d//读取键值#defineRECEIVE0Xf400//接收缓冲开始地址#defineSEND0xfa00//发送缓冲开始地址#defineIR0x50//红外接收缓冲开始地址#defineHEAD0xaa//数据帧头#defineTAIL0x55//数据帧尾#defineSDAP1_7#defineSCLP1_6unsignedcharxdata*buf1;//接受数据缓冲unsignedintbuf1_length;//接收到的数据实际长度unsignedcharxdata*buf2;//发送数据缓冲unsignedintbuf2_length;//要发送的数据实际长度bitbuf1_flag;//接收标志,1表示接受到一个数据帧,0表示没有接受到数据帧或数据帧为空bitbuf2_flag;//发送标志,1表示需要发送或没发送完毕,0表示没有要发送的数据或发送完毕unsignedcharstate1,state2;//用来标志接收字符的状态,state1用来表示接收状态,state2用来表示发送状态unsignedchardata*ir;union{unsignedchara[2];unsignedintb;unsignedchardata*p1[2];unsignedintdata*p2[2];unsignedcharxdata*p3;//红外缓冲的指针unsignedintxdata*p4;}p;//union{////unsignedchara[2];////unsignedintb;//unsignedchardata*p1[2];//unsignedintdata*p2[2];//unsignedcharxdata*p3;//unsignedintxdata*p4;//地址指针//}q;//union{unsignedchara[2];unsignedintb;}count;union{unsignedchara[2];unsignedintb;}temp;union{unsignedchara[4];unsignedintb[2];unsignedlongc;}ir_code;union{unsignedchara[4];unsignedintb[2];unsignedlongc;unsignedchardata*p1[4];unsignedintdata*p2[4];unsignedcharxdata*p3[2];unsignedintxdata*p4[2];}i;unsignedcharir_key;bitir_flag;//红外接收标志,0为缓冲区空,1为接收成功,2为缓冲溢出voidsub(void);voiddelay(void);voidie_0(void);voidtf_0(void);voidie_1(void);voidtf_1(void);voidtf_2(void);voidread_ir(void);voidir_jiema(void);voidir_init(void);voidir_exit(void);voidstore_ir(void);voidread_key(void);voidreset_iic(void);unsignedcharread_byte_ack_iic(void);unsignedcharread_byte_nack_iic(void);bitwrite_byte_iic(unsignedchara);voidsend_ack_iic(void);voidsend_nack_iic(void);bitreceive_ack_iic(void);voidstart_iic(void);voidstop_iic(void);voidwrite_key_data(unsignedchara);unsignedintread_key_data(unsignedchara);voidie0(void)interrupt0{ie_0();}voidtf0(void)interrupt1{tf_0();}voidie1(void)interrupt2{ie_1();}voidtf1(void)interrupt3{tf_1();tf_2();}voidtf2(void)interrupt5{//采用中断方式跟查询方式相结合的办法解码EA=0;//禁止中断if(TF2){//判断是否是溢出还是电平变化产生的中断TF2=0;//如果是溢出产生的中断则清除溢出位,重新开放中断退出EA=1;gotoend;}EXF2=0;//清除电平变化产生的中断位*ir=RCAP2H;//把捕捉的数保存起来ir++;*ir=RCAP2L;*ir++;F0=1;TR0=1;//开启计数器0loop:TL0=0;//将计数器0重新置为零TH0=0;while(!EXF2){//查询等待EXF2变为1if(TF0)gotoexit;//检查有没超时,如果超时则退出};EXF2=0;//将EXF2清零if(!TH0)//判断是否是长低电平脉冲过来了{//不是长低电平脉冲而是短低电平if(F0)count.b++;//短脉冲数加一temp.a[0]=RCAP2H;//将捕捉数临时存放起来temp.a[1]=RCAP2L;gotoloop;//返回继续查询}else{//是低电平脉冲,则进行处理F0=0;*ir=temp.a[0];//把连续的短脉冲总时间记录下来ir++;*ir=temp.a[1];ir++;*ir=RCAP2H;//把长电平脉冲时间记录下来ir++;*ir=RCAP2L;ir++;if(ir=0xda){gotoexit;//判断是否溢出缓冲,如果溢出则失败退出}gotoloop;//返回继续查询}exit:ir_flag=1;//置ir_flag为1表示接收成功end:;}voidrs232(void)interrupt4{staticunsignedcharsbuf1,sbuf2,rsbuf1,rsbuf2;//sbuf1,sbuf2用来接收发送临时用,rsbuf1,rsbuf2用来分别用来存放接收发送的半字节EA=0;//禁止中断if(RI){RI=0;//清除接收中断标志位sbuf1=SBUF;//将接收缓冲的字符复制到sbuf1if(sbuf1==HEAD){//判断是否帧开头state1=10;//是则把state赋值为10buf1=RECEIVE;//初始化接收地址}else{switch(state1){case10:sbuf2=sbuf14;//把高半字节右移到的半字节sbuf2=~sbuf2;//把低半字节取反if((sbuf2&0x0f)!=(sbuf1&0x0f))//判断接收是否正确{//接收错误,有可能接收的是数据帧尾,也有可能是接收错误if(sbuf1==TAIL)//判断是否接收到数据帧尾{//是接收到数据帧尾buf1=RECEIVE;//初始化接收的地址if(*buf1==RESET)//判断是否为复位命令{ES=0;sbuf2=SP+1;for(p.p1[0]=SP-0x10;p.p1[0]=sbuf2;p.p1[0]++)*p.p1[0]=0;}state1=0;//将接收状态标志置为零,接收下一个数据帧buf1_flag=1;//置接收标志为1,表示已经接收到一个数据帧REN=0;//禁止接收}else{//不是接受到数据帧尾,表明接收错误state1=0;//将接收状态标志置为零,重新接收buf1=RECEIVE;//初始化发送的地址*buf1=NACK;//把NACK信号存入接收缓冲里buf1_flag=1;//置标志位为1,使主程序能对接收错误进行处理REN=0;//禁止接收}}else{//接收正确rsbuf1=~sbuf1;//按位取反,使高半字节变原码rsbuf1&=0xf0;//仅保留高半字节,低半字节去掉state1=20;//将状态标志置为20,准备接收低半字节}break;case20:sbuf2=sbuf14;//把高半字节右移到的半字节sbuf2=~sbuf2;//将低半字节取反if((sbuf2&0x0f)!=(sbuf1&0x0f))//判断接收是否正确{//接受错误state1=0;//将接收状态标志置为零,重新接收buf1=RECEIVE;//初始化接收的地址*buf1=NACK;//把NACK信号存入发送缓冲里buf1_flag=1;//置标志位为1,使主程序能对接收错误进行处理REN=0;//禁止接收}else{sbuf1&=0x0f;//仅保留低半字节,去掉高半字节rsbuf1|=sbuf1;//高低半字节合并*buf1++=rsbuf1;//将接收的数据保存至接收缓冲里,并且数据指针加一buf1_length++;//接收数据长度加一state1=10;//将state1置为10,准备接收下个字节的高半字节}break;}}}else{TI=0;//清除发送中断标志if(buf2_length)//判断发送长度是否为零{//发送长度不为零if(state2==0)//判断是否发送高半字节{//发送高半字节sbuf2=*buf2;//将要发送的字节送到sbuf2rsbuf2=~sbuf2;//取反,使高半字节变为反码sbuf2=4;//将高半字节右移到低半字节rsbuf2&=0xf0;//保留高半字节,去掉低半字节sbuf2&=0x0f;//保留低半字节,去掉高半字节rsbuf2|=sbuf2;//合并高低半字节SBUF=rsbuf2;//发送出去state2=10;//将state2置为10准备发送下半字节}else{//发送低半字节sbuf2=*buf2;//将要发送的字节送到sbuf2buf2++;//指针加一buf2_length--;//发送数据长度减一rsbuf2=~sbuf2;//取反,使低半字节变为反码rsbuf2=4;//将低半字节反码左移到高半字节rsbuf2&=0xf0;//保留高半字节,去掉低半字节sbuf2&=0x0f;//保留低半字节,去掉高半字节rsbuf2|=sbuf2;//合并高低半字节SBUF=rsbuf2;//发送出state2=0;}}else{//如果发送数据长度为零则发送数据帧尾if(buf2_flag){//判断是否发过数据帧尾SBUF=TAIL;//将数据帧尾发送出去while(TI==0);TI=0;buf2_flag=0;//置发送标志为零,表示发送完毕}}}EA=1;//开放中断}
本文标题:红外遥控器软件解码原理和程序 - 21IC中国电子网
链接地址:https://www.777doc.com/doc-78765 .html