单片机红外接收与红外发射

2020-03-17 14:37:28 浏览数 (1)

1. 红外接收1.1 说明1.2 NEC协议1.3 关于红外接收的波形1.4 解码1.4 红外对射思考2. 红外发射2.1 红外发射管参数2.2 红外发射电路搭建2.3 程序设计2.5 实验结果2.4 红外发射电路目前遇到的问题3. 总结

1. 红外接收

1.1 说明

我们采用的是 HS0038B 这个红外一体化接收头 ,所以在使用时需要按照具体协议来进行解析。

当连接好设备后就可以进行数据分析了,首先看一段数据

HS0038B 这个红外一体化接收头,当收到有载波的信号的时候,会输出一个低电平,空闲的时候会输出高电平,我们用逻辑分析仪抓出来一个红外按键通过HS0038B 解码后的图形来了解一下。

1.2 NEC协议

NEC 协议的数据格式包括了引导码用户码、用户码(或者用户码反码)、按键键码键码反码,最后一个停止位。停止位主要起隔离作用,一般不进行判断,编程时我们也不予理会。其中数据编码总共是 4 个字节 32 位。

第一个字节是用户码,第二个字节可能也是用户码,或者是用户码的反码,具体由生产商决定,第三个字节就是当前按键的键数据码,而第四个字节是键数据码的反码,可用于对数据的纠错。

这个 NEC 协议,表示数据的方式不像我们之前学过的比如 UART 那样直观,而是每一位数据本身也需要进行编码,编码后再进行载波调制。

  • 引导码:9ms 的载波 4.5ms 的空闲。
  • 比特值“0”:560us 的载波 560us 的空闲。
  • 比特值“1”:560us 的载波 1.68ms 的空闲。

1.3 关于红外接收的波形

通过逻辑分析仪对红外接收管上的数据采集,基本上可以对数据的采集进行一个比较准确的时序图。

关于红外接收管的电路连接其实很简单,就是接电源和数据引脚即可

以下就是我们通过逻辑分析仪采集到的波形

通过对数据的采集,我们可以对其进行解码。

1.4 解码

一般来说,解码放在中断中,这里的中断一般是GPIO的上升沿或者下降沿中断。对于一般的程序而言,这样的设计是没有问题的。其原理可以描述如下:

(1)当来一个一个下降沿中断时,进入中断处理函数,处理事件

(2)当延时6ms后检测到该电平依然为低电平,该事件有效

(3)收集四组数据:用户码,用户反码,按键码,按键反码,存到数组中

(4)校验数据,一般而言,都是可以先校验按键码与按键反码是否正确,若正确表示解码正确

(5)处理按键码

以上是处理该问题的基本办法,编码如下:

代码语言:javascript复制
//NEC 红外0数据格式 解析
int IR0_IN(void)
{
  unsigned char j,k,N=;
    // EX0 = 0; 

  //第一步:判断红外是否有效
  if (IR0IN == )
  {
    //信号无效
    return -1;
  }

  //第二步:信号有效,延时检测,确认IR信号出现
  ET0 = ;
  IRdelay();
  if (IR0IN == ) 
  { 
    //不是有效的电平
    ET0 = ;
    return -2;
  } 

  //第三步:等IR变为高电平,跳过9ms的前导低电平信号。
  while (!IR0IN)           
  {
    IRdelay();
  }

  //收集四组数据:用户码,用户反码,按键码,按键反码
  for (j=;j<;j  )         
  { 
    for (k=;k<;k  ) //每组数据有8位
    {
        //等 IR 变为低电平,跳过4.5ms的前导高电平信号。
        while (IR0IN)            
        {
          IRdelay();
        }
        //等 IR 变为高电平
        while (!IR0IN)          
        {
          IRdelay();
        }
        //计算IR高电平时长
        while (IR0IN)           
        {
          //0.14ms计数过长自动离开。
          IRdelay();
          N  ;           
          if (N>=)
          { 
            ET0=;
            return -3;
          }
        }               
        IR0COM[j]=IR0COM[j] >> ; //数据最高位补“0”
        if (N>=) {IR0COM[j] = IR0COM[j] | 0x80;} //数据最高位补“1”
        N=;
    }//end for k    
  }//end for j

  //按键码是否正确
  if (IR0COM[]!=~IR0COM[])
  { 
    ET0 = ;
    return -4; 
  }

  ET0 = ; 
  return ; 
} 

但是如果需要检测两个红外光,该方法就有缺陷,因为要用到两个中断引脚,这对于单片机来说,是比较困难的。

为了解决这个问题,我们可以采用定时器定时去查询引脚状态的方式进行。

比如我们可以采用定时器0去定时读取电平状态。如果信号有效则保存下来。

所以我们可以采用100us的定时器Timer0进行

代码语言:javascript复制
void Timer0Init(void) //100微秒@22.1184MHz
{
    AUXR |= 0x80; //定时器时钟1T模式
    TMOD &= 0xF0; //设置定时器模式
    TL0 = 0x9A; //设置定时初值
    TH0 = 0xA9; //设置定时初值
    TF0 = ; //清除TF0标志
    TR0 = ; //定时器0开始计时

    ET0 = ; //允许T0中断
    EA = ;
    TR0 = ;
}

定时器开启后,不断的查询两个引脚的状态即可实现该过程。

1.4 红外对射思考

如果要实现红外对射的功能

2. 红外发射

2.1 红外发射管参数

目前采用的红外发射管为TSAL6200

2.2 红外发射电路搭建

2.3 程序设计

通过对红外发射管的研究发现,当红外发射管发出38Khz的波形时,接收管上输出的是低电平,其他情况下,红外接收管上接收的电平为高电平,所以要让红外接收管上的电平为特定的波形,需要采用26us的定时器。

目前由于我手上只有S8550三极管,所以当引脚输出高电平时,三极管不导通,低电平时三极管导通。

根据定时器计算26us的定时器中断

代码语言:javascript复制
void Timer_Routine(void) interrupt 1
{
 TL0 = 0xE8;    //设置定时初值
 TH0 = 0xFD;    //设置定时初值
    count  ;

    if(flag == )
    {
        OP = ~OP;
    }
    else
    {
        OP = ;
    }

    if(send_ir_flag == )
    {
        IR1_SEND = OP;
    }else
    {
        IR2_SEND = OP;
    } 
}

然后主要是按照协议发送数据即可

代码语言:javascript复制
//红外发射函数
void SendIRdata(char user_data,char key_data)
{
  //1.发送开始码 9ms
  send_code(,);
  //2.发送4.5ms结果码
  send_code(,);
  //3.发送用户码
  send_data(user_data);
 //send_code(0,4279);
  //4.发送用户反码
  send_data(~user_data);
 //send_code(0,4279);
  //5.发送按键码
  send_data(key_data);
 //send_code(0,4279);
  //6.发送按键反码
  send_data(~key_data);
  //7.发送结束码
  send_code(,);
}

以上就是红外发射的基本情况。

2.5 实验结果

通过逻辑分析仪对数据的采集,我们得到如下的数据

通过放大,可以看到波形的基本情况

该信号基本上是我们发射出来的信号。

调试手段:由于红外发射管发射出来的光线人眼是看不到的,所以可以打开手机摄像头拍红外摄像头,可以看到当红外发射管发射数据时,是有颜色的。

2.4 红外发射电路目前遇到的问题

红外发射管发射的距离达不到要求,只能在1m的范围之内数据有效,其他的情况下数据无效。对于该问题,有两点猜测

(1)红外发射与红外接收头不匹配,造成数据没办法很好接收到

(2)红外发射管功率不够

3. 总结

对于以上的测试及调节手段,遇到了一些问题,主要是对硬件部分的不熟悉带来了一些麻烦。其实对于红外接收部分的调试还是很顺利的,只是到了红外接收部分,却遇到了一些问题,其中有一个问题就是由于没有发送结束码,导致数据始终接收不到,后来通过对红外遥控的数据采集,才发现了问题的原因。后来又遇到红外发射管发射距离太短的问题,目前尝试各种办法,无果,所以该问题目前先放一放。

0 人点赞