⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 learnable-ir.c

📁 learnable-ir.c 红外遥控器解码程序
💻 C
字号:
 //Fosc=11.0592MHz   
 // states for and variables IR data processing ; 
 #include <reg51.h>  
 #define unsigned char uchar
 #define unsigned int uint
 typedef enum{    
              IR_idle,    
              IR_waitstart,             
              IR_getaddr,             
              IR_getaddrinv,             
              IR_getdata,             
              IR_getdatainv             
             }_IRstate;                  
   
 _IRstate IRstate = IR_idle;   
   
 uchar IRaddr=0xff;   
 uchar _IRaddr=0xff;   
 uchar IRdata=0xff;   
 uchar _IRdata=0xff;   
 uchar IR_repeat=0;   
 uchar IR_ready=0;   
 uchar  IR_poweron=0;   
 //bit ir_done=0;   
 // time constants   
 uint IRtimer=0; // IR timeout    
   
 //cpu初始化   
 void cpu_init(void)   
 {   
     TMOD=0X11; // T0 and T1 十六位定时                   
     TH0=0xee;  //fosc=11.0592M,timer=5ms   
     TL0=0x00;    
     TR0=1; // run timer 0;   
     TF0=0;   
   
     ET0=1;  // enable tmr 0 overflow interrupt   
     IT0=1; // int0 edge sensitive   
     EX0=1; //  enable "int0"   
     EA=1;   // global interupt enable    
 }   
   
 //T0中断   
 void tmrint() interrupt 1   
 {   
     TH0=0xee;   
     TL0=0x00;    //5ms
     if (IRtimer)     //IR接收超时   
         --IRtimer; //    
     else  
     {   
         IRstate=IR_idle;   //IRstate标志接收头状态,为0则标志有红外信号
 //        IR_poweron=0;   
     }   
 }   
   
 //Fosc=11.0592MHz   
#define msec_12p5  0x2d00   
#define msec_15  0x3600   
#define msec_9  0x2066   
 //define msec_9  0x1066   
#define msec_2p5  0x900   
#define msec_0p9  0x33d   
#define msec_1p68  0x610   
   
   
 //void IRint() interrupt 0(void)   
   
 //When the IR receive pin goes low and interrupt is generated    
 // IR is collected by starting timer 2 in the first falling edge of the pin   
 // then on every other falling edge, the timer value is saved and the timer restarted .     
 // the captured time is then used to get the IR data    
 // a "start of data" is 13.5Msec,a "1" is 2.25Msec,a "0" is 1.12 msec and a "repeat" is 11.25msec.   
 // the counter increments at 1.085 Usec   
 // I allow a fairly large tolerance to time jitter but there are no false triggers seen.   
   
 void IRint() interrupt 0   
 {   
     static uchar bits;   
     unsigned short time;   
     switch(IRstate)   
     {   
         case IR_idle:   
             TL1=0;   
             TH1=0;   
             TR1=1;   
             IRstate=IR_waitstart;   
             IRtimer=26;   
             break;   
         case IR_waitstart: //P2_4=!P2_4;   
             TR1=0;   
             time=TH1;   
             time =(time <<8)+TL1;;   
             TL1=0;   
             TH1=0;   
             TR1=1;   
             if ((time > msec_12p5)&&(time < msec_15)) // greater than 12.5Msec & less than 15 msec = start code    
             {       
                 IRaddr=0;   
                 _IRaddr=0;   
                 IRdata=0;   
                 _IRdata=0;   
                 bits=1;   
                 IRstate=IR_getaddr;   
             }   
             else if ((time > msec_9)&&(time <  msec_12p5))// less than 12.5Msec  and greater than 9 msec =Repeat code    
             {        
                 IR_repeat=2;   
                 IRstate=IR_idle;   
             }   
             else    
             {           // to short, bad data just go to idle    
                 IRstate=IR_idle;                   
             }                   
             break;   
         case IR_getaddr:    // P2_4=!P2_4;   
             TR1=0;   
             time=TH1;   
             time =(time <<8)+TL1;;   
             TL1=0;   
             TH1=0;   
             TR1=1;   
             if ((time>msec_2p5)||(time<msec_0p9))// if  > 2.5msec or shorter than .9Msec bad data , go to idle    
             {      
                 IRstate=IR_idle;   
                 break;    
             }   
             if (time>msec_1p68)// greater than 1.68Msec is a 1   
             {         
                 IRaddr|= bits;   
             }   
             bits=bits<<1;   
             if (!bits)   
             {   
                 IRstate=IR_getaddrinv;                   
                 bits=1;   
             }   
             break;                 
         case IR_getaddrinv:  //P2_4=!P2_4;   
             TR1=0;   
             time=TH1;   
             time =(time <<8)+TL1;;   
             TL1=0;   
             TH1=0;   
             TR1=1;   
             if ((time>msec_2p5)||(time<msec_0p9))// if  > 2.5msec or shorter than .9Msec bad data , go to idle    
             {      
                 IRstate=IR_idle;   
                 break;    
             }   
             if (time>msec_1p68)// greater than 1.68Msec is a 1    
             {        
                 _IRaddr|= bits;   
             }   
             bits=bits<<1;   
             if (!bits)   
             {   
                 IRstate=IR_getdata;;                   
                 bits=1;   
             }   
             break;                 
         case IR_getdata:   
             TR1=0;   
             time=TH1;   
             time =(time <<8)+TL1;;   
             TL1=0;   
             TH1=0;   
             TR1=1;   
             if ((time>msec_2p5)||(time<msec_0p9))// if  > 2.5msec or shorter than .9Msec bad data , go to idle   
             {       
                 IRstate=IR_idle;   
                 break;    
             }   
             if (time>msec_1p68)// greater than 1.68Msec is a 1   
             {         
                 IRdata|= bits;   
             }   
             bits=bits<<1;   
             if (!bits)   
             {   
                 IRstate=IR_getdatainv;                   
                 bits=1;   
             }   
             break;                 
         case IR_getdatainv:   
             TR1=0;   
             time=TH1;   
             time =(time <<8)+TL1;;   
             TL1=0;   
             TH1=0;   
             TR1=1;   
             if ((time>msec_2p5)||(time<msec_0p9)) // if  > 2.5msec or shorter than .9Msec bad data , go to idle    
             {      
                 IRstate=IR_idle;   
                 break;    
             }   
             if (time>msec_1p68)// greater than 1.68Msec is a 1    
             {        
                 _IRdata|= bits;   
             }   
             bits=bits<<1;   
             if (!bits)         // we have it all , now we make sure it is a NEC code from the CHS IR transmitter   
             {                   // make sure address,~address are correct , data ,~data are correct and address is 0.   
                 IR_ready=((IRaddr^_IRaddr)==0xff)&&((IRdata^_IRdata)==0xff)&&(IRaddr==0);   
                 if(IR_ready)   
                 {   
                     IRstate=IR_idle;   
                 }       
             }   
             break;                 
         default:   
             IRstate=IR_idle;   
             break;   
     }   
 }   
   
 void main(void)   
 {   
     cpu_init();   
     while(1)   
     {   
         if(IR_ready)   
         {   
             IR_ready=0;   
             switch(IRdata)   
             {   
                 case 0x45:        //1   
                     //your code   
                     break;   
                 case 0x44:        //3   
                     //your code   
                     break;   
                 case 0x43:       //4   
                     //your code   
                     break;   
                 case 0x08:        //prev   
                     //your code   
                     break;   
                 case 0x5a:        //next   
                     //your code   
                     break;   
                 default:   
                     break;   
           }   
         }   
     }   
 }  

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -