单片机实现红外接收解码摘要:接收到红外遥控器的脉冲波形,并通过解析其波形得到红外遥控器的相应解码,实习 对相应设备的控制本文详细接受红外遥控技术原理并如何通过C51单片机实现红外遥控 关键字:单片机,红外遥控,解码遥控器相信人家不会陌生,口常生活中会使用到各种各样的遥控器,比如电视机、DVD 机、空调、机顶盒甚至音响、热水器等都用到遥控器,其实红外技术已经走进与人们的生活 并且与人们的生活息息相关了红外遥控器作为设备的输入控制具有操作简便、价格便宜等诸多好处您可以根据您公 司产品需要和遥控器提供商协商定制遥控器,包括遥控器键盘布局、每个按键的键码等遥控器键盘上每个按键的键码是一个小于256的一个数值,按键后通过遥控器红外管产 生脉冲发送出去,红外接收器接收到脉冲后,对脉冲流进行分析,提取键码值,并按照键码 值实现其遥控目的2 •红外接收原理红外遥控信号接收:红外接收电路可以使用集成接收器,接收器包括红外接收管及信号处理ic,接收器对 外只有三个引脚,一个接电源的Vcc脚、一个接地的GND脚、一个脉冲信号输出脚,当然 脉冲信号输出脚直接接单片机的某个可以使用的IO脚就可以了 zzJ)虹外接收部分3 •脉冲波形分析:每次按键,红外接收器这边会收到一串脉冲宽度不等的脉冲波形流,其脉冲流由35个 脉冲波形构成:前导码:第1个脉冲波形用户码1:第2到第9个脉冲波形用户码2:第10到第17个脉冲波形键码:第18到第25个脉冲波形键码反码:第26到第33个脉冲波形连续按键脉冲:第34和第35个脉冲为结束脉冲(也即连续按键脉冲),在每次按键结 束后会有两个结束脉冲,如果一直按键不放的话,会一直发送连续按键脉冲,并可以认为在 收到10个连续按键脉冲后是下一个按键。
注意:不同的遥控器产生的用户码值可能不一样,笔者碰到两种不同的用户码:0x00, OxFF 及 0x04, 0x7Fo脉冲流中有四种不同的脉冲波形宽度:其中前导码脉宽为:40(4ms) <脉冲宽度< 50(5ms)连续按键脉宽为:21(2.1ms)<脉冲宽度<25(2.5ms)bit "0"脉宽为: 3(0.3ms) < 脉冲宽度 < 7(0.7ms)bit "1"脉宽为: 14(1.4ms) < 脉冲宽度 <19(1.9ms)在收到一串脉冲流后,就要对其进行分析,先要检测第一个脉冲波形是不是前导码,如 果不是,则继续检测前导码,如果是则检测如下32个脉冲波形:用户码1为1字节,由8个脉冲波形组成(其中一个脉冲波形表示字节中1 bit):用户码2为1字节;键值为1字节;键值反码为1字节,键值反码为键值取反值先判断所收到用户码是否正确,如果不正确则丢弃此次所收键码,如呆正确则利用键值 反码取反与键值比较,判断收码是否正确,如果不正确则丢弃所收键码如下图所示:前导码:用户跖键码:结束码: L从上图可以看出其用户码为:ObOOlOOOOO-OblllllllO,由于其低位在前,故转换后得 到用户码为:ObOOOOOlOO-ObOlllllll,即 0x04, 0x7F;其键码及键码反码为:ObOOOlOOlO-OblllOllOl,同样也是低位在前,转换后得到键码 及键码反码为:ObOlOOlOOO-OblOUOlll,即 0x48, 0xB7。
4 •实现:4.1初始化初始化时当然要先初始化单片机红外接收管脚为高阻输入状态,其次要初始化定时 器,因为检测分析脉冲波形时需要用到定时器,根据上面对脉冲流波形分析可以知道最 窄的脉宽为bit “0”,为0.3ms左右,所以定时器最好定时为每0.1ms中断一次比较好, 但是定时器的值怎么设置呢,这样根据单片机的振荡器决定4.2脉冲波形分析首先当然是检测前导码,单片机红外接收管脚在初始化时已经设置为高阻输入状态 (即高电平状态),当有红外输入时,状态变为低电平状态,一旦检测到有低电平过来, 则开始准备检测前导码得到每个脉冲波形序号,并根据定时器统计出每个脉冲波形在 高电平状态维持的时间,通过其时间值检测第一个脉冲是否是前导码,如果不是则重新 检测前导码,如果是前导码则分析其后每个脉冲波形是bit “0”,还是bit “1”,并按 顺序每八个波形为一个字节方式保存到用户码1字节变量、用户码2字节变量、键码字 节变量、键码反码字节变量,直到收满32个bits4.3收码判断所收到的用户码是否正确、键码及键码反码是否正确,如果都正确则认为此次 收码为正确收码,否则丢弃收码完后,还会有结束脉冲波形,如果用户一直按住某个键不放,遥控器会一直发 送连续按键脉冲波形,如果多次收到连续按键,町以认为再次收到键码,这个可以根据 实际需要定。
5 •程序代码#include #define umt unsigned mt#define uchai unsigned char uchar code table[]={0x3f,0x06,0x5b,0x4£0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39, 0x5e,0x79, 0x71};uchar code weitable[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf;0x7f};uchar irnum; //定时器0定时时间计数uchar bitnum; 〃存放接收到的位数uchai staitflag; //开始标志uchai irdata[33];uchar ineceok=0; 〃判断是否接收到一帧数据,33位uchai ircode[4]; //存放 4 个码值uchai uprosok;uchar disp[8];sbit LS138A=P2A2;sbit LS138B=P2A3;//138译码器的A端由P2.2 1 1控制//138译码器的B端由P2.3 1 1控制sbit LS138C=P2A4;//138译码器的C端由P2.4 1 1控制void delay(uint i) {uchar j;〃定时1msfbr(i;i>O;i-) foi-0=110j>0j-);} void init() 〃初始化 TO, exter 0 {IT0=l;//外部中断,下降沿触发IE0=l; 〃外部中断0允许EX0=l; 〃开中断〃定时计数器0中断TMOD=0x02; // 工作方式 1,16 位THO=OxOO; 〃定时 0・256msTLO=OxOO;ETO=1;〃开中断EA=1;TRO=1;//定时计数器启动中断}void upros(void) //解码{uclw i,j,k;uclw value;k=l;for(j=0j<4j++){for(i=0;i<8;i++){value=value»l;if(irdata[k]>6)//^收的数据为 0 或 1,0 为 1.125ms<5,l 为 2.25 约 8〜9,曲中间 value=value|0x80:k++;}iicode[j]=value; 〃编码值给 ircode,value=0;}uprosok= 1; 〃红外数据提取完毕}〃显示,要将接收到的码拆开8位显示void irxvoik(void) 〃将接收到的码拆开显示{ _disp[0]=ircode[0]/16; //按 16 进制显示disp[l]=ircode[0]%16;disp[2]=ircode[ 1 ]/16;disp[3]=ircode[l]%16;disp[4]=ircode[2]/16; //按 16 进制显示disp[5]=ircode[2]%16;disp[6]=iicode[3]/16;disp[7]=ircode[3]%16;}void displav(void) 〃送到数码管显示LS138C=0;LS 138B=0;LS 138A=0; PO=table[disp[O]]; delav(lO); 〃第一个 数码管显示1〃第一个数码管LS 138C=0;LS 138B=0;LS 138A= 1; PO=table[disp[l]]; delay(10); 显示2LS 138C=O;LS 138B= 1 ;LS 138A=0; P0=table[disp[2]]; delav(lO);LS 138C=0;LS 138B= 1 ;LS 138A= 1; PO=table[disp[3]]; delav(lO);LS 138C= 1 ;LS 138B=0;LS 138A=0; P0=table[disp[4]]; delav(lO);LS 138C= 1 ;LS 138B=0;LS 138A= 1; PO=table[disp[5]]; delay(10);LS 138C= 1 ;LS 138B= 1 ;LS 138A=0; P0=table[disp[6]]; delav(lO); LS138C=1;LS138B=1;LS138A=1; PO=table[disp[7]]; delav(lO);}void main(){imtQ;while(l){if(iireceok) //若接收到数据{uprosQ; 〃解码iireceok=0;}if(irpiosok) 〃数据解码完毕拆开显示{iiAvorkQ;uprosok=0;}displayQ;}}void exterOQ iiitemipt 0{if(iinum>50) 〃收到引导码、14.5ms{stailflag=l;bitnum=0;}if(startflag){iidata[bitnum]=iinum; //将接收到的数据放入 irdata irnum=0;bitnum+-r;if(bitnum=33)ureceok= 1; 〃接收到一帧数据 start flag=O:}}}void timeiOQ mtemipt 1{irnum++; //定时时间 irnum*0.256nis}。