搜索
bottom↓
回复: 8

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

[复制链接]

出0入0汤圆

发表于 2008-12-6 10:45:09 | 显示全部楼层 |阅读模式
程序是用网上公布的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!='\0')

  {

    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.

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出0入0汤圆

发表于 2008-12-6 18:31:12 | 显示全部楼层
红外解码最关键的是时序要控制得非常好,配合你的12M晶振,弄一个准确的延时试试(时间可用keil仿真得到,力求精确)



我有个帖讲红外解码的,LZ可以看下.

出0入0汤圆

 楼主| 发表于 2008-12-6 18:24:23 | 显示全部楼层
定时器还没学呢,找到了一个汇编的,不懂汇编,里边没有显示模块,没法测试,哪位帮忙把核心部分转成C的



;///////////////////////    宏定义   ////////////////////////////////////////



STACK_START  EQU 03Fh ;堆栈起始

DELAY_TIME_H  EQU 0F8H ;计时器2ms中断

DELAY_TIME_L  EQU 02FH



FLAG_REM  BIT 00H ;已接收到遥控信号

FLAG_REM_TIMEOUT BIT 01H ;接收遥控信号超时



;///////////////////////     变量  //////////////////////////////////////////



REM_CNT   EQU 7EH ;已接收数据位数

REM_BUF   EQU 7FH ;遥控数据缓冲区



;============================================================================

;-------------------------  主程序  -----------------------------------------



ORG 0000H

JMP MAIN



ORG 0003H   ;外部中断

JMP INT_REM



ORG 000BH   ;计时器中断

AJMP INT_TIMER



MAIN:

MOV SP,#STACK_START

MOV     TH0,#DELAY_TIME_H

        MOV     TL0,#DELAY_TIME_L

MOV TMOD,#00100001B  ;计时器模式



MOV TL1,#0FDH  ; 9600 BPS

MOV TH1,#0FDH  ; 8 位

MOV SCON,#01000000B  ; 无校验



SETB TR0   ;开计数器

SETB TR1

SETB ET0   ;开中断

SETB EX0

SETB EA



CLR FLAG_REM

SETB FLAG_REM_TIMEOUT



MOV REM_CNT,#0





;-------------------------主循环---------------------------------------------

LOOP:

JB FLAG_REM,REM_HANDLE ;有遥控信号未处理

JMP LOOP



;--------------------------遥控数据处理--------------------------------------

REM_HANDLE:

MOV A,REM_BUF  ;通过串口发送数据

MOV SBUF,A

JNB TI,$

CLR TI



ACALL DELAY_100MS

CLR FLAG_REM

JMP LOOP



;--------------------------外部中断(遥控输入)--------------------------------

;   遥控芯片:   M50462AP

;



INT_REM:

CLR EX0   ;关中断

PUSH PSW   ;保存现场

PUSH ACC



JB FLAG_REM,INT_REM_END ;有遥控信号未处理

     ;拒绝接收



SETB RS0



MOV R5,#50   ;延时200US去干扰

REM_DELAY:

JB P3.2,INT_REM_END

DJNZ R5,REM_DELAY



JB FLAG_REM_TIMEOUT,REM_START

     ;已超时,重新开始



MOV A,TH0   ;粗略计算两次间隔

ANL A,#0FH



CJNE A,#0BH,REM_SKIP_CHK_0

BIT_IS_0:

CLR C   ;BIT IS 0

JMP REM_CHK_OK

REM_SKIP_CHK_0:

JC INT_REM_END  ;<0BH

CJNE A,#0EH,REM_CHK_1 ;干扰

BIT_IS_1:

SETB C   ;BIT IS 1

JMP REM_CHK_OK

REM_CHK_1:

JC BIT_IS_0  ;<0EH

JMP BIT_IS_1  ;>0EH

REM_CHK_OK:

MOV A,REM_BUF  ;将一位数据存储

RRC A

MOV REM_BUF,A



INC REM_CNT   ;接收位数计数器加一



MOV A,REM_CNT

CJNE A,#10H,REM_CHK_NEXT ;已接收到16位数据

SETB FLAG_REM  ;接收到有效的遥控信号

     ;遥控码在 REM_BUF 里

REM_START:

MOV REM_CNT,#0

REM_CHK_NEXT:

MOV TH0,#DELAY_TIME_H ;设置超时计数器

        MOV TL0,#DELAY_TIME_L

CLR FLAG_REM_TIMEOUT

INT_REM_END:

POP ACC   ;恢复现场

POP PSW

SETB EX0

RETI



;-------------------------计时器中断-----------------------------------------

INT_TIMER:

SETB FLAG_REM_TIMEOUT

RETI



;--------------------------延时子程序----------------------------------------

DELAY_100MS:

MOV R7,#0C8H

DELAY_100MS_L0:

MOV R6,#0F8H

DELAY_100MS_L1:

DJNZ R6,DELAY_100MS_L1

NOP

DJNZ R7,DELAY_100MS_L0

RET



END

出0入0汤圆

发表于 2008-12-6 17:47:50 | 显示全部楼层
你用定时器读取值吧,很好用的

出0入54汤圆

发表于 2008-12-6 12:20:07 | 显示全部楼层
没有引导码的话可以参考下异步串口的检测方法

出0入0汤圆

 楼主| 发表于 2008-12-6 11:32:47 | 显示全部楼层
没有引导码的,我有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.

出0入0汤圆

发表于 2008-12-6 11:29:03 | 显示全部楼层
我这是038的红外解码程序,不过原理应当差不多的,不知你是否需要,你所说的50462没有引导码吗?038是有的引导码的

出0入0汤圆

发表于 2010-9-30 15:39:18 | 显示全部楼层
mark

出0入0汤圆

发表于 2014-7-3 23:07:47 | 显示全部楼层
这个50462就是不大容易搞定~~~~~~~~~~~~
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-8-26 02:15

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表