初学时序,50462的红外解码拆腾了好几天也没解出来,发上代码和时序图高手帮我看看【

2020-01-23 14:32发布

程序是用网上公布的9012解码改的,整了好多天,没整出来



//   本程序主要是遥控器解码和1602驱动程序

//-------------------------------------------------------

//   LCD1602   IR-DECODE

//   writed by nxp---2006.12.29

//-------------------------------------------------------

//   连线表:  CPU=89S52

//   SysClock=12MHz

//   LCD:  1602

//   功能:解码红外遥控器

//   遥控器芯片:50462

    

#include <at89x52.h>

#define uchar unsigned char

#define uint  unsigned int 

/*----------------------------控制I/O口设置,根据实际而定---------------*/

#define  RS    P2_7        //RS数据命令选择端,高电平数据,低电平命令

#define  RW    P2_6        //RW读写选择端,高电平读操作,低电平写操作

#define   E    P2_5        //E使能控制端,E高电平跳变为低电平时LCD执行命令

#define   DATA P0          //数据端口定义

#define   D0   P0_0

#define   D1   P0_1

#define   D2   P0_2

#define   D3   P0_3

#define   D4   P0_4

#define   D5   P0_5

#define   D6   P0_6

#define   D7   P0_7



#define   IR_RE P3_2

/*------------------------------------------------------------------------------*/

  bit   k=0;                                      //红外解码判断标志位,为0则为有效信号,为1则为无效

  uchar n=0;                                      //用来控制外部中断

  uchar code str0[16]=" REMOTE CONTROL";          //开机画面显示

  uchar code str1[16]="  IR-CODE: ";

  uchar code str2[16]="ERROR";

  

  uchar *p0=str0;

  uchar *p1=str1;

  uchar *p2=str2;

  delay1ms(uint k);

  

  void disp(void);                            //红外键值显示程序

  uchar  data date[2];                        //date数组为存放地址原码,数据原码

   

/*------------------------LCD忙判断子程序--------------------------------------*/

void busy()

{

  RS=0;RW=1;

  E=0;E=1;DATA=0xff;

  while(D7);

}

/*----------------------- 写命令子程序-----------------------------------------*/

void wcom(uchar com)

{

  busy();

  RS=0;RW=0;

  E=1;

  DATA=com;

  E=0;

}

/*-------------------------写数据子程序--------------------------------------*/

void wdata(uchar dat)

{

  busy();

  RS=1;RW=0;

  E=1;

  DATA=dat;

  E=0;

}

/*--------------------------读命令子程序-----------------------------------*/

 

uchar rcom(void)

{

  uchar com;

  busy();

  RS=0;RW=1;

  DATA=0xff;

  E=1;

  com=DATA;

  E=0;

  return(com);

}

/*----------------------------读数据子程序-----------------------------*/

uchar rdat(void)

{

  uchar dat;

  busy();

  RS=1;RW=1;

  DATA=0xff;

  E=1;

  dat=DATA;

  E=0;

  return(dat);

}

/*--------------------------延时1.05ms程子程序-----------------------*/

delay1050()             

{

   uint i,j;

   for(i=0;i<1;i++)

     for(j=0;j<130;j++)

     ;

}

/*---------------------------延时920us子程序-----------------------*/

delay920()

{

   uint i,j;

   for(i=0;i<1;i++)                  

     for(j=0;j<113;j++)

     ;

}

/*--------------------------延时2400ms程子程序-----------------------*/

delay2400()                                          

{

   uint i,j;

   for(i=0;i<3;i++)          

     for(j=0;j<99;j++)

      ;

}



/*--------------------------以下为初始化程序,由上面子程序组成,根据个人爱好-----------*/



/******************************清屏程序***********************************/

 void clear()

 { wcom (0x01);}

/******************************归位程序********************************/

 void rehome()

 { wcom(0x02); }

/*******************8*****888**88888显示模式设定8888888888888888888888*/

void  mode(bit x)

 {

    if(x==1)wcom(0x38);          //两行5*8 mode 

 else wcom(0x34);            //一行5*10 mode

 }

/*------------------------显示开关控制命令----------------------------*/

void on_off(bit x)

{

  if(x==1)wcom(0x0f);           //显示开,光标开,光标闪烁

  else wcom(0x0c);             //显示开,光标关

}



/*------------------------init初始化组合-------------------------*/

void init()

{

  clear();          //清屏

  mode(1);          //模式设置

  on_off(1);         //显示设置

  wcom(0x06);        //移动方式

}

/*---------------------------对字符串的处理------------------------*/

void strchar(uchar *p)

{

  while(*p!='')

  {

    wdata(*p);

 p++;

  }

}

/*----------------------------------------------------------*/

/*-----------------------红外解码程序(核心)-----------------*/

/*----------------------------------------------------------*/

void IR_decode()

{

  uchar  i,j;

  for(i=0;i<2;i++)

  {

    for(j=0;j<8;j++)

    {

           while(IR_RE==1);                                              //等待低电平到来

           while(IR_RE==0);                    //等待地址码第1位高电平到来

           delay920();                         //延时920ms判断此时引脚电平

           if(IR_RE==1)

           {       

                    delay920();

                             date>>=1;

                             date=date&0x80;     

           }

           else if(IR_RE==0)

               {

                    date>>=1;

                    date=date|0x7f;

               }

      }                                    //1位数据接收结束

   }                                       //32位二进制码接收结束

   delay1050();

   delay1050();

   delay1050();

}



/*------------------二进制码转换为压缩型BCD码,并显示---------------*/

void two_2_bcd(uchar date)

{

   uchar temp;

   temp=date;

   date&=0xf0;

   date>>=4;                    //右移四位得到高四位码

   date&=0x0f;                  //与0x0f想与确保高四位为0

   if(date<=0x09)

   {

    // wcom(0xcb);                  

     wdata(0x30+date);            //lcd显示键值高四位

   }

   else

   {

     date=date-0x09;

  //wcom(0xcb);

  wdata(0x40+date);

   }

   date=temp;

   date&=0x0f;

   if(date<=0x09)

   {

     wdata(0x30+date);            //lcd显示低四位值

   }

   else

   {

     date=date-0x09;

  wdata(0x40+date);

   }

   wdata(0x48);                 //显示字符'H'

} 



//////////////////////////////转换程序结束///////////////////////////



/*----------------------解码成功后,1602显示键值子程序---------------*/

void disp()

{

      wcom(0xc0);

      two_2_bcd(date[0]);

      wdata(0x20);

      two_2_bcd(date[1]);

      wdata(0x20);

}



/*------------------------外部中断0程序-------------------------*/

/*------------------主要用于处理红外遥控键值--------------------*/

void int0() interrupt 0

{ 

   uint i;

   if(k==0)

   { 

      EX0=0;                                //检测到有效信号关中断,防止干扰

      IR_decode();                          //如果接收到的是有效信号,则调用解码程序

      disp();                               //解码成功,调用显示程序,显示该键值

   }

  EX0=1;                                 //开外部中断,允许新的遥控按键

}



/*---------------------------------------------------------------*/

/*           以下为主程序,主要对LCD初始化,开始界面设置         */

/*---------------------------------------------------------------*/

void main(void)

{

  SP=0x60;                                //堆栈指针

  TMOD=0x11;                              //定时器模式设置所选为 模式1

  TH0=0xd8;                               //定时器初值理论为 10ms;

  TL0=0xf7;                               //实际取d8f7

  ET0=1;                                  //允许定时器0中断

  EX0=1;                                  //允许外部中断0,用于检测红外遥控器按键

  EA=1;                                   //总中断开

  init();                                 //初始化LCD

  wcom(0x80);                             //写入字符的地址为第1行第1列

  strchar(p0);                            //调用显示字符串函数

  wcom(0xc0);

  //strchar(p1);

  while(1);

}





50462时序图 (原文件名:50462时序图.jpg) 

本贴被 ciddy 编辑过,最后修改时间:2008-12-06,10:46:49.
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
8条回答
xingzhang
1楼-- · 2020-01-23 15:11
红外解码最关键的是时序要控制得非常好,配合你的12M晶振,弄一个准确的延时试试(时间可用keil仿真得到,力求精确)



我有个帖讲红外解码的,LZ可以看下.
ciddy
2楼-- · 2020-01-23 17:44
 精彩回答 2  元偷偷看……
qdvenus
3楼-- · 2020-01-23 19:02
你用定时器读取值吧,很好用的
lusson
4楼-- · 2020-01-23 22:07
没有引导码的话可以参考下异步串口的检测方法
ciddy
5楼-- · 2020-01-24 00:21
没有引导码的,我有9012和3010的程序,还是没整出来,还有一个网上找的时序图,也是50462的





 (原文件名:2005510176625.jpg) 

图中波形为开机键的键码二进制表示11100010(引导码C0-C7)和01000000(键码D0-D7)



十六进制表示为#4702H,47为引导码 02为键码





 (原文件名:200551011237158.jpg) 



一个0.25MS宽的低电平加一个0.75MS的高电平 表示“0”



一个0.25MS宽的低电平加一个1.75MS的高电平 表示“1” 



本贴被 ciddy 编辑过,最后修改时间:2008-12-06,11:33:36.
qdvenus
6楼-- · 2020-01-24 02:13
我这是038的红外解码程序,不过原理应当差不多的,不知你是否需要,你所说的50462没有引导码吗?038是有的引导码的

一周热门 更多>