文档详情

红外遥控代码

jin****ng
实名认证
店铺
DOCX
24.09KB
约9页
文档ID:177271064
红外遥控代码_第1页
1/9

红外线遥控器软件解码原理和程序(C语言)UPD6121G产生的遥控编码是连续的32位二进制码组,其中前16位为用户识别 码,能区别不同的电器设备,防止不同机种遥控码互相干扰该芯片的用户识别 码固定为十六进制01H;后16位为8位操作码(功能码)及其反码UPD6121G 最多额128种不同组合的编码遥控器在按键按下后,周期性地发出同一种32位二进制码,周期约为108ms 一组码本身的持续时间随它包含的二进制“0”和“1”的个数不同而不同,大约 在45〜63ms之间,图4为发射波形图当一个键按下超过36ms,振荡器使芯片激活,将发射一组108ms的编码脉 冲,这108ms发射代码由一个起始码(9ms), —个结果码(4.5ms),低8位地址 码(9ms~18ms),高8位地址码(9ms~18ms) ,8位数据码(9ms~18ms)和这8位 数据的反码(9ms~18ms)组成如果键按下超过108ms仍未松开,接下来发射的 代码(连发代码)将仅由起始码(9ms)和结束码(2.5ms)组成代码格式(以接收代码为准,接收代码与发射代码反向)① 位定义② 单发代码格式③ 连发代码格式注:代码宽度算法:16位地址码的最短宽度:1.12X16=18ms 16位地址码的最长宽度: 2.24msX16=36ms易知8位数据代码及其8位反代码的宽度和不变:(1.12ms+2.24ms)X8=27ms 所以32位代码的宽度为(18ms+27ms) ~(36ms+27ms)1.解码的关键是如何识别“0”和“1”,从位的定义我们可以发现“0”、“1” 均以0.56ms的低电平开始,不同的是高电平的宽度不同,“0”为0.56ms,“l” 为1.68ms,所以必须根据高电平的宽度区别“0”和“ 1”。

如果从0.56ms低电 平过后,开始延时, 0.56ms 以后,若读到的电平为低,说明该位为“0”,反之 则为“ 1”,为了可靠起见,延时必须比0.56ms长些,但又不能超过1.12ms,否 则如果该位为“0”,读到的已是下一位的高电平,因此取(1.12ms+0.56ms) /2=0.84ms 最为可靠,一般取 0.84ms 左右均可2.根据码的格式,应该等待9ms的起始码和4.5ms的结果码完成后才能读码接收器及解码一体化红外线接收器是一种集红外线接收和放大于一体,不需要任何外接元 件,就能完成从红外线接收到输出与 TTL 电平信号兼容的所有工作,而体积和普 通的塑封三极管大小一样,它适合于各种红外线遥控和红外线数据传输下面是一个对 51实验板配套的红外线遥控器的解码程序,它可以把上图 32 键的 红外遥控器每一个按键的键值读出来,并且通过实验板上P1 口的8个LED显示 出来,在解码成功的同时并且能发出“嘀嘀嘀”的提示音红外线一开始发送一段13.5ms的引导码,引导码由9ms的高电平和4.5ms的低电平组 成,跟着引导码是系统码,系统反码,按键码,按键反码,如果按着键不放,则遥控器则发 送一段重复码,重复码由9ms的高电平,2.25ms的低电平,跟着是一个短脉冲。

本程序 经过试用,能解大部分遥控器的编码!#in elude "at89x52.h"#defi neNULL0x00〃数据无效#defi neRESET0X01 〃程序复位#defi neREQUEST0X02 〃请求信号#defi neACK0x03 〃应答信号,在接收数据后发送ACK信号表示数据接收正确,也位请求信号的应答信号#defi neNACK0x04〃应答信号,表示接收数据错误#defi neBUSY0x05〃忙信号,表示正在忙#defi neFREE0x06 〃空闲信号,表示处于空闲状态#defi neREAD_IR0x0 b//读取红外#defi neSTORE_IR 0x0c//保 存数据#defi neREAD_KEY 0x0d〃 读取键值#defi neRECEIVE0Xf400〃接收缓冲开始地址#defi neSEND0xfa00〃发送缓冲开始地址#defi neIR0x50〃红外接收缓冲开始地址#defi neHEAD0xaa〃数据帧头#defi neTAIL0x55〃数据帧尾#defi neSDAP1_7#defi neSCLP1 6un sig ned cha r xdata * bufl; 〃接受数据缓冲un sig ned int buf1_le ngth; 〃接收到的数据实际长度un sig ned cha r xdata * buf2; 〃发送数据缓冲un sig ned int buf2_le ngth; 〃要发送的数据实际长度bit buf1_flag; 〃接收标志,1表示接受到一个数据帧,0表示没有接受到数据帧或数据 帧为空bit buf2_flag; 〃发送标志,1表示需要发送或没发送完毕,0表示没有要发送的数据或发送完毕unsigned char state1,state2; //用来标志接收字符的状态,statel用来表示接收状态,state2用来表示发送状态un sig ned cha r data *ir;union{un sig ned cha r a[2];un sig ned int b;un sig ned cha r data * p1[2];un sig ned int data * p2[2];un sig ned cha r xdata * p3; 〃红外缓冲的指针un sig ned int xdata * p4;}p;〃union{ //// un sig ned cha r a[2]; //// un sig ned int b;// un sig ned cha r data * p1[2];// un sig ned int data * p2[2];// un sig ned cha r xdata * p3;// un sig ned int xdata *p4; 〃地址指针〃}q; //union{un sig ned cha r a[2];un sig ned int b;}co unt;union{un sig ned cha r a[2];un sig ned int b;}temp;union{un sig ned cha r a[4];un sig ned int b[2];un sig ned long c;}ir_code;union{un sig ned cha r a[4];un sig ned int b[2];un sig ned long c;un sig ned cha r data * p1[4];un sig ned int data * p2[4];un sig ned cha r xdata * p3[2];un sig ned int xdata * p4[2];}I;un sig ned cha r ir_key;bit ir_flag; 〃红外接收标志,0为缓冲区空,1为接收成功,2为缓冲溢出void sub(void); void delay(void);void ie_0(void); void tf_0(void);void ie_1(void); void tf_1(void);void tf_2(void); void r ead_i r(void);void ir_jiema(void); void ir_ini t(void);void ir_exit(void);void sto re_i r(void);void r ead_key(void);void r eset_iic(void);un sig ned cha r r ead_byte_ack_iic(void);un sig ned cha r r ead_byte _n ack_iic(void); bit wr ite_byte_iic( un sig ned cha r a);void sen d_ack_iic(void);void send_n ack_iic(void);bit receive_ack_iic(void);void sta rt_iic(void);void stop_iic(void);void wr ite_key_data( un sig ned cha r a);un sig ned int r ead_key_data( un sig ned cha r a);void ie0(void) interr upt 0{ie_0();} void tfO(void) interrupt 1{tf_0();}void ie1(void)interrupt 2{ie_1();}void tf1(void) interrupt 3{tf_1();tf_2();}void tf2(void) interr upt 5{ 〃采用中断方式跟查询方式相结合的办法解码EA=0;if(TF2){TF2 = 0; 断退出EA=1; goto end;}EXF2 = 0;*ir =RCAP2H; ir + + ;*ir =RCAP2L; *ir + + ;F0=1;TR0 = 1;loop:〃禁止中断〃判断是否是溢出还是电平变化产生的中断〃如果是溢出产生的中断则清除溢出位,重新开放中//清除电平变化产生的中断位〃把捕捉的数保存起来〃开启计数器0TL0 = 0; 〃将计数器0重新置为零TH0=0; while(!EXF2){ if(TF0)goto exit;};EXF2 = 0;if(!TH0){if(F0)cou nt.b+ + ;temp.a[0] = RCAP2H;temp.a[1] = RCAP2L; goto loop;} else{F0=0;*ir=temp.a[0];ir + + ;*ir=temp.a[1];ir + + ;*ir =RCAP2H;ir + + ;*ir =RCAP2L;ir + + ;if(ir>=0xda) {goto exit;〃查询等待EXF2变为1〃检查有没超时,如果超时则退出//将 EXF2 清零〃判断是否是长低电平脉冲过来了〃不是长低电平脉冲而是短低电平〃短脉冲数加一〃将捕捉数临时存放起来//返回继续查询〃是低电平脉冲,则进行处理〃把连续的短脉冲总时间记录下来〃把长电平脉冲时间记录下来〃判断是否溢出缓冲,如果溢出则失败退出exit:end:}goto loop;}ir_ flag = 1;void r s232(void)〃返回继续查询〃置ir_flag为1表示接收成功interr upt 4{static un sig ned cha r sbuf1,sbuf2, rsbuf1, rsbuf2; 〃sbuf1,sbuf2 用来接收发送临时用,rsbuf1,rsbuf2用来分别用来存放接收发送的半字节EA=0;if(RI){RI = 0;sbuf1 = SBUF;if(sbuf1 = = HEAD){state1 = 10; buf1 = RECEIVE;〃禁止中断//清除接收中断标志位〃将接收缓冲的字符复制到sbuf1 〃判断是否帧开头//是则把state赋值为10〃初始化接收地址}else{switch(state1){case 10:sbuf2=sbuf1>>4; 〃把高半字节右移到的半字节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; buf1_flag = 1;〃不是接受到数据帧尾,表明接收错误//将接收状态标志置为零,重新接收 〃初始化发送的地址//把 NACK信号存入接收缓冲里〃置标志位为1,使主程序能对接收错误进行处理REN = 0;〃禁止接收if((sbuf2&0x0f)! = (sbuf1&0x0f))〃接收正确〃按位取反,使高半字节变原码〃仅保留高半字节,低半字节去掉〃将状态标志置为20,准备接收低半字节}else{r sbuf1 = ~sbuf1;rsbuf1 &=0xf0;state1 = 20;}br eak;case 20:sbuf2=sbuf1>>4;sbuf2=~sbuf2;//把高半字节右移到的半字节 〃将低半字节取反〃判断接收是否正确〃接受错误//将接收状态标志置为零,重新接收〃初始化接收的地址〃把NACK信号存入发送缓冲里〃置标志位为1,使主程序能对接收错误进〃禁止接收〃仅保留低半字节,去掉高半字节〃高低半字节合并〃将接收的数据保存至接收缓冲里,并〃接收数据长度加一〃将state1置为10,准备接收下个字节的〃清除发送中断标志〃判断发送长度是否为零〃发送长度不为零〃判断是否发送高半字节〃发送高半字节〃将要发送的字节送到sbuf2 〃取反,使高半字节变为反码〃将高半字节右移到低半字节〃保留高半字节,去掉低半字节〃保留低半字节,去掉高半字节〃合并高低半字节〃发送出去〃将state2置为10准备发送下半字节{state1=0; buf1 = RECEIVE;* buf1 = NACK; buf1_flag = 1;行处理REN = 0;}else{ sbufl&= OxOf;r sbuf1|=sbuf1;* buf1 + + = rsbufl; 且数据指针加一buf1_le ngth+ + ; state1 = 10;高半字节}br eak;}}}else{TI=0;if(buf2_le ngth){ if(state2==0){sbuf2=* buf2; r sbuf2=~sbuf2; sbuf2>>=4; rsbuf2&=OxfO;sbuf2&= OxOf; r sbuf2|=sbuf2;SBUF=r sbuf2; state2=10;}else{sbuf2=* buf2; buf2+ + ;buf2」en gth--; r sbuf2=~sbuf2;〃发送低半字节〃将要发送的字节送到sbuf2〃指针加一〃发送数据长度减一〃取反,使低半字节变为反码r sbuf2vv=4; rsbuf2&= OxfO; sbuf2&= OxOf;r sbuf2|=sbuf2; SBUF=r sbuf2; state2=0;}} else{ if(buf2_flag){ SBUF=TAIL; while(TI==0); TI=0; buf2_flag=0;}}}EA=1;〃将低半字节反码左移到高半字节 〃保留高半字节,去掉低半字节 〃保留低半字节,去掉高半字节 〃合并高低半字节〃发送出〃如果发送数据长度为零则发送数据帧尾 〃判断是否发过数据帧尾//将数据帧尾发送出去〃置发送标志为零,表示发送完毕〃开放中断。

下载提示
相关文档
正为您匹配相似的精品文档