单片机
返回首页

红外解码原理及程序

2016-09-08 来源:eefocus

//----------------------------------------------------------------------------------------------------------------------------------------------

// 红外解码原理基本简介:当发射键按下后,就会发射出33位遥控编码,按下的键不同,发射出的编码不同;
// 33位数据中。第一位是起始码,告诉接收器准备开始接收。后面的32位时数据,最开始发送出去的是操控码,用于不同遥控器的识别。同一各遥控器
// 所有按键的操控码都相同;发送时,先发低位,再发高位;接下来的数据是操控码的反码,用于验证操控码,同样也是低位在前,高位在后;接下来
// 的就是数据了,数据石油8位2进制的数构成,同样低位在前,高位在后。最后的8位数据时前面数据的反码,用于数据的校对;
// 在解码时最关键的是怎样识别发送过来的0和1;遥控编码,是用38kHZ的载波发送的;通常, ”0“用0.56ms的低电平和0.56ms的高电平组合而成,脉冲宽度
// 位1.12ms;”1“是用0.56ms的低电平和1.69ms的高电平组合而成,脉冲宽度为2.25ms。这页就位我们提供了一种方法来识别0和1,即判别脉冲宽度;这页就是
// 本程序所用到的方法;其次,比较关键的是,如何识别起始位;通常用9ms的低电平和4.5ms的高电平组合成起始位,因而同样可以用判别脉冲宽度的方法来识
// 别起始位;
//------------------------------------------------------------------------------------------------------------------------------------------------ 
                                                                                                   


 


  #include          //包含头文件;

//--------------------------------------------------------------------
//重新声明变量标识符;
//-------------------------------------------------------------------- 
  #define  uchar  unsigned char
  #define  uint  unsigned int
  #define  ulong  unsigned long int

  sbit  out=P3^2;        //端口定义;


  uchar  add=0,_add=0,tdata=0,_tdata=0;   //分别为 操控码,操控反码,数据,数据反码;
  uchar  add_up=0,add_down=0,_add_up=0,_add_down=0,tdata_up=0,tdata_down=0,_tdata_up=0,_tdata_down=0;//up代表高4位,down代表低4位;
  uchar  num=0;         //用于判断接收数据的位数,判断终止位;
  ulong  bitdata=0x00000000;      //用于存放接收到的32位二进制数;

  bit   finish_flag=0;       //结束标志;
  bit   start_flag=0;       //开始标志;
  bit   time=1;         //数据与开始标志识别;
  bit   data_start=0;       //数据开始标志;

 

  uchar  code table[]={
           0x28,/*0*/
                 0x7E,/*1*/
                 0xA2,/*2*/
                 0x62,/*3*/
                 0x74,/*4*/
                 0x61,/*5*/
                 0x21,/*6*/
                 0x7A,/*7*/
                 0x20,/*8*/
                 0x60,/*9*/
                 0x30,/*A*/
                 0x25,/*b*/
                 0xA9,/*C*/
                 0x26,/*d*/
                 0xA1,/*E*/
                 0xB1 /*F*/
             };

 

//------------------------------------------------------------------------------------------------------
//所用到函数的声明;
//------------------------------------------------------------------------------------------------------
  void display(uchar t);
  void initial();
  bit  start_check(uchar data1,uchar data2);
  bit  trans_to_bit(uchar data1,uchar data2);
  void trans_bitdata_to_data();
  void trans_data();
  bit  data_check();
  void  interrupt0();
  void display(uchar t);

//-------------------------------------------------------------------------------------------------
//函数名称:delay();
//入口参数:uchar n;
//功能:延时;

//-------------------------------------------------------------------------------------------------


  void  delay(uchar n)
     {
      while(n--);
      }
 
//-------------------------------------------------------------------------------------------------
//函数名称:initial();
//入口参数:无;
//功能:初始化;

//-------------------------------------------------------------------------------------------------     
   
  void  initial()
     {
      EA=1;     //开总中断;
      EX0=1;     //开外部中断0;
      IT0=1;     //外部0中断方式位下降沿中断;
      TMOD=0x01;    //定时器0,工作方式1;
      TH0=0x00;    //置初值;
      TL0=0x00;
      time=1;
      num=0;
      data_start=0;
      start_flag=0;
      finish_flag=0;
      }

//-------------------------------------------------------------------------------------------------
//函数名称:start_check();
//入口参数:uchar data1,uchar data2;
//出口参数类型:bit;
//功能:开始位判断;
//------------------------------------------------------------------------------------------------- 
   bit  start_check(uchar data1,uchar data2)
     {
      uint i;
      i=data1*256+data2;
      if(i>7500&&i<14500)
       return 1;
      else
       return 0;
     }


//-------------------------------------------------------------------------------------------------
//函数名称:trans_to_bit();
//入口参数:uchar data1,uchar data2;
//出口参数类型:bit;
//功能:将定时器的值转化位2进制数0和1;

//------------------------------------------------------------------------------------------------- 

  bit   trans_to_bit(uchar data1,uchar data2)
     {
      uint i;
      i=data1*256+data2;
      if(i>1200&&i<2300)
       return 1;
      else
       return 0;
      }

//-------------------------------------------------------------------------------------------------
//函数名称:trans_bitdata_to_data();
//入口参数:无;
//出口参数类型:void;
//功能:分离出操控码,操控反码,数据,数据反码;;

//------------------------------------------------------------------------------------------------- 

  void trans_bitdata_to_data()
     {
      add=(uchar)(bitdata&0x000000ff);
      _add=(uchar)((bitdata&0x0000ff00)>>8);
      tdata=(uchar)((bitdata&0x00ff0000)>>16);
      _tdata=(uchar)((bitdata&0xff000000)>>24);
     }

 


//-------------------------------------------------------------------------------------------------
//函数名称:trans_data();
//入口参数:无;
//出口参数类型:void;
//功能:分离出操控码,操控反码,数据,数据反码的高4位和低4位;
//------------------------------------------------------------------------------------------------- 
  void trans_data()
     {
      add_up=(add&0xf0)/16;
      add_down=add&0x0f;
      _add_up=(_add&0xf0)/16;
      _add_down=_add&0x0f;
      tdata_up=(tdata&0xf0)/16;
      tdata_down=tdata&0x0f;
      _tdata_up=(_tdata&0xf0)/16;
      _tdata_down=_tdata&0x0f;
      
     }

 

//-------------------------------------------------------------------------------------------------
//函数名称:data_check();
//入口参数:无;
//出口参数类型:bit;
//功能:检验所得数据的正确性;
//------------------------------------------------------------------------------------------------- 
  bit  data_check()
     {
      if((add==~_add)&&(tdata==~_tdata))
       return 1;
      else
       return 0;
     }

 

//-------------------------------------------------------------------------------------------------
//函数名称:interrupt0();
//入口参数:无;
//出口参数类型:void;
//功能:外部中断0;

//------------------------------------------------------------------------------------------------- 

  void  interrupt0()  interrupt 0
     {
      uchar TH0_BUF,TL0_BUF;     //定时器数据缓存;
      if(!time&&data_start)      //判断起始位是否有效,为第二次中断时;
       {
         TR0=0;        //关定时器0;
         if(start_check(TH0,TL0))
          {start_flag=1;data_start=0;TH0=0x00;TL0=0x00;TR0=1;}  //若起始位有效,置位开始标志位start_flag,定时器重新定时;
         else                //若起始位无效,初始化,等待下个起始位;
          initial();
       }
                
       else if(!time&&start_flag)             //起始位有效,则在第二次中断时接收数据;
         {
            TR0=0;
            TH0_BUF=TH0;
            TL0_BUF=TL0;
            TH0=0x00;
            TL0=0x00;
            TR0=1; 
            bitdata=bitdata>>1;         //先移位,后赋值;
            if(trans_to_bit(TH0_BUF,TL0_BUF))
             bitdata=bitdata|0x80000000;
            else 
              ;
            if(num>=31)           //接收完成,完成标志finish_flag置位; 
             finish_flag=1; 
             else  
              num++;
         }        
        else if(time)               //第一此中断,开定时器;
         {
          time=!time;
          TR0=1;
          data_start=1;      
         }
      }         
       


//-------------------------------------------------------------------------------------------------
//函数名称:display();
//入口参数:uchar t;
//出口参数类型:void;
//功能:显示函数;

//-------------------------------------------------------------------------------------------------  
  void display(uchar t)
    {
     while(t--)
      {
       P0=0x00;
       P2=0xfe;
       P0=table[add_up];
       delay(10);
       P0=0x00;
       P2=0xfd;
       P0=table[add_down];
       delay(10);
       P0=0x00;
       P2=0xfb;
       P0=table[_add_up];
       delay(10);
       P0=0x00;
       P2=0xf7;
       P0=table[_add_down];
       delay(10);
       P0=0x00;
       P2=0xef;
       P0=table[tdata_up];
       delay(10);
       P0=0x00;
       P2=0xdf;
       P0=table[tdata_down];
       delay(10);
       P0=0x00;
       P2=0xbf;
       P0=table[_tdata_up];
       delay(10);
       P0=0x00;
       P2=0x7f;
       P0=table[_tdata_down];
       delay(10);
        }
       }


//----------------------------------------------------------------------------------------------
//主函数入口;
//---------------------------------------------------------------------------------------------- 

  main()
   {
     initial();        //初始化;
     while(1)
      { 
       display(1); 
       if(finish_flag)     //完成后,进行数据处理;
        { 
         initial();    //初始化,准备接收第二次;
         trans_bitdata_to_data();
         if(data_check())   //判断接收数据是否正确,如果正确,则显示,否则丢弃;
          trans_data();                                    
         }       
       }
   }

进入单片机查看更多内容>>
相关视频
  • RISC-V嵌入式系统开发

  • SOC系统级芯片设计实验

  • 云龙51单片机实训视频教程(王云,字幕版)

  • 2022 Digi-Key KOL 系列: 你见过1GHz主频的单片机吗?Teensy 4.1开发板介绍

  • TI 新一代 C2000™ 微控制器:全方位助力伺服及马达驱动应用

  • MSP430电容触摸技术 - 防水Demo演示

最新器件
精选电路图
  • CCD图像传感器在微光电视系统中的应用

  • 如何利用ESP8266制作一个简单的四轴飞行器

  • 非常简单的150W功放电路图

  • 基于IC555的可变PWM振荡器电路

  • 优化电路板布局的简单方法

  • 分享一个电网倾角计电路

    相关电子头条文章