红外遥控器的解码

2020-01-22 12:01发布

红外遥控器的解码
实测距离10米时不会错误或需要重复按遥控器 (*^__^*) ……


接收头 (原文件名:接收头.jpg.jpg)


正确解码 (原文件名:20110103426.jpg)
第一行显示的是:地址码+地址码+操作码+操作码反码  接受数据正确时第二行显示OK  旁边的数字是连_发次数


错误解码 (原文件名:20110103427.jpg)
第一行显示的是:地址码+地址码+操作码+操作码反码  接受数据错误时第二行显示error  旁边的数字是连_发次数


51开发板配的万能遥控器 (原文件名:20110103428.jpg)
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
97条回答
qq335702318
1楼-- · 2020-01-22 14:22
=====================================H文件========================================================

#ifndef DECODE_H_
#define DECODE_H_


/******************************************************************/
/*                     函 数 声 明                                */
/******************************************************************/
void Timer0init(void);//定时器0初始化
void EX0init(void);   //外部中断初始化
void Decode(void);    //解码子程序
void get_IRkey(void);  //键处理


/******************************************************************/
/*                     宏  定  义  区                             */
/*  由于遥控器和程序存在一定误差,必须允许编码时长有一定的范围    */
/*  以下定义了时长和范围以及本机地址。用于调试                    */
/******************************************************************/
#define IR_addr1 0x0a                                //本机地址1
#define IR_addr2 0x0a                                //本机地址2
#define Guide_timer 39                            //引导码最短时长
#define Continuous_timer 39         //连_发码最短时长
#define IR_L_timer_min 3                        //数据0 最短时长
#define IR_L_timer_max 7                        //数据0 最长时长
#define IR_H_timer_min 8                        //数据1 最短时长
#define IR_H_timer_max 12                        //数据1 最长时长
#define TIMER0_COUNT 0x1f                //定时器定时时间
#define Timeout_cnt 250                            //超时时长

/******************************************************************/
/*                    变  量  保  存  区                          */
/******************************************************************/
static unsigned char Timer0_cnt;                        //定时器计数值
static unsigned char Timer0_cnt_bk;
static bit timeout;                                                        //超时标志
static bit Guide;                                                    //引导码有效
static bit Continuous;                      //连_发码
static unsigned char IR_time[33];                        //保存每两个下降沿之间的时间间隔


/******************************************************************/
/*                       结  构  体  区                           */
/* 保存一次解码后接受到的四字节数据                               */
/******************************************************************/
static struct IR_data                                //红外接收数据寄存
{
unsigned char addr1;                                //地址1(客户码1)
unsigned char addr2;                                //地址2(客户码2)
unsigned char data1;                                //数据1(数据码)
unsigned char data2;                                //数据2(数据码反码)
}IR_data;


#endif


/************ 编解码说明 ***************

引导码+地址吗+地址码+数据码+数据码反码+连_发码+...

引导码:9ms低电平+4.5ms 高电平
连_发码:9ms低电平+2.25ms高电平
数据0:0.56ms低电平+0.56ms高电平
数据1:0.56ms低电平+1.69ms高电平

*****************************************/




=====================================C文件========================================================

/******************************************************************/
/*                   红 外 遥 控 解 码                            */
/* CPU & XTAL :89c52 @ 12Mhz                                     */
/* 支持的红外编码方案: NEC6121                                   */
/* 编码格式:引导信号(或连_发信号)+地址码+地址码+控制码+控制码反码 */
/******************************************************************/


#include "decode.h"
#include "display.c"


/******************************************************************/
/*                   定时器0初始化                                */
/*                   定时值:225us                                */
/*                   方式2 自动重载                               */
/******************************************************************/
void Timer0init(void)//定时器0初始化
{
  //定时值 225us
  TMOD=0x02;//定时器0工作方式2 自动重载
  TH0=TIMER0_COUNT; //重载值
  TL0=TIMER0_COUNT; //初始化值
  ET0=1;    //定时器0中断有效
  TR0=1;    //定时开始
}


/******************************************************************/
/*                   外部中断初始化                               */
/*                   中断端口:外部中断0 P3.2                     */
/*                   触发方式:下降沿                             */
/******************************************************************/
void EX0init(void)
{
EA = 1;    //总中断开
IT0 = 1;   //指定外部中断0下降沿触发,INT0 (P3.2)
EX0 = 1;   //外部中断有效
}


/******************************************************************/
/*                   Timer0中断子程序                             */
/******************************************************************/
void Timer0(void) interrupt 1 using 1
{
Timer0_cnt++;
if(Timer0_cnt>Timeout_cnt)
timeout=1;                                         //超时标志
}


/******************************************************************/
/*                    外部中断0函数                               */
/* 下降沿触发                                                  */
/******************************************************************/
void ex0_isr (void) interrupt 0 using 0
{
static unsigned char m=0;
Timer0_cnt_bk=Timer0_cnt; //备份时间计数值,即前一个下降沿到本下降沿的时间间隔
Timer0_cnt=0x00;                  //清空时间计数值


if(timeout)                   //如果超时
{
TL0=TIMER0_COUNT;  //初始化定时器0
Timer0_cnt=0x00;   //清空时间计数值
timeout=0;                   //清除超时标志
Guide=0;           //清除引导标志
Continuous=0;      //清除连_发标志
m=0;                           //复位数据位
}
else
{
if(Guide|Continuous)                   //如果引导码有效
  {
  IR_time[m++]=Timer0_cnt_bk;         //保存时间间隔
   if(m==32)                                         //接收够32数据后
    {
     m=0;
         Guide=0;                                         //清除引导标志
     Decode();                                         //解码         
    };
  };                                                                
                                                                  
if(Timer0_cnt_bk>Guide_timer)         //如果时间间隔>引导码时长
{
  Guide=1;                                                 //使能引导标志
  m=0;
};
if(Timer0_cnt_bk>Continuous_timer)         //如果时间间隔>引导码时长
{
  Continuous=1;                                                 //使能引导标志

  EX0=0;

  /**此处加入连_发操作代码**/
  display_Continuous();

  EX0=1;
  m=0;  
};

};//end of 超时                                                     

}


/******************************************************************/
/*                       解码子程序                               */
/******************************************************************/

void Decode(void)
{
unsigned char m,n,s=0x00;
static unsigned char *p;  //指向结构体IR_data.XX的指针
EX0 = 0;   //外部中断无效

p=&IR_data.addr1;

for(n=0;n<4;n++)
{
for(m=8;m>0;m--)
  {                                                                                  
  if((IR_time>IR_L_timer_min)&(IR_time<IR_L_timer_max))//数据“0” 0.56ms低电平+0.56ms高电平                  
   {
   *p>>=1;
   *p&=0x7f;
   }
  else if((IR_time>IR_H_timer_min)&(IR_time<IR_H_timer_max)) //数据“1” 0.56ms低电平+1.69ms高电平   
   {
   *p>>=1;
   *p|=0x80;  
   };
  s++;
  };
  p++;
};
if(IR_data.data2==~IR_data.data1)                   //数据2=数据1反码
{
if((IR_data.addr1==IR_addr1)&(IR_data.addr2==IR_addr2))
get_IRkey();
}
else
{

/**非本机遥控器或数据错误**/
display_error();

};
EX0 = 1;                           //重新开放外部中断
}

/******************************************************************/
/*                    键 处 理 函 数                              */
/* 正确接收数据并解码时被中断程序调用                           */
/* 按键处理函数结束前外部中断不开放                               */
/* 此处保存按键处理函数,键值在于结构体IR_data                    */
/******************************************************************/
void get_IRkey()
{
display_keyValue();    //显示从遥控收到的数据
}



============================================资料==============================================================
源程序ourdev_608886TMXLKE.rar(文件大小:41K) (原文件名:遥控解码 测试.rar)
网上找的教程 作者所有ourdev_608887HO95UR.pdf(文件大小:317K) (原文件名:手把手教你红外解码.pdf)
网上找的教程 作者所有ourdev_608888K13FOP.doc(文件大小:164K) (原文件名:红外解码.doc)
sdwzq
2楼-- · 2020-01-22 15:45
ken_ly
3楼-- · 2020-01-22 19:00
 精彩回答 2  元偷偷看……
greatwall2
4楼-- · 2020-01-22 22:45
谢谢分享
b60885262
5楼-- · 2020-01-23 04:21
试了,发现不显示,

/************ 位变量定义 *********/
sbit RS=P1^3;
sbit RW=P1^1;
sbit  E=P1^0;
sbit BF=P3^3;
qq335702318
6楼-- · 2020-01-23 04:33
回复【5楼】b60885262
-----------------------------------------------------------------------

红外接收头接单片机外部中断0,INT0 (P3.2)
1602数据口接P0 (需要上拉电阻)
晶振用12 MHz

一周热门 更多>