51单片机红外模块学习,必会解读

 

这篇文章是我学习红外模块的时候的一些心得和体会,并附带个人对于这块的理解,希望能够对大家有帮助。

首先一点的就是红外发射信号后,单片机上接受数据部分

51单片机红外模块学习,必会解读_第1张图片

51单片机红外模块学习,必会解读_第2张图片

这是常见的接收模块,负责接受发射出的调制波,还有整个遥控部分的示意图51单片机红外模块学习,必会解读_第3张图片

这个就是调制后的波,我们可以看到,最开始有一个引导码,这个是由NEC协议决定的,然后是客户码,可以类比为钥匙,这个对孔后就可以开门了,最重要的就是操作码,这个就是要发送的信息,最后有一个操作反码,用于校验操作码是否正确。

接着就到了红外接收部分,先看一下流程:

51单片机红外模块学习,必会解读_第4张图片

引导码出现以后,进行一下延时判断(代码没有判断,因为比较简单),

然后,重点就来了

51单片机红外模块学习,必会解读_第5张图片

 

主要过程看下边信号的时间轴,发生事件后去看timer0的时间轴,很容易就能理解了

一开始的跳变沿产生一次中断,但这时候flag = 0,所以就进入timer0 = 0,flag = 1,注意!!!!这时候信号已经在传输了,timer0正在计时,当下一个跳变沿产生,也就是这一位信号传输完成时,又一次进入中断,这时候flag = 1,所以就进入到保存timer0的值,i++,然后把timer0重新置零,然后timer0 重新计时,传输下一位数据,再产生一次跳变沿,再读走时间,重复下去,直到i=33,也就是传了33位数据之后,停止接受,并将接受完成位置一。

之后对数据进行解码,也就是根据时间长短,判断数据是0还是1,并将数据按8位,一字节存入之前定义的数组中,这时候数组中第三个就是要传输的数据了,整个过程完成。

#include
#define uchar unsigned char
#define uint unsigned int    
sbit IR=P3^2;  
#define DataPort P0 //定义数据端口 
sbit du=P2^6;//                    段锁存
sbit we=P2^7;//                 位锁存
uchar table[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};// 显示段码值0~9
uchar  irtime;//红外用全局变量,存储红外带宽
bit ir_ok;//存储完成标志位
bit irpro_ok;    //解码完成标志位
uchar irdata[33];
uchar irbyte[4];
void inter0_init()    //定时器0初始化    ok
{
    TMOD |= 0X02;
    TH0 = TL0 = 0;
    ET0 = 1;
    TR0 = 1;
}
void timer0() interrupt 1 using 1        //ok
{
    irtime++;
}
void inter0_ex()         //外部中断0初始化函数
{
    EA = 1;    
    IT0 = 1; 
    EX0 = 1;  //开外部中断0
}
void ex0_play()interrupt 0 //外部中断0处理函数 ok
{
    static bit flag;//开始处理标志位
    static uchar i;//存储33位数据 
    if(flag)
    {
        if(irtime<63&&irtime>=33)//开始标志信号持续时间,这个和具体晶振频率有关
        i = 0;
        irdata[i] = irtime;
        irtime=0;
        i++;//处理下一位
        if(i == 33)
        {
            ir_ok = 1;
            i = 0;
        }
    }
    else
    {
        flag = 1;  //开始标志位置1
        irtime = 0;    //重新计时
    }
}
void Ir_work(void)//红外键值码           //ok
{
       switch(irbyte[2])//判断第三个数码值,第三个为数据位,第四个是数据码取反校验位
             {
             case 0x0c:DataPort=table[1];break;//1 
             case 0x18:DataPort=table[2];break;//2
             case 0x5e:DataPort=table[3];break;//3
             case 0x08:DataPort=table[4];break;//4
             case 0x1c:DataPort=table[5];break;//5
             case 0x5a:DataPort=table[6];break;//6
             case 0x42:DataPort=table[7];break;//7
             case 0x52:DataPort=table[8];break;//8
             case 0x4a:DataPort=table[9];break;//9
             default:break;
             }

          irpro_ok=0;//处理完成标志
}
void Ircordpro(void)//解码函数         //ok

  unsigned char i, j, k;
  unsigned char byte,value;

  k=1;
  for(i=0;i<4;i++)      //处理4个字节
     {
      for(j=1;j<=8;j++) //处理1个字节8位
         {
          byte=irdata[k];
          if(byte>7)//大于某值为1,这个和晶振有绝对关系,这里使用12M计算,此值可以有一定误差
             value|=0x80;
          if(j<8)
            {
             value>>=1;
            }
           k++;
         }
     irbyte[i]=value;  //存储解码值
     value=0;     
     } 
     irpro_ok=1;//处理完毕标志位置1
}
void main()
{
    inter0_init();
    inter0_ex();

    we = 1;
    P0 = 0x00;
    we = 0;

    while(1)
    {
        if(ir_ok)
        {
            Ircordpro();
            ir_ok = 0;
        }
        if(irpro_ok)
        {
            Ir_work();
        }
    }
}

你可能感兴趣的:(51单片机,单片机)