kinggate的单片机小屋 https://bbs.21ic.com/?456626 [收藏] [复制] [RSS] 本站主要收集单片机、嵌入式、电子的资料,并希望能结交一些喜欢单片机的朋友 我有很多资料的,但因为忙,都没有时间放上去,敬请关注~~~~

日志

SC6122红外线解码程序(原创)

已有 3418 次阅读2007-4-29 10:58 |系统分类:单片机| SC6122, 红外线, 解码, 遥控器

/*--------------------------------------------------------------------------------
  遥控器解码处理程序

此程序非延时读取红外码,所以占用资源少!


  算法:测两个下降沿的的时间,作判断 0?  1?,遇到引导码,计数清0

接收完32位码后,遇到重复码则不在进入0或1的判断,避免第二次按键按键出错

 

注意:红外接收管接收到的波形与SC6122 PDF文件里的波形不同,为翻转了的波形,所以,处理时为:9MS低电平,4.5MS高电平引导码,其他的0 \1也相应翻转.

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

#include<reg51.h>
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long 


extern show(uchar showdata);


volatile ulong IRcode=0x00000000;  //32位的键代码


volatile uint customcode=0x0000;      //16位用户码
volatile uint time_us=0x0000;      //两个下降沿之间的时间 


volatile uchar timeH,timeL;  //保存TH1 TL的值


uchar Lcustomcode=0x00;      //低8用户码
uchar Hcustomcode=0x00;     //高8
uchar datacode=0x00;    //8位键数据码
uchar Rdatacode=0x00;      //8位键数据反码 
sbit power=P1^7;  //电源开关
bit NewIRcode=0;  //指示当处理完了32位码后,就有了新的遥控码
bit DataRight=0;   //为1时读取数据正确



//------------------------------------------------------------------------------
void init()  

  TMOD=0x11; //定时器0,工作方式1 ;  定时器1,工作方式1
  TCON=0x01; //外中断0下降沿触发,(包括TR1=0,TR0=0)
  TH0=0x3c;  //初始化定时器0,定时50ms
  TL0=0xb0;
  TH1=0x00;  //初始化定时器1
  TL1=0x00;   


  EA=1;    //开全中断
  ET0=1;   //开放T0中断
  ET1=1;      //开放T1中断
  EX0=1;   //开放INT0
 
}


//-------------------------------------interrupt0-------------------------------------
void IR_ISR() interrupt 0 using 1 //遥控器中断处理函数
{  
  static uchar cn=0;  
 
  TR1=0; 
  timeH=TH1;
  timeL=TL1;
  TH1=0;
  TL1=0;
  TR1=1;
 
  time_us=(unsigned int)timeH;
  time_us=time_us<<8;
  time_us=time_us|timeL;


  if(time_us>13300&&time_us<13700) {cn=1;IRcode=0;}  //遇到引导码,就把cn清0,IRcode清0 
  
  if(cn<34)
  {
  if(time_us>1000&&time_us<1300) //0 
          {IRcode=IRcode|0x00000000; if(cn<33) IRcode=IRcode>>1;}


  else if(time_us>2000&&time_us<2450) //1 
          {IRcode=IRcode|0x80000000;if(cn<33) IRcode=IRcode>>1;}
  }
   
  else if(time_us>11000&&time_us<11500) {IRcode=IRcode;}; //遇到重复码
                            
   cn++;


  if(cn==34) {NewIRcode=1;TR1=0;}  //读完32位码,则有新码产生


}


//--------------------------------------timer_ISR------------------------------
void Timer0_ISR() interrupt 1 using 2  //定时器0中断函数
{
 //TR1=0; 
 //TR1=1;
}
void Timer1_ISR() interrupt 3 using 3  //定时器1中断函数
{
  
}
      
//------------------------------------main()----------------------------------------------
void main()

   
    init();   
    power=1; 
 
 while(1)   
  {
        
  if(NewIRcode==1)    //如果有新的遥控码就读
      {  
   
    customcode=IRcode;    //取红外码中的用户码
    Lcustomcode=IRcode;   //取低8位用户码
      IRcode=IRcode>>8;       
    Hcustomcode=IRcode;  //取高8位用户码
       IRcode=IRcode>>8; 
    datacode=IRcode;      //取数据码
       IRcode=IRcode>>8;   
       Rdatacode=IRcode;   //取数据码的反码   
 
      if((customcode!=0xFF80)||(~Rdatacode!=datacode)) {DataRight=0;IRcode=0;} //校验用户码,反码
    
  else DataRight=1;    
 
     NewIRcode=0; //读完之后清零,表示新码已读
    }
  
   if(DataRight==1)  {show(datacode);}                        
       
  } 


}


 


 


 



 


路过

鸡蛋

鲜花

握手

雷人

发表评论 评论 (5 个评论)

回复 雨亭工作室 2007-5-7 02:56
不错,收录了。
回复 user22901 2007-6-12 09:36
干吗要反过来写程序 用施密特触发器不是出正的码么?
回复 佳佳 2007-12-10 16:39
为什么要初始化定时器0呢? 好像整个程序中都没有用到 对于关键字volatile,不定义为这个类型对结果有影响吗?

QUOTE:
以下为blog主人的回复: 呵呵,我的这个程序是是从产品的程序中拷出来的,定时器0用来做别的功能的,在这个程序中是没用到. 在这个程序中,我把volatile去掉,遥控器也能读出正确的值,但是在嵌入式的编程中,一般的中断函数所操作的全局变量加上比较保险,以免编译器优化它而产生错误.


QUOTE:
以下为blog主人的回复: 呵呵,我的这个程序是是从产品的程序中拷出来的,定时器0用来做别的功能的,在这个程序中是没用到. 在这个程序中,我把volatile去掉,遥控器也能读出正确的值,但是在嵌入式的编程中,一般的中断函数所操作的全局变量加上比较保险,以免编译器优化它而产生错误.
回复 佳佳 2007-12-10 20:17
time_us=(unsigned int)timeH;为什么要进行强制类型转换

QUOTE:
以下为blog主人的回复: 因为左边的16位,右边的8位,当然,不显式强制也是没错的.
回复 xx 2009-6-5 03:27
kinggate太地道了。