微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 红外遥控总结及程序讲解

红外遥控总结及程序讲解

时间:10-02 整理:3721RD 点击:
  1.以一个9ms低电平,4.5ms的高电平为引导码,后跟32位2进制代码。
  2.前16位为用户码及其反码,后16位为操作码及其反码。
  3.以脉宽为0.565ms,间隔为0.56ms,周期为1.125ms的组合表示为“0”
  4.以脉宽为0.565ms,间隔为1.685ms周期为2.25ms的组合表示为“1”
  注:引导码+用户码+用户反码+操作码+操作反码
  其中:后四项总共32位
程序思路:
思路一:
主函数:
if( t==34 )
         {      
                 /*把所采集的32位数分别分四组每一组8位,
                 这样很方便的分出用户码、用户反码、操作码、
                 操作反码,a[0]是用户码,a[1]用户反码,
                 a[2]是操作码,a[3]是操作反码*/
                    for(ii=0;ii<4;ii++)
                          {
                                  for(jj=0;jj<8;jj++)
                                 {                  
                               if(aa[dd]<=17)
                                   bb &= 0xfffffffe;
                                   if(aa[dd]>=23)
                                   bb |= 0x00000001;
                                   if(jj<8)
                                   bb=bb<<1;       
                                   dd++;         
                                 }
                             tt[ii]=bb;//把32位码分为
                             bb=0;       
                          }
                            DigDisplay();
                            dd=3;//每次循环完之后dd清零防止下一次循环重复
                    t = 0;
                            INTF=0;//TMR2与PR2未匹配
                            INTE=1;//允许外部中断
                            flag1=0;//标志位清零
                                TMR2ON = 0;//定时器2关闭
                        
         }
中断函数:
/*中断函数*/
void interrupt ISR(void)
{
    if(TMR2IE && TMR2IF)//定时器2产生中断
     {
         TMR2IF = 0;//TMR2与PR2不匹配
                 num++;//每个周期80us自加1
     }   
   if(INTE && INTF)//外部中断开始
     {
                PEIE=0;//禁止外设中断开启
                t++;//每进1次中断自加1,方便看出几个下降沿
                if( t==1 && flag1==0)//当第一次下降沿触发中断就开始计时
                {
                   TMR2ON=1;//定时器使能
                }
                if( t==2 && 167<num<170 )//是否接受到引导码
                {
                   flag1=1;
                }
                if( flag1==0 )//过滤连续码
                {
                   num=0;
                   return;
                }
                if( flag1==1 && t>2 && t<=34)//成功接受到引导码
            {
                    aa[t]=num;//aa[t]存放每一位的时间,用来判断后面每一位是0还是1
                }       
            num=0;//num清零               
                INTF=0;
        PEIE=1;
          }  
}       
显示函数:
void DigDisplay()
{
               switch(tt[2])
                        {
                         case(0xA2)://CH-
                         x=1;break;
                         
                         case(0x62)://CH
                         x=2;break;
                         
                         case(0xE2)://CH+
                         x=3;break;
                         
                         case(0x22)://倒退
                         x=4;break;
                         
                         case(0x02)://前进
                         x=5;break;
                         
                         case(0xC2)://播放
                         x=6;break;
                         
             case(0xE0)://-
                         x=7;break;
                         
             case(0xA8)://+
                         x=8;break;
                         
             case(0x90)://EQ
                         x=9;break;
                         
                         case(0x68)://0
                         x=10;break;
                         
             case(0x98)://100+
                         x=11;break;
                         
             case(0xB0)://200+
                         x=12;break;
                         
             case(0x30)://1
                         x=13;break;
                         
             case(0x18)://2
                         x=14;break;
                         
             case(0x7A)://3
                         x=15;break;
                         
                         case(0x10)://4
                         x=16;break;
                         
             case(0x38)://5
                         x=17;break;
                         
             case(0x5A)://6
                         x=18;break;
                         
                         case(0x42)://7
                         x=19;break;
                         
             case(0x4A)://8
                         x=20;break;
                         
                         case(0x52)://9
                         x=21;break;
                         
                        }
                       
      STB=1;
          STB=0;
          cmd(0x44);
      delay(10);
                 
          shiwei=x/10;
          gewei=x%10;
          
          cmd(0xC4); //十位
      send(table1[shiwei]);
          
      cmd(0xC6); //个位
      send(table1[gewei]);
          
          cmd(0xC0);//千
          send(0x00);
          
          cmd(0xC2); //百
          send(0x00);
          
      cmd(0x8f);  
          STB=1;
}
程序思路二:
主函数:
void main(void)
{   OSCCON=0x70;//设置时钟为4M
    TRISB&=0xf8;//设置RB0,RB1,RB2为输出脚   
    intr_con(); //总中断初始化
    timer1_int();//定时器1初始化        
    while(1)
    {      
           if(tt == 34)       
                {
                        DigDisplay();
                    //原码判断,显示程序
                        //  INTE=1;//允许外部中断
                        //  flag=0;
                          tt = 0;
                          INTF=0;
                          INTE=1;//允许外部中断
                          flag=0;
                          TMR2ON = 0;
                }
               
    }         
}
中断函数:
void interrupt ISR(void)
{
    if(TMR2IE && TMR2IF)//定时器2产生中断
     {
         TMR2IF = 0;//TMR2与PR2不匹配
                 num++;
     }   
   if(INTE && INTF)//外部中断开始
     {
                  
                PEIE = 0;//外设中断清零
                tt++; //进一次中断自加一次,能算出进了多少次中断
                if(tt == 1 && flag == 0)//第一次下降沿时,tt=1
                  TMR2ON = 1;//定时器开始计时
                if(tt == 2 && num>=160)//第二次下降沿时,如果通过引导码,这继续执行
                  flag=1;
                if(flag == 1 && tt>2 && tt<=34)
                  {
                          if(num<=16)//当时间小于1.125毫秒时
                             aa &= 0xfffffffe;//变量aa最后一位清零
                          if(num>=26)//如果时间大于2.25毫秒时,程序最后一位置1
                             aa |= 0x00000001;
                          if(tt < 33)
                            aa=aa<<1;  
                   }
                if(tt == 34)
                  {
                        aa &= 0x0000ffff;//只看操作码,清零前16位
                        INTE = 0;//不允许外部中断
                  }
                num = 0;
                INTF=0;
                PEIE = 1;
          }  
}       
显示函数:
void DigDisplay()
{
               switch(aa)
                        {
                         case(0x0000D12F)://CH-
                         x=1;break;
                         
                         case(0x0000B14F)://CH
                         x=2;break;
                         
                         case(0x0000F10F)://CH+
                         x=3;break;
                         
                         case(0x0000916F)://倒退
                         x=4;break;
                         
                         case(0x0000817F)://前进
                         x=5;break;
                         
                         case(0x0000E11F)://播放
                         x=6;break;
                         
             case(0x0000F00F)://-
                         x=7;break;
                         
             case(0x0000D42B)://+
                         x=8;break;
                         
             case(0x0000C837)://EQ
                         x=9;break;
                         
                         case(0x0000B44B)://0
                         x=10;break;
                         
             case(0x0000CC33)://100+
                         x=11;break;
                         
             case(0x0000D827)://200+
                         x=12;break;
                         
             case(0x00009867)://1
                         x=13;break;
                         
             case(0x00008C73)://2
                         x=14;break;
                         
             case(0x0000BD43)://3
                         x=15;break;
                         
                         case(0x00008877)://4
                         x=16;break;
                         
             case(0x00009C63)://5
                         x=17;break;
                         
             case(0x0000AD53)://6
                         x=18;break;
                         
                         case(0x0000A15F)://7
                         x=19;break;
                         
             case(0x0000A55B)://8
                         x=20;break;
                         
                         case(0x0000A957)://9
                         x=21;break;
                          
                        }
                       
      STB=1;
          STB=0;
          cmd(0x44);
      delay(10);       
          shiwei=x/10;
          gewei=x%10;
          cmd(0xC4); //十位
      send(table1[shiwei]);
      cmd(0xC6); //个位
      send(table1[gewei]);
          cmd(0xC0);//千
          send(0x00);
          cmd(0xC2); //百
          send(0x00);
      cmd(0x8f);  
          STB=1;
}

如果需要PIC原装芯片或者替代芯片的都可以联系我。颜生13430885511(微信同号)/qq2355910801

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top