发布论文 | 上传资料 | 发布供求 | 发布求职 | 发布项目 | 加入收藏 | RSS
您当前的位置:首页 > 文章中心 > 单 片 机 > 51单片机

keil c51红外遥控解码源程序

时间:2008-07-25 13:48:28  来源:  作者: 点击:18

keil c51程序适用uPC1621/uPC1622及兼容的红外遥控器芯片,占用外部中断0和定时器1,以中断方式解码,节省系统资源,以查询方式检测遥控信号是否有效.
解码思路:
    红外线经一体化接受头解码放到后送到单片机的外部中断0,单片机设置外部中断下降沿触发,T0和T1为16位定时器,T0在系统启动后定时5ms.T1在外部中断0启动后开始定时,初值为0,每次在INT0中断后先读T1计数值,并重设初值为0,而且判断T1的计数值,


代码
//Fosc=11.0592MHz   
// states for and variables IR data processing ;   
typedef enum{    
             IR_idle,    
             IR_waitstart,             
             IR_getaddr,             
             IR_getaddrinv,             
             IR_getdata,             
             IR_getdatainv             
            }_IRstate;                  
  
_IRstate IRstate = IR_idle;   
  
unsigned char IRaddr=0xff;   
unsigned char _IRaddr=0xff;   
unsigned char IRdata=0xff;   
unsigned char _IRdata=0xff;   
unsigned char IR_repeat=0;   
unsigned char IR_ready=0;   
unsigned char  IR_poweron=0;   
//bit ir_done=0;   
// time constants   
unsigned int 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;    
    if (IRtimer)     //IR接收超时   
        --IRtimer; //    
    else  
    {   
        IRstate=IR_idle;   
//        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 unsigned char 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;   
         &n bsp;  }   
        }   
    }   
}   

来顶一下
近回首页
返回首页
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表
推荐资讯
音乐程序的设计原理之单片机
音乐程序的设计原理之
FPGA的可编程全数字锁相环路实现
FPGA的可编程全数字锁
什么是模拟电路?
什么是模拟电路?
挪威发明蛇形消防机器人
挪威发明蛇形消防机器
相关文章
    无相关信息
栏目更新
栏目热门