红外遥控--红外遥控的编解码以及识别驱动

红外遥控的编解码以及识别驱动

       由于不同的遥控器的编码格式可能是不同的,这里只是目前我所用的这款遥控器的单片机识别程序以及可以对未知编码格式的红外遥控器进行解码的方法。

红外遥控器的编码一般由引导码、系统码、系统反码、功能码、功能反码、固定停止码或者校验码等组成。

1、实例 红外遥控器解码识别程序

作为例子的遥控器是属于一种空调遥控器的编码。(以后所说的T都是指400us的时间)

其编码格式由引导码+固定头码+功能码+校验码组成。

引导码脉冲为8T的高电平和8T的低电平。

位1脉冲宽度为1T的高电平,3T的低电平。

位0脉冲宽度为1T的高电平,1T的低电平。

校验码为所有的数除了rDrv_PulseWidth据和累加取反。

红外遥控的波形如下图所示:

我用到了stm8单片机中的定时器1,以及红外接收头所对应的中断,中断使用下降沿,主要通过脉冲低电平的时间

不同来区分不同的数据。定时器1来计算连续两次中断的间隔(其对应了相应脉冲的宽度)

根据上述条件,写出的红外遥控识别程序如下:

#include "public.h"

#define PeriodT  25        //T的时间/16us

  static u16 OldT1Count=0; //保存计数器1的旧值
  static u16 T1Count=0;    //保存计数器1的当前值

  static u8 BitCount=0;   //写入位数值
  static u8 NewData;      //有没有新的一帧数据到来标志

  u8 RecvData[12];        //用于保存接收数据的数组

  static u16 u8PulseWidth=0; //计算出的脉冲宽度值

/*******************************************************************************
//  Function:      vDrv_ExitIntPC4Init()
//  Description:   红外按键外部中断PC4
//  Author: Huangzhigang 2014-0306
*******************************************************************************/
void vDrv_ExitIntPC4Init()
{
  //PC4 中断 输入 浮动
  GPIO_Init(GPIOC, GPIO_PIN_4, GPIO_MODE_IN_FL_IT);     //红外接收头对应IO口

  //EXTI_SetExtIntSensitivity(EXTI_PORT_GPIOC, EXTI_SENSITIVITY_RISE_FALL);  //上升沿触发中断
  EXTI_SetExtIntSensitivity(EXTI_PORT_GPIOC,  EXTI_SENSITIVITY_FALL_ONLY);   //下降沿触发中断

}

/*******************************************************************************
//  Function:      Time1_Init()
//  Description:   定时器1初始化配置
//  Author: Huangzhigang 2014-0306
*******************************************************************************/
void Time1_Init()
{
  TIM1_DeInit();

  //向上计数   分频数为256  自动重装载值为0xffff
  //256/16= 16us  计数器加一次  加到0xffff 清零重新加
  TIM1_TimeBaseInit(255, TIM1_COUNTERMODE_UP, 0xffff, 0);

  //允许更新中断
  //TIM1_ITConfig(TIM1_IT_UPDATE, ENABLE);
  TIM1_Cmd(ENABLE);
}

/*******************************************************************************
//  Function:      rDrv_PulseWidth
//  Description:   计算脉宽
//  Param:
//  Return:       有宽度返回1  无效宽度返回0
//  Others:
//  Author: Huangzhigang 2014-0306
*******************************************************************************/
u8 rDrv_PulseWidth() //u8 *PulseWidth
{
  T1Count =  TIM1_GetCounter();

  if(OldT1Count == 0)
  {
    OldT1Count = T1Count;
    u8PulseWidth = 0;
    return 0;
  }
  else
  {
    if(T1Count - OldT1Count > 0)
    {
     u8PulseWidth = T1Count-OldT1Count;
      OldT1Count = T1Count;
      return 1;
    }
    else
    {
      u8PulseWidth = 0xffff-OldT1Count+T1Count;
       OldT1Count = T1Count;
      return 1;
    }
  }
}
/*******************************************************************************
//  Function:      vDrv_WriteRecvData
//  Description:   将接受的数据写入数组
//  Param:         u8Bit  写入的值为1还是0
                   红外遥控器发送数据是先发送高位数据 再发低位数据
//  Author: Huangzhigang 2014-0306
*******************************************************************************/
void  vDrv_WriteRecvData(u8 u8Bit)
{
   u8 Bit = 1;

   if(u8Bit)
   {
      RecvData[BitCount/8] |=   Bit<<(7-(BitCount%8));     //对应位写1
   }
   else
   {
      RecvData[BitCount/8] &= ~(Bit<<(7-(BitCount%8)));    //对应位写0
   }

  if(++BitCount > 95)
  {
    NewData=0;
    BitCount=0;
  }
}

/*******************************************************************************
//  Function:      Interrupt_Remote
//  Description:   红外遥控PC4 中断处理
//  思路: 有遥控器的波形 算出进入条件,1,0 各个情况的脉冲宽度
//   进入条件:为8T的低电平和8T的高电平  以下降沿为触发方式 计时16T 即可
//   1:1T的低电平 3T的高电平   计时4T
//   0;1T的低电平 1T的高电平  计时2T
//   计算方式  定时器1 定时16us  T=400us  所以1T的时间等于计数器加400/16=25次
//   16T = 26*16=400  4T =100  2T= 50
//  Author: Huangzhigang 2014-0306
*******************************************************************************/
void Interrupt_Remote()
{
  if(rDrv_PulseWidth())
  {
     if((u8PulseWidth >= (400-5))&&(u8PulseWidth <=(400+5)) )//PeriodT*16+Herror  //5表示误差范围
     {
        NewData=1;       //表示有新数据到来  开启数组的写入功能
     }
     else if((u8PulseWidth >= (100-5))&&(u8PulseWidth <=(100+5))&&(NewData==1))
     {
       vDrv_WriteRecvData(1);
     }
     else if((u8PulseWidth >=(50-5))&&(u8PulseWidth  <= (50+5))&&(NewData==1))
     {
       vDrv_WriteRecvData(0);
     }
     else
     {
       NewData=0;
       BitCount=0;
     }
  }
}

2、对于未知编码的红外遥控器进行破解的方法。

我使用的是STM8单片机,st下载器强大的调试功能让我可以实时监控单片机程序的运行和变量变化情况。

将上述代码Interrupt_Remote() 除了rDrv_PulseWidth()之外的其它函数全部都去掉,因为目前还不知道红外遥控器实际的编码以及脉冲宽度情况。使用一个数组来记录和保存rDrv_PulseWidth()函数在每次中断后所计算出来的脉冲宽度。(建议不知道的情况下数组足够大,一般几十字节)。这样在一次红外遥控按键后,我们所设的数组中就能过得到一组完整脉冲宽度数据,冲这组数据中我们就可以判断出该遥控器的编码情况,并可以在自己的单片机程序中使用它了(代码以后补充)。

时间: 2024-08-12 04:37:25

红外遥控--红外遥控的编解码以及识别驱动的相关文章

利用CxImage实现编解码Gif图像代码举例

Gif(GraphicsInterchange Format,图形交换格式)是由CompuServe公司在1987年开发的图像文件格式,分为87a和89a两种版本.Gif是基于LZW算法的无损压缩算法.Gif图像是基于颜色表的,最多只支持8位(256色).Gif减少了图像调色板中的色彩数量,从而在存储时达到减少图像文件大小的目的.Gif分为静态Gif和动画Gif两种,扩展名为.gif,是一种压缩位图格式,支持透明背景图像,适用于多种操作系统. 下面利用CxImage开源库,实现对Gif图像进行编

【H.264/AVC视频编解码技术具体解释】十三、熵编码算法(4):H.264使用CAVLC解析宏块的残差数据

<H.264/AVC视频编解码技术具体解释>视频教程已经在"CSDN学院"上线,视频中详述了H.264的背景.标准协议和实现,并通过一个实战project的形式对H.264的标准进行解析和实现,欢迎观看! "纸上得来终觉浅.绝知此事要躬行".仅仅有自己依照标准文档以代码的形式操作一遍,才干对视频压缩编码标准的思想和方法有足够深刻的理解和体会. 链接地址:H.264/AVC视频编解码技术具体解释 GitHub代码地址:点击这里 1. H.264的CAVLC

关于Tomcat上请求的编解码问题

最近翻阅<深入分析 Java Web 技术内幕>(作者:许令波),关于Tomcat上Web请求的编解码问题,少了一个小点,可能影响了部分读者的理解,我特意查证了一下,特总结如下: 1. 请求的PathInfo部分用Tomcat的Connector元素的URIEncoding属性指定的编码来解码. 具体使用可参考:https://tomcat.apache.org/tomcat-8.5-doc/config/http.html. 2. 第二先说请求体(POST正文)的解析,Tomcat按下次顺序

中文编解码问题

在做EIP审批接口是遇到中文编解码问题,现在将编解码过程记录如下: 前端Javascript: encodeURIComponent(string) 后端Java: string = new String(string.getBytes("ISO8859-1"), "UTF-8"); 附注(引用地址:http://blog.csdn.net/kalision/article/details/8640793): 发现原来在对后台java程序里的string赋值的时候,

各种音视频编解码学习详解

各种音视频编解码学习详解 媒体业务是网络的主要业务之间.尤其移动互联网业务的兴起,在运营商和应用开发商中,媒体业务份量极重,其中媒体的编解码服务涉及需求分析.应用开发.释放license收费等等.最近因为项目的关系,需要理清媒体的codec,比较搞的是,在豆丁网上看运营商的规范 标准,同一运营商同样的业务在不同文档中不同的要求,而且有些要求就我看来应当是历史的延续,也就是现在已经很少采用了.所以豆丁上看不出所以然,从 wiki上查.中文的wiki信息量有限,很短,而wiki的英文内容内多,删减版

FFMPEG视音频编解码零基础学习方法-b

感谢大神分享,虽然现在还看不懂,留着大家一起看啦 PS:有不少人不清楚“FFmpeg”应该怎么读.它读作“ef ef em peg” 0. 背景知识 本章主要介绍一下FFMPEG都用在了哪里(在这里仅列几个我所知的,其实远比这个多).说白了就是为了说明:FFMPEG是非常重要的. 使用FFMPEG作为内核视频播放器: Mplayer,ffplay,射手播放器,暴风影音,KMPlayer,QQ影音... 使用FFMPEG作为内核的Directshow Filter: ffdshow,lav fil

字符编解码的故事(ASCII,ANSI,Unicode,Utf-8区别)

好文分享UTF-8, 字符集, 编解码 (关于字符编码的深入解释,请参见我的原创文章<关于字符编码,你所需要知道的>.) 此文为转载,有少许修订,原文出处不详. 很久很久以前,有一群人,他们决定用8个可以开合的晶体管来组合成不同的状态,以表示世界上的万物.他们认为8个开关状态作为原子单位很好,于是他们把这称为"字节". 再后来,他们又做了一些可以处理这些字节的机器,机器开动了,可以用字节来组合出更多的状态,状态开始变来变去.他们看到这样是好的,于是它们就这机器称为"

java编解码技术,netty nio

对于java提供的对象输入输出流ObjectInputStream与ObjectOutputStream,可以直接把java对象作为可存储的字节数组写入文件,也可以传输到网络上去.对与java开放人员来说,默认的jdk序列化机制可以避免操作底层的字节数组,从而提升开发效率. 1.为什么需要序列化 网络传输与对象序列化 2.java编解码技术指的什么 netty nio是基于网络传输,当进行远程跨进程服务调用时,需要把被传输的对象编码为字节数组或者bytebuffer对象.而当远程服务读取到byt

文件的编解码操作

文件的编解码操作需要借助中间类NSData NSString *s = @"tsdfsdfsdfsdf"; NSData *data = [s dataUsingEncoding:NSUTF8StringEncoding]; s = [[NSString alloc] initWithData:data encoding:(NSUTF8StringEncoding)];