基于51单片机 的红外遥控解码设计

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Imkiimki/article/details/53047045

红外线遥控在生活中有着广泛的应用,比如空调,电视,音响,机顶盒等。红外线遥控实际上就是一种通信方法,利用LED发射红外线,接收器接收到数据,进行处理后就可以得到发送端的信号。利用一个简单的红外线发光二极管,我们可以制作万能遥控器。众所周知,电视机的遥控不能控制空调,甚至不同的电视机遥控只能控制自己的电视。这是因为红外遥控都遵循了一个协议,从而保证稳定和可靠。最常见的是日本的NEC芯片下的协议。在该协议下,红外信号以38Khz的红外波作为载波信号,以9ms的高电平和4.5毫秒的低电平作为引导码,然后是8位客户码1,8位客户码28位操作码,8位操作反码(如图)。基于51单片机 的红外遥控解码设计 - 锋锋 - Dale的博客

 这些信号的作用分别如下:客户码12:用于区分不同的设备,比如不同品牌的电视遥控之间有着不同的客户码,因而可以相互识别,不至于产生干扰。操作码:包含了遥控正在所要传输的操作信息;操作码反码就是操作码取反后的数据,作用在与对操作码进行校验,收到信号后对操作码和操作码反码进行比较,如果发现差异,这说明数据传输过程中出现了干扰,这次接收就要忽略。

   接收的原理是采用光敏二极管,受红外线照射产生电信号。实际中使用红外一体化接收头,只能选择性接收38Khz的红外信号,增加了抗干扰的能力,其内部有增益电路和滤波电路,直接输出高低电平。需要注意的是接收头输出的信号和发射信号反相了。如下图所示:

可以看到,接收到的信号无论是0还是1,都首先是一个下降沿,只不过是间隔的时间不同罢了,因此,我们可以将接受头接到P3.2口,用中断的方法得到每个位,记录下间隔时间,再写程序判断是0还是1即可。

 

讲完理论知识,回到我们最初的目标:用单片机制作遥控器。那么首先面临的问题就是要获取配套遥控器的编码信息。本文将讲述如何用单片机接收NEC协议下的编码信号,然后在数码管上显示出来。

我们的思路是首先识别引导码,确认接下来是一个发射的信号后将48位信号(共32位)储存起来。这可以利用中断来实现,实际上记录的是中断间隔时间(用计时器周期来表示)在void int0 () interrupt 0中定义了数组bitnum[],存储一个引导码和32位信号数据。

然后通过中断时间的判断,得知是0还是1。这一部分在void irpros(void)中实现。将处理后的结果放到ircode[]里去。

第三步:将ircode[]里的数据转化为16进制,便于在数码管上显示。

配套数码管显示函数,将以上几步用main函数串起来就实现了红外编码的获取。

最终效果基于51单片机 的红外遥控解码设计 - 锋锋 - Dale的博客

#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit ir=P3^2;
sbit beep=P2^3;
uchar irtime;
uchar irdata[33];
uchar bitnum;
uchar startflag;
uchar irok;
uchar ircode[4];
uchar irprosok;
uchar disnum[8]={0,0,0,0,0,0,0,0};

sbit dula=P2^6;
sbit wela=P2^7;
uchar code table_du[]={
0x3f,0x06,0x5b,0x4f,0x66,0x6d,
0x7d,0x07,0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};
uchar code table_we[]={
0xfe,0xfd,0xfb,0xf7,0xef,0xdf};

void timer0init(void) //256*(1/12m)*12=0.256ms
{
	TMOD=0x02;
 	TH0=0x00;
 	TL0=0x00;
	ET0=1;
	EA=1;
	TR0=1;
}


void irpros(void) // 红外码值处理
{
	uchar mun,k,i,j;
	k=1;
	for(j=0;j<4;j++)
	{
		for(i=0;i<8;i++)
		{
			mun=mun>>1;
			if(irdata[k]>5)
			{
				mun=mun | 0x80;
			}
				k++;
		}
		ircode[j]=mun;
	}
	irprosok=1;
}

void irwork(void) // 红外码值转换
{
	disnum[0]=ircode[0]/16;
	disnum[1]=ircode[0]%16;
	disnum[2]=ircode[1]/16;
	disnum[3]=ircode[1]%16;
	disnum[4]=ircode[2]/16;
	disnum[5]=ircode[2]%16;
	disnum[6]=ircode[3]/16;
	disnum[7]=ircode[3]%16;

}

delay(uchar x)
{
	uchar a,b;
	for(a=x;a>0;a--)
		for(b=200;b>0;b--);

}

display()
{
	uchar i;
	for(i=0;i<6;i++)
	{
		//P0=0xff;
		wela=1;
		wela=0;
			
		 P0=table_du[disnum[i]];
		 dula=1;
		 dula=0;
		P0=table_we[i];
		wela=1;
		wela=0;
		delay(10);
	}
}

void int0init(void)
{
 IT0=1;
 EX0=1;
 EA=1;
}


void main()
{
	timer0init();
	int0init();
	while(1)
	{
		if(irok==1)
		{
			irpros();
			irok=0;
		}
		if(irprosok==1)
		{
			irwork();
			irprosok=0;
		}
		// display(); 
	}
		
}

void int0 () interrupt 0 //中断服务
{
if(startflag)
 {
  if(irtime>32&&irtime<63)  //8-16ms
	{  beep=1;
	   bitnum=0;
	}
	irdata[bitnum]=irtime;
	irtime=0;
	bitnum++;
	if(bitnum==33)
	  {	  beep=~beep;
	   bitnum=0;
	   irok=1;
	  }	
 }
else
 {
 irtime=0;
 startflag=1;
 }
}

void timer0 () interrupt 1
{
	irtime++;
}


 

 

现在,离制作万能遥控只有一步之遥了,只需要把得到的编码用二极管输出就大功告成。

 

附获取编码的全部代码

—————————————————————————————————————

 
  

猜你喜欢

转载自blog.csdn.net/Imkiimki/article/details/53047045