首页 > 代码库 > 红外遥控--红外遥控的编解码以及识别驱动

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

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


       由于不同的遥控器的编码格式可能是不同的,这里只是目前我所用的这款遥控器的单片机识别程序以及可以对未知编码格式的红外遥控器进行解码的方法。
       红外遥控器的编码一般由引导码、系统码、系统反码、功能码、功能反码、固定停止码或者校验码等组成。

 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=http://www.mamicode.com/0;  >

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

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

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




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