导航: 老古网老古论坛XMOS公共讨论区XMOS开源项目区单片机程序设计嵌入式系统广告区域
→红外解码,大家切磋[ats2008]

 *第18177篇: 红外解码,大家切磋

  
楼 主:ats2008 2003年12月20日23:01
 红外解码,大家切磋
首先把我的联系方式留几个:
QQ:112165
E_Mail:ats2008@tom.com
msn:ats2008@tom.com

由于刚开始接触单片机,所以做出来的程序也许不代表什么,程序还有一点点工作没有做,但是你可以在任何一个网站找代码,就是16B的非0即1数据转化为1B的问题,在程序中均有详细的说明,采用的是INT0,INT1,非门双中断,T0,T1双定时,更详细的请看程序,有什么好的想法,可以和我交流,最好的联系方式为Msn,由于我接触单片机只有 短短两个月,这里采用的是At89C52芯片,外电路不要找我,因为我采用的是最简电路.
详细程序如下(Keil C编译成功):

/*  title 红外解码方式程序设计*/
/*芯片的固有属性为起始位为低电平触发,也就是说采用反向双触发方式第三次出发就为需要的码*/
/*引导码9msL+4.5msH*/
#define CLK_CPU 11.0592
#include   <AT89X52.H>  

   bit flag;                       /*  定义中断标志*/
   bit status;                     /*中断来源 INT0=0;INT1=1*/
   unsigned int  *px;               /*存储解码信号*,第一位存储码数*/

   struct code_end
   {
      unsigned int number;
   unsigned char *compressdata;  /*把数据压缩后存储*/
   }code_end;

   unsigned int *time_high;        /*记录高电平持续时间  第一位为引导脉冲高点平*/
   unsigned int *time_low;
   unsigned int time_stand;        /*脉冲基数,即为低电平时间*/
   unsigned int count_intr;      /*中断产生的次数,这里去除了引导玛*/
   bit overlow_sign;               /*溢出标志*/
   bit start_recieve=0;
   void get_time_stand();
   void write_data();

   unsigned int int0_count;         /*低脉冲触发次数*/
   unsigned int int1_count;         /*高脉冲触发次数*/

   bit rec_time();  
   /*记录高低电平的时间*/
 void service_int0() interrupt 0 using 2   /* 中断0设置标志*/
     {
      flag=1;
   status=0;
   int0_count++;
   if(int0_count>  1)
   start_recieve=1;
   else
    start_recieve=0;
  }


 void service_int1() interrupt 1 using 2
  {

         flag=1;
   status=1;
   int1_count++;
      if(int0_count>  1)
   start_recieve=1;
   else
 start_recieve=0;

  }
     
void timer0_init()   /*定时器0初始化*/
     {
  TMOD = 0x11; /*定时器0 1 均工作在1状态*/
  TH0  = 0x00;
  TL0  = 0x00;
  TR0=0;
     }

void timer1_init() /* 定时器1初始化*/
 {
  TMOD = 0x11;
  TH1  = 0x00;
  TL1  = 0x00;
  TR1=0;
 }
    

bit  IR_init()  /*红外信号接收初始化*/
     {
  /*这里用来获取引导码,包括两个电平*/
  /*time_high time_low 第一个存储数据就是相应的引导码的数据*/
  /*9ms Low 4.5ms High  格力空调的编码,利用TEK示波器可以获取*/
  rec_time();
  return start_recieve;
  }
     
void write_data()  /*信号保存*/
  {
  unsigned int i;
  unsigned int j;
  unsigned int count_loop;
  unsigned int sgl;
  struct code_end code_end;
  *px=count_intr;     /*必须保证px的起始位置*/
  px++;        /*第一位开始存储码*/
  for(j=1;j  <count_intr+1;j++)
    {
      if(*time_high>  2*time_stand)/*大于2倍就认为是1*/
   *px=1;
   else
   *px=0;
   px++;
    }

      /*数据一共存储了count_intr个,这里采用的是 unsigned int 格式*/
   /*需要进一步压缩来获取最简单模式,code_end */
   code_end.number=count_intr;
   px=px-code_end.number;
   sgl=count_intr%8;
       count_loop=(count_intr-sgl)/8; /*设置循环次数*/
    for(i=0;i  <count_loop;i++)
      {
    for(j=0;j  <8;j++)

    {/*移位运算,压缩数据*/
    
    code_end.compressdata++;
    }
    code_end.compressdata++;
    for(i=0;i  <sgl;i++)
    {
    /*不为8的整数,移位运算,压缩数据*/
    }
  
   }
      


    /*转化为Bit*/

  }

  
void get_time_stand() /*获取时间基数*/
  {
     unsigned int i;
  unsigned int sum;
  sum=0;
      time_stand=600; /*这里芯片为600us*/


   /*设计获取方式:利用中断0的时间来获取*/
  for(i=1;i  <count_intr+1;i++)
           {
     if(count_intr!=0)
     sum=sum+(*time_low)/count_intr;
      time_low++;
     }
     time_stand=sum;
  }

 

bit rec_time() /*记录高低电平时间*/
 {
    while(flag)
   {
       if(status==0)
    {

    TR0=1;            /*开定时器0*/
    TR1=0;             /*关闭定时器1,计算时间,并存储*/
    if(int0_count!=1) /*不记录第一次中断前的时间*/
    {
    *time_high=(TL1+TH1*256)/11.0592/1000; 
    TH1=0;
    TL1=0;
    time_high++;
    }
    flag=0;
    }

    else
    {
    TR1=1;        /*开启定时器1*/
    TR0=0;       /*关闭定时器0,计算时间,并存储*/
    *time_low=(TL0+TH0*256)/11.0592/1000;
    TH0=0;
    TL0=0;
    time_low++;
    if(TF1)  /*溢出在表示接收结束,最后一位默认为高点平*/
                {
    overlow_sign=1;
    time_high++;
    *time_high=0xffff;
                }
    flag=0;
    } 
    
   
}

    return overlow_sign; /*溢出标志*/
 }


 main()
 {  
 
 int0_count=0;
 int1_count=0;
  flag=1;/*调试用*/
   count_intr=0;
       
    timer0_init();
    timer1_init();
       IR_init();

    while((!overlow_sign)&&(start_recieve))
    {
    rec_time();
    }
  
    count_intr=int0_count-1;/*除引导码外中断的次数*/

    get_time_stand();
    write_data();
 }

  
2楼:guest 2003年12月21日10:11
 我也编写了一个电视机红外遥控器的解码程序
我也编写了一个电视机红外遥控器的解码程序,不过是51平台的汇编程序 ,程序不是很长,大约四五十行吧!占用一个寄存器和A,占用单片机的一个中断口,输出自定义的按键编号。唯一的缺点是解码时间很长,(ms级)解码开始就必须进入临界状态 ,不太RT,如要作为RT系统的输入,要外加一片解码单片机,如2051之类的。
我的QQ:30926638
  
3楼:Lichunfu 2003年12月23日21:13
 我也在考虑你说的问题
我也一直在研究这个问题,我原来编过一个解码程序,只要遥控器发送结束解码也就结束,但是占用内存过大,不理想。也曾经在老古论坛上寻求过各位DX的帮助,但是没有结果。可以交流交流吗?E-mail:fulingda@163.com

>>>>>>对该主题发表你的看法

本主题贴数3,分页: [第1页]


[上一篇主题]:招聘:硬件开发应用工程师 (上海市)

[下一篇主题]:有没有下载线制做高手,可编程89S51,89S52,希望能拜他为师。