本篇介绍红外解码的原理和程序的写法。
下面来看一下,红外线是如何编码的。

下面来具体说一下,解码的原理,每按一下遥控器的一个按键,遥控器就会发出32个“0”“1”代码(当然是通过高低电平的占空比来判断是0还是1的),具体是0,1是如何编码的上面图片中有介绍,和一个引导码,引导码的作用是告诉处理器,接下来将要开始发送代码,我们在编写程序时,当检测到引导码时,就应该准备接受数据了。32位代码中的前16位是用户识别码,不同的遥控器不相同,防止互相干扰的,后16是8为数据码,和8位数据反码。
接下来开始介绍如何解码程序的编写。
程序中用到了两个中断,一个是定时器中断,一个是外部中断。定时器中断用来准确计时,判断接受的代码是0还是1,外部中断用来准确确定定电平到来的时刻,然后开始计时。
/*********************************************************
函数功能:红外解码,用八位数码管显示红外线的按键码,便于红外控制
测试环境:hot 51学习板
编译环境:keil4
整理人:张家越 QQ:435835181
整理时间:2011-04-03
************************************************************/
#include<>
#define uchar unsigned char
#define uint unsigned int
uchar code seg_du[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,
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; //设置定时器工作在方式2
TH0=0x00; //
TL0=0x00; //设置定时器的初值
ET0=1; //开定时器中断
TR0=1; // 打开定时器
EA=1; //开总中断
}
/************************************************************************
外部中断1的初始化
***********************************************************************/
void int1init()
{
IT1=1; //设置触发方式为上升沿
EX1=1; //开外部中断1
EA=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进制数分离,便于数码管显示,分离完毕后显示。
编程技巧:善用标志位,是程序的层次感很强,便于阅读,修改和调试。
改程序已通过调试!
联系方式:435835181@