红外线遥控器解码程序
- 格式:pdf
- 大小:244.02 KB
- 文档页数:5
一文教会你红外线遥控器软件解码程序
红外线一开始发送一段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_6
unsigned char xdata *buf1;//接受数据缓冲。
红外遥控器软件解码及其应用红外遥控器软件解码及其应用摘要:通过对红外遥控器各按键发送冲波形的分析可以识别码型,从而为软件解码提供依据。
本文以实例介绍红外遥控器与单片机的硬件接口,并从原理出发给出软件解码的方法。
这是一个可以直接引用的成功例子,同时也为各类红外遥控器在单片机控制产品中的开发应用提供了一个非常实用的参考。
关键词:遥控器软件解码单片机在单片机控制产品的开发应用中,为了向控制系统软件控制命令,键盘往往是不可缺少的。
传统方法是利用并行输入/输出接口芯片扩展一个键盘接口,或者直接利用单片机的并行端口进行扩展。
在某些应用环境下,这种方式2个弊端:①键盘和控制系统连在一起,不灵活,环境适应性差;②浪费单片机的端口,且硬件成本较高。
使用红外遥控器作为控制系统的输入设备,具有成本低、灵活方便的特点。
本文目的就在于介绍软件解码研究的一般方法和红外遥控器进行二次开发的应用技术。
该方法已在多个应用系统设计中成功地实现,效果良好。
红外遥控器是一种非常容易买到,且价格便宜的产品,种类很多,但它们都是配合某种特定电子产品的(如各种电视机、VCD、空调器等),由专用CPU解码,作为一般的单片机控制系统能直接使用。
使用现成遥控器作为控制系统的输入,需要解决如下几个问题:如何接收红外遥控信号;如何识别红外遥控信号;解码软件的设计。
其它的问题都是非本质的,例如遥控器面板功能键标注的问题,可自行设计、重印即可。
1红外遥控信号的接收接收电路可以使用集成红外接收器成品。
接收器包括红外接收管和信号处理IC.接收器对外只有3个引脚:Vcc、GND和1个脉冲信号输出PO.与单片机接口非常方便,如图1所示。
①Vcc接系统的电源正极(+5V);②GND接系统的地线(0V);③脉冲信号输出接CPU的中断输入引脚(例如8031的13脚INT1)。
采取这种连接方法,软件解既可工作于查询方式,也可工作于中断方式。
2脉冲流分析要了解一个未知的遥控器,首先要分析其脉冲流,从而了解其脉冲波形特征(以何种方式携带“0”、“1”信息),进而了解其编码规律。
利用A VR(M8)的输入捕获(ICP)对万能红外线遥控器进行解码本实例程序为自创,若转载请注明出处,谢谢!小弟不久前买了一个科朗公司出版的万能电视遥控器RM-2008,用作对设备的红外遥控,折腾了几天,今天终于弄清楚了如何对该遥控器进行解码,很开心,所以把成果与各位大虾分享,有什么错误的地方请指正。
万能遥控器在使用前一般要进行设置,针对RM-2008这款万能遥控,设置方法如下:先按住“设置”键不放,再按下“电源”(“开/关”)键,工作指示灯亮起,然后释放两键,在此时进入代码输入状态,依次键入0 0 0 指示灯熄灭,设置成功!说明一下:0 0 0 编码是日立公司初期的红外编码方式,也就是网上到处都通用的红外编码方式(如下图),另外本程序只能对此编码进行解码数据头的时间:Th=9+4.5=13.5ms数据“0”的时间:T0=0.565+0.56=1.125ms数据“1”的时间:T1=1.685+0.56=2.245ms本程序通过使用输入捕获功能(ICP)捕捉红外信号的高电平脉宽,达到解码的目的;如果捕获到的脉宽是4.5ms 则表示此信号为同步码,如果捕获到的脉宽是1.685ms 的话则表示“1”否则表示“0”测试电路如下:使用DNW 串口调试软件时的效果/////////////////////////////////只有一个文件main.c/////////////////////////////////// #include <avr/io.h>#include <avr/signal.h>#include <avr/interrupt.h>#include <avr/wdt.h>#include <util/delay.h>#include <stdio.h>/*----------------------遥控操作值--------------------*/// key code (hex)#define Key_1 0x01#define Key_2 0x02#define Key_3 0x03#define Key_4 0x04#define Key_5 0x05#define Key_6 0x06#define Key_7 0x07#define Key_8 0x08#define Key_9 0x09#define Key_0 0x00#define Menu 0x5c // 菜单#define Menu_up 0x56 // 菜单上#define Menu_down 0x57 // 菜单下#define Menu_left 0x5f // 菜单左#define Menu_right 0x5b // 菜单右#define Menu_ok 0x16 // 菜单确认#define Channel_up 0x1b // 频道+ #define Channel_down 0x1f // 频道- #define Sound_up 0x1e // 音量+ #define Sound_down 0x1a // 音量- #define Open_Close 0x12 // 开/关#define Mute 0x10 // 静音#define Pic_in_pic 0x51 //画中画#define Standard 0x58 // 制式#define Return 0x52 // 返回#define Times 0x0b // 倍数#define Screen 0x16 // 屏幕#define Audio 0x1d // 伴音#define NICAM 0x13 // 丽音#define TV_Vedio 0x0f // 电视/视频#define Sleep 0x0e //睡眠/*----------------------常用参数定义-------------------*/ #define P0 0#define P1 1#define P2 2#define P3 3#define P4 4#define P5 5#define P6 6#define P7 7#define FREQ 8 //定义单片机工作频率为8M#define uint unsigned int#define uchar unsigned char#define Start_T1 TCCR1B|=_BV(CS11);TCNT1=0//复位预计分频器并开启定时器T1#define Stop_T1 TCCR1B&=~_BV(CS11) //关闭定时器T1/*-----------------IR信号指示灯操作函数---------*/#define EN_IR_LED DDRB|=_BV(P1)#define CLR_IR_LED PORTB&=~_BV(P1)#define SET_IR_LED PORTB|=_BV(P1)/*----------------------某些端口操作-------------------*/volatile unsigned char i,j,k;volatile unsigned long IRcode; //定义一个长度为4字节的无符号long 类型变量来存储代码volatile unsigned char *IRcodePointer ; //定义一个无符号的单字节指针变量,//用此地址变量来分别读取IRCode的//4个字节其中操作码为IRcodePointer[2]//用户码为IRcodePointer[0]volatile unsigned char IRReceiveEffective=0; //IR信号接收有效当程序响应接收以后请马上清零这样才会继续接收下一IR码volatile unsigned char IRReceiveCurrentBit=0; //IR信号当前接收位0时表示第0位即同步码(4.5ms高电平)volatile unsigned int Pulse_length=0; //捕获的脉冲宽度volatile unsigned char ICP_Parity=0; //捕获中断奇偶次计数1时为偶次并在此时判断脉宽volatile unsigned char Received_Key_Temp; //红外接收操作键缓存const unsigned char String[]={"You Have Press Key : "};/*----------------------串口定义-------------------*/unsigned char SetPrintfConvertMode=0; //使用printf作其他转换,并非输出到UARTvoid Uart_Init(void);int System_putchar(char c, FILE *stream);int System_getchar(FILE *stream);FILE mystd = FDEV_SETUP_STREAM(System_putchar,System_getchar,_FDEV_SETUP_RW);/*----------------------常用函数定义------------------*/void delay_nms(unsigned int ms) //N ms延时函数{for(i=0;i<ms;i++)_delay_loop_2(FREQ*250);}/*----------------------系统初始化函数定义------------------*/void IO_INIT(void){PORTB|=_BV(P0); //设置ICP引脚内部上拉经过试验验证,上拉会提高红外接收灵敏度}ISR(TIMER1_COMPA_vect){IRReceiveCurrentBit=0;//重置IR接收位为第0位,为下次接收做准备TIMSK&=~_BV(OCIE1A); //关闭溢出中断TCCR1B|=_BV(ICES1); //设置输入捕获上升沿有效ICP_Parity=0;Stop_T1;CLR_IR_LED;}ISR(TIMER1_CAPT_vect){if(!IRReceiveEffective){if(ICP_Parity==0){ICP_Parity++;TIMSK|=_BV(OCIE1A);TCCR1B&=~_BV(ICES1); //设置输入捕获下降沿有效Start_T1 ;}else{Stop_T1;ICP_Parity=0;TCCR1B|=_BV(ICES1);//设置输入捕获上升沿有效Pulse_length=ICR1;if(IRReceiveCurrentBit==0){if(Pulse_length>=3500&&Pulse_length<5500)// 如果是引导码(4.5ms) 进入下一个bit的读取IRReceiveCurrentBit++;}else if(IRReceiveCurrentBit<33) //接收32位数据{IRcode>>=1;if(Pulse_length<1900&&Pulse_length>1400) //判断是否为1 ( 1.685 ms) IRcode|=0x80000000;IRReceiveCurrentBit++;if(IRReceiveCurrentBit==33){IRReceiveCurrentBit=0; //重置IR接收位为第0位,为下次接收做准备if(IRcodePointer[0]==(unsignedchar)(~IRcodePointer[1])&&IRcodePointer[2]==(unsignedchar)(~IRcodePointer[3])){SET_IR_LED; //开启IR信号指示灯IRReceiveEffective=1; //数据有效}delay_nms(5); //因为32位数据后面还有一个信号上跳变,所以要适当延时,延时0.65ms以上即可}}}}}/////////////////////////////////////////////////////////////////int main(void){wdt_disable();IO_INIT();Uart_Init();TCCR1B=_BV(WGM12)|_BV(CS11);//采用8分频这样的话TCNT1的计数时基为1usOCR1A=8000; //TCNT1 计数上限设置IR接收超时这里设置8msTIMSK|=_BV(TICIE1);//开启输入捕获中断TCCR1B|=_BV(ICES1);//输入捕获上升沿有效EN_IR_LED; //IR信号指示灯允许CLR_IR_LED; //关闭IR信号指示灯IRcodePointer=&IRcode;sei();while(1){if(IRReceiveEffective){Received_Key_Temp=IRcodePointer[2];//把接收到的操作键放入缓存IRReceiveEffective=0; //允许下一次接收switch(Received_Key_Temp){case Key_1 : printf("\n%sKey_1",String);break;case Key_2 : printf("\n%sKey_2",String);break;case Key_3 : printf("\n%sKey_3",String);break;case Key_4 : printf("\n%sKey_4",String);break;case Key_5 : printf("\n%sKey_5",String);break;case Key_6 : printf("\n%sKey_6",String);break;case Key_7 : printf("\n%sKey_7",String);break;case Key_8 : printf("\n%sKey_8",String);break;case Key_9 : printf("\n%sKey_9",String);break;case Key_0 : printf("\n%sKey_0",String);break;case Menu : printf("\n%sMenu",String);break;case Menu_up : printf("\n%sMenu_up",String);break;case Menu_down : printf("\n%sMenu_down",String);break;case Menu_left : printf("\n%sMenu_left",String);break;case Menu_right : printf("\n%sMenu_right",String);break;case Menu_ok : printf("\n%sMenu_ok",String);break;case Channel_up : printf("\n%sChannel+",String);break;case Channel_down : printf("\n%sChannel-",String);break;case Sound_up : printf("\n%sSound+",String);break;case Sound_down : printf("\n%sSound-",String);break;case Open_Close : printf("\n%sOpen_Close",String);break;case Mute : printf("\n%sMute",String);break;case Standard : printf("\n%sStandard",String);break;case Return : printf("\n%sReturn",String);break;case Times : printf("\n%sTimes",String);break;//case Screen : printf("\n%sScreen",String);break;//Screen 与menu_ok 值相同case Audio : printf("\n%sAudio",String);break;case NICAM : printf("\n%sNICAM" ,String);break;case TV_Vedio : printf("\n%sTV_Vedio",String);break;case Sleep : printf("\n%sSleep",String);break;case Pic_in_pic : printf("\n%sPic_in_pic",String);break;default:printf("\n%sOther Key 0x%x",String,Received_Key_Temp);break;}CLR_IR_LED; //处理完数据以后关闭IR信号指示灯}}}/*----------------------串口函数实体------------------*/void Uart_Init(void){UCSRB=_BV(RXEN)|_BV(TXEN);UBRRL=25; //8M 19200stdout=&mystd;stdin=&mystd;}int System_putchar(char c, FILE *stream){if(SetPrintfConvertMode==1){}else{if (c == '\n')System_putchar('\r', stream);loop_until_bit_is_set(UCSRA, UDRE);UDR = c;}return 0;}int System_getchar( FILE *stream){loop_until_bit_is_set(UCSRA,RXC);return UDR;}/////////////////////////////////程序结束////////////////////////////。
红外遥控解码程序红外接收头的型号有很多HS0038 VS838等功能⼤致相同,只是引脚封装不同。
红外接收有⼏种统⼀的编码⽅式,采样哪种编码⽅式取决于遥控器使⽤的芯⽚,接收头收到的都是⼀样的。
电视遥控器使⽤的是专⽤集成发射芯⽚来实现遥控码的发射,如东芝TC9012,飞利浦AA3010T等,通常彩电遥控信号的发射,就是将某个按键所对应的控制指令和系统码(由0和1组成的序列),调制在38KHz的载波上,然后经放⼤、驱动红外发射管将信号发射出去。
不同公司的遥控芯⽚,采样的遥控码格式也不⼀样,较普遍的有两种,⼀种NEC标准,⼀种是PHILIPS标准。
NEC标准:遥控载波的频率为38KHz(占空⽐1:3)当某个键按下时,系统⾸先发射⼀个完整的全码,如果按键超过108ms仍未松开,接下来发射的代码(连发代码)将由起始码(9ms)和结束码(2.5ms)组成。
⼀个完整的全码 = 引导码 +⽤户码 +⽤户码 + 数据码 + 数据码 + 数据反码。
其中,引导码⾼电平9ms,低电平4.5ms;系统码8位,数据码8位,共32位;其中前16位为⽤户识别码,能区别不同的红外遥控设备,以防⽌不同的机种遥控码互相⼲扰。
后16位为8位的操作码和8位的操作反码,⽤于核对数据是否接收准确。
收端根据数据码做出应该执⾏上⾯动作的判断。
连发代码是在持续按键时发送的码。
它告知接收端。
某键是在被连续的按着。
NEC标准下的发射码表⽰发射数据0时⽤”0.56ms⾼电平 + 0.565ms低电平 = 1.125ms”表⽰;数据1⽤”⾼电平0.56ms + 1.69ms = 2.25ms”表⽰。
遥控器发射信号:需要注意的是:当⼀体化接收头收到38kHz红外信号时,输出端输出低电平,否则为⾼电平。
所以⼀体化接收头输出的波形和发射波形是反向的PHILIPS标准:载波频率38KHz:没有筒,点按键时,控制码1和0之间切换,若持续按键,则控制码不变。
⼀个全码 = 起始码’11’ +控制码 + ⽤户码 + ⽤户码数据0⽤“低电平1.778ms + ⾼电平1.778ms”表⽰;数据1⽤“⾼电平1.778ms + 低电平1.778ms”表⽰。
红外解码程序本篇介绍红外解码的原理和程序的写法。
下面来看一下,红外线是如何编码的。
下面来具体说一下,解码的原理,每按一下遥控器的一个按键,遥控器就会发出32个“0”“1”代码(当然是通过高低电平的占空比来判断是0还是1的),具体是0,1是如何编码的上面图片中有介绍,和一个引导码,引导码的作用是告诉处理器,接下来将要开始发送代码,我们在编写程序时,当检测到引导码时,就应该准备接受数据了。
32位代码中的前16位是用户识别码,不同的遥控器不相同,防止互相干扰的,后16是8为数据码,和8位数据反码。
接下来开始介绍如何解码程序的编写。
程序中用到了两个中断,一个是定时器中断,一个是外部中断。
定时器中断用来准确计时,判断接受的代码是0还是1,外部中断用来准确确定定电平到来的时刻,然后开始计时。
/*********************************************************函数功能:红外解码,用八位数码管显示红外线的按键码,便于红外控制测试环境:hot 51学习板编译环境:keil4整理人:张家越QQ:435835181整理时间:2011-04-03************************************************************/#include<reg51.h>#define uchar unsigned char#define uint unsigned intuchar code seg_du[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0 x6f,0x77,0x7c,0x39,0x5E,0x79,0x71 };//0-f的段选码unsigned char code seg_we[]={0,1,2,3,4,5,6,7};uchar irtime,startflag,bitnum,irreceok;uchar irdata[33];uchar irprosok;uchar display[8];uchar ircode[8] ;sbit led1=P0^1;sbit led2=P0^2;/******************************************************************** ****函数功能:延时函数,在数码管显示时使用,不需要很精确********************************************************************* ****/void delay_50us(uint t){uchar j;for(;t>0;t--)for(j=19;j>0;j--);}/******************************************************************** ******函数的功能:定时器0的初始化********************************************************************* *****/void timer0init(){TMOD=0x02; //设置定时器工作在方式2TH0=0x00; //TL0=0x00; //设置定时器的初值ET0=1; //开定时器中断TR0=1; // 打开定时器EA=1; //开总中断}/******************************************************************** ****外部中断1的初始化********************************************************************* **/void int1init(){IT1=1; //设置触发方式为上升沿EX1=1; //开外部中断1EA=1; //开总中断}/******************************************************************** **定时器0的功能函数,每中断一次irtime++,用于计时********************************************************************* **/void timer0() interrupt 1{irtime++; //定时器中断一次irtime++,用于计时}/******************************************************************** ***外部中断0的处理函数,每当有低电平数据过来时,中断一次,(使用次中断的前提是,信号线必需接在外部中断0上面,也就是P3^2口),函数功能是,把信号从高低电平变成时间的代码放入irdata【】中********************************************************************* ***/void int1() interrupt 2{if(startflag){if(irtime>32) //一组代码检测完毕{bitnum=0;}irdata[bitnum]=irtime; //把检测到的时间送到数组irdata【】中去irtime=0;bitnum++;if(bitnum==33) //如果检测到bitnum=33,说明32位用户码已经检测完毕{bitnum=0; //将bitnum清零以便重新计数irreceok=1; //接收完毕标志位置一}}else //(此函数先进入else语句,跳过引导码的检测){startflag=1; //将开始标志位置一irtime=0; //设置时间初值为零irreceok=1; //接收完毕标志位置一}}/******************************************************************** *****函数功能:把irdata【】中的时间代码转换成二进制代码存放在ircode【】中********************************************************************* *****/void irpros(){uchar k=1,value,j,i;for(j=0;j<4;j++){for(i=0;i<8;i++){value=value>>1; //右移7次(第一次是00,相当于没有移位)if(irdata[k]>6) //循环8次{value=value|0x80;}k++;}ircode[j]=value;}irprosok=1;}/******************************************************************** ********函数的功能是:将ircode【】中的二进制代码转换成为16进制代码便于在数码管上显示******************************************************************* ********/void irwork(){display[0]=ircode[0]/16;display[1]=ircode[0]%16;display[2]=ircode[1]/16;display[3]=ircode[1]%16;display[4]=ircode[2]/16;display[5]=ircode[2]%16;display[6]=ircode[3]/16;display[7]=ircode[3]%16;}/******************************************************************** ****函数功能:用数码管显示解码结果********************************************************************* ***/void display1(){uchar i;for(i=0;i<8;i++){P2=seg_we[i];P0=seg_du[display[i]];delay_50us(40);}}void main(){timer0init(); //定时器初始化int1init(); //外部中断初始化while(1){if(irreceok) //判断数据接收完毕(数组中存储的是高低电平的时间){irpros(); //执行处理函数,将高低电平时间转化成16进制的0,1代码,存放在数组中irreceok=0; //标志清零}if(irprosok) //处理函数执行完毕,{irwork(); //将存储的16进制代码分离,便于数码管显示irprosok=0; //标志清零}display1();}}//在最后我再分析一下程序的编写思路,便于大家理解,一旦有按键按下,接受管接收到引导码,进入外部中断,并将高低电平的时间放入irdata【】数组中,接受完毕标志位置一,判断接受标志位,为1,进行处理函数,将高低电平转换成16进制数,处理标志位置一,判断处理标志位,为1,执行分离函数,将16进制数分离,便于数码管显示,分离完毕后显示。
用单片机解码红外遥控器遥控器使用方便,功能多.目前已广泛应用在电视机、VCD、DVD、空调等各种家用电器中,且价格便宜,市场上非常容易买到。
如果能将遥控器上许多的按键解码出来.用作单片机系统的输入.则解决了常规矩阵键盘线路板过大、布线复杂、占用I/O口过多的弊病。
而且通过使用遥控器,操作时可实现人与设备的分离,从而更加方便使用。
下面以TC9012编码芯片的遥控器为例。
谈谈如何用常用的51系统单片机进行遥控的解码。
一、编码格式1、0和1的编码遥控器发射的信号由一串O和1的二进制代码组成.不同的芯片对0和1的编码有所不同。
通常有曼彻斯特编码和脉冲宽度编码。
TC9012的O和1采用PWM方法编码,即脉冲宽度调制,其O码和1码如图1所示(以遥控接收输出的波形为例)。
O码由O.56ms低电平和0.56ms高电平组合而成.脉冲宽度为1.12ms.1码由0.56ms低电平和1.69ms高电平组合而成.脉冲宽度为2.25ms。
在编写解码程序时.通过判断脉冲的宽度,即可得到0或1。
2、按键的编码当我们按下遥控器的按键时,遥控器将发出如图2的一串二进制代码,我们称它为一帧数据。
根据各部分的功能。
可将它们分为5部分,分别为引导码、地址码、地址码、数据码、数据反码。
遥控器发射代码时.均是低位在前。
高位在后。
由图2分析可以得到.引导码高电平为4.5ms,低电平为4.5ms。
当接收到此码时.表示一帧数据的开始。
单片机可以准备接收下面的数据。
地址码由8位二进制组成,共256种.图中地址码重发了一次。
主要是加强遥控器的可靠性.如果两次地址码不相同.则说明本帧数据有错.应丢弃。
不同的设备可以拥有不同的地址码.因此。
同种编码的遥控器只要设置地址码不同,也不会相互干扰。
图中的地址码为十六进制的0EH(注意低位在前)。
在同一个遥控器中.所有按键发出的地址码都是相同的。
数据码为8位,可编码256种状态,代表实际所按下的键。
数据反码是数据码的各位求反,通过比较数据码与数据反码.可判断接收到的数据是否正确。
资料整理自互联网,版权归原作者! 欢迎访问 新势力单片机,嵌入式
专业技术论坛:
红外线遥控器解码程序
Wang1jin 收藏. 交流论坛: / 推荐网站: 个人博客:
红外线遥控是目前使用最广泛的一种通信和遥控手段.由于红外线遥控装置具有体积小,功耗低,功能强,成本低等特点,因 而,继彩电,录像机之后,在录音机,音响设备,空凋机以及玩具等其它小型电器装置上也纷纷采用红外线遥控.工业设备中, 在高压,辐射,有毒气体,粉尘等环境下,采用红外线遥控不仅完全可靠而且能有效地隔离电气干扰.
1 红外遥控系统
通用红外遥控系统由发射和接收两大部分组成,应用编/解码专用集成电路芯片来进行控制操作,如图 1 所示.发射部分 包括键盘矩阵,编码调制,LED 红外发送器;接收部分包括光,电转换放大器,解调,解码电路.
2 遥控发射器及其编码
遥控发射器专用芯片很多,根据编码格式可以分成两大类,这里我们以运用比较广泛,解码比较容易的一类来加以说明, 现以日本 NEC 的 uPD6121G 组成发射电路为例说明编码原理.当发射器按键按下后,即有遥控码发出,所按的键不同遥控编码 也不同.这种遥控码具有以下特征:
采用脉宽调制的串行码,以脉宽为 0.565ms,间隔 0.56ms,周期为 1.125ms 的组合表示二进制的"0";以脉宽为 0.565ms, 间隔 1.685ms,周期为 2.25ms 的组合表示二进制的"1",其波形如图 2 所示.
个人博客:
电子综合站点:
资料整理自互联网,版权归原作者! 欢迎访问 新势力单片机,嵌入式
专业技术论坛:
上述"0"和"1"组成的 32 位二进制码经 38kHz 的载频进行二次调制以提高发射效率,达到降低电源功耗的目的.然后 再通过红外发射二极管产生红外线向空间发射,如图 3 所示.
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.5m s)组成.
代码格式(以接收代码为准,接收代码与发射代码反向)
①位定义
个人博客:
电子综合站点:
资料整理自互联网,版权归原作者! 欢迎访问 新势力单片机,嵌入式
专业技术论坛:
②单发代码格式
③连发代码格式
注:代码宽度算法:
16 位地址码的最短宽度:1.12×16=18ms
易知 8
16 位地址码的最长宽度:2.24ms×16=36ms
位数据代码及其 8 位反代码的宽度和不变:(1.12ms+2.24ms)×8=27ms
∴32
位代码的宽度为(18ms+27ms)~(36ms+27ms)
个人博客:
电子综合站点:
资料整理自互联网,版权归原作者! 欢迎访问 新势力单片机,嵌入式
专业技术论坛: 1. 解码的关键是如何识别"0"和"1",从位的定义我们可以发现"0","1"均以 0.56ms 的低电平开始,不同的是高电平 的宽度不同,"0"为 0.56ms,"1"为 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 的结果码完成后才能读码.
如果邮购我们开发的 51 单片机试验板和扩展元件的网友, 可以获得如上图所示的红外遥控手柄, 这种遥控器的编码格式符合上 面的描述规律, 而且价格低廉,有 32 个按键, 按键外形比较统一,如果用于批量开发,可以把遥控器上贴膜换成你需要的字符, 这为开发产品提供了便利.
接收器及解码
一体化红外线接收器是一种集红外线接收和放大于一体,不需要任何外接元件,就能完成从红外线接收到输出与 TTL 电 平信号兼容的所有工作,而体积和普通的塑封三极管大小一样,它适合于各种红外线遥控和红外线数据传输.
下面是一个对 51 实验板配套的红外线遥控器的解码程序, 它可以把上图 32 键的红外遥控器每一个按键的键值读出来, 并 且通过实验板上 P1 口的 8 个 LED 显示出来,在解码成功的同时并且能发出"嘀嘀嘀"的提示音.
这是站长最新用单片机 AT89C51 制作的 30 路红外遥控器, 遥控器就是自家的 VCD 遥控器,接收板用了 5 片 CD4069 作为输出 缓冲隔离,当按下遥控器 30 个按键中的一个,接收板对应的一个触点会变成高电平,松开按键,立即恢复成低电平,和 TTL 兼容.
最下面给大家介绍几个下载资料的地方: 51 学习专区: / USB 学习专区: / CAN 学习专区:
个人博客: 电子综合站点:
资料整理自互联网,版权归原作者! 欢迎访问 新势力单片机,嵌入式
专业技术论坛:
AVR 学习专区: / FPGA 学习专区: / STM32 学习专区: / ARM 学习专区: / DSP 学习专区: / PIC 学习专区: / DIY 电子制作专区: / GPS 学习专区: / GUI 学习专区: / EDA 软件学习专区: / 电源学习专区: /
个人博客: 电子综合站点:
。