前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >单片机红外接收与红外发射

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

作者头像
bigmagic
发布2020-03-17 14:37:28
3.3K0
发布2020-03-17 14:37:28
举报
文章被收录于专栏:嵌入式iot嵌入式iot

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. 总结

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

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-03-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 嵌入式IoT 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 红外接收
    • 1.1 说明
      • 1.2 NEC协议
        • 1.3 关于红外接收的波形
          • 1.4 解码
            • 1.4 红外对射思考
            • 2. 红外发射
              • 2.1 红外发射管参数
                • 2.2 红外发射电路搭建
                  • 2.3 程序设计
                    • 2.5 实验结果
                      • 2.4 红外发射电路目前遇到的问题
                      • 3. 总结
                      领券
                      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档