单片机红外接收程序出错问题

有一个问题,是关于红外线接收的,在外部中断函数里出错了,功能是按下遥控器的一个键,在数码管上显示相应数字,NEC协议,引导码是9ms高电平+4.5ms低电平,但在外部中断里判断接收到的引导码中的高电平持续时时间时出错了,结果就是数码管只是显示默认的值图片说明
L1灯总是被点亮,说明后面读取用户根本就没有进行,但我又找不到我的获取电平持续时间函数错在哪(晶振11.0592MHZ),求教

 #include<reg52.h>
#include<intrins.h>

#define uint8 unsigned char 
#define uint16 unsigned int 
#define uint32 unsigned long int 
#define DataPort P0

uint8 code DuanMa[16]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
                        0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//共阴数码管段选码表,无小数点
sbit IR_RECEIVE=P3^2;
sbit dula=P2^6;
sbit wela=P2^7;
sbit L0=P1^0;
sbit L1=P1^1;
sbit L2=P1^2;
sbit L3=P1^3;
sbit L4=P1^4;
sbit L5=P1^5;
sbit L6=P1^6;
sbit L7=P1^7;

bit irflag=0;
uint8 ircode[4];
uint8 T0RH=0;
uint8 T0RL=0;

uint8 i,j;
uint16 time;
uint8 byt;

void InitInfrared();//红外线初始化
uint8 GetHighTime();//读高电平持续时间,实际发过来的是低电平
uint8 GetLowTime();//获取低电平持续时间,实际发过来的是高电平
void ConfigTimer0(uint8 ms);
void LedScan();//数码管动态扫描刷新函数,需在定时中断中调用

void main()
{   
    EA=1;
    InitInfrared();
    ConfigTimer0(1); //定时器0初始化
    PT0=1;           //定义定时器0为高优先级中断

    DataPort=0xfe; //取位码 第一位数码管选通,即二进制1111 1110
    wela=1;      //位锁存
    wela=0;

    while(1)
    {

    }

}


void InitInfrared()//红外线初始化
{
    IR_RECEIVE=1;
    TMOD&=0X0F;
    TMOD|=0X10;
    TR1=0;
    ET1=0;
    IT0=1;
    EX0=1;
}

uint8 GetHighTime()//读高电平持续时间,实际发过来的是低电平
{
    TH1=0;
    TL1=0;
    TR1=1;
    while(IR_RECEIVE)//避免没有收到起始信号而使程序一直停滞在这一步,需有个定时
    {
        if(TH1>0X40) 
        {
            break;
        }
    }
    TR1=0;
    return(TH1*256+TL1);//每个TH1代表256个TL1,1.09*(TH1*256+TL1)   
}

uint8 GetLowTime()//获取低电平持续时间,实际发过来的是高电平
{
    TH1=0;
    TL1=0;
    TR1=1;
    while(!IR_RECEIVE)
    {
    if(TH1>0X40)      //远远超过了9ms
        {
            break;
        }
    }
    TR1=0;
    return(TH1*256+TL1);
}

void INT0_Interrupt() interrupt 0
{
    L0=0;
    time=GetLowTime(); //获取低电平持续时间
    if((time<7833)||(time>8755))// 8537-9542us,9ms误差允许
    {
        L1=0;
        IE0=0;
        return;
    } 
    time=GetHighTime();//获取高电平持续时间
    if((time<3686)||(time>4608))//4.5ms误差允许
    {
        L2=0;
        IE0=0;
        return;
    }  
    for(i=0;i<4;i++)
    {
        if(i==0)L3=0;
        if(i==1)L4=0;
        if(i==2)L5=0;
        if(i==3)L6=0;
        for(j=0;j<8;j++)
        {
            time=GetLowTime();
            if((time<313)||(time>718))//341-782,560us误差允许,发送过来的0和1都是从560us的高电平开始
            {
                IE0=0;
                return; 
            }  
            time=GetHighTime();
            if((time>313)&&(time<718))//如果560us(上一句),检测时间,与之前的560us合起来判断是0还是1,过后341-782,最好是560,如果是这种情况,则发送过来的则为0
            {
                byt>>=1;
            }  
            else if((time>1345)&&(time<1751))//高电平持续时间1466-1908,最好是1690,发送过来的是1
            {
                byt>>=1;
                byt|=0X80;  
            }
            else
            {
                IE0=0;
                return;
            }  
            L7=0;
        }
        ircode[i]=byt;
        irflag=1;
    }
    IR_RECEIVE=1;
    IE0=0;

}

void ConfigTimer0(uint8 ms)
{
    uint32 tmp;
    tmp=11059200/12;
    tmp=(tmp*ms)/1000;
    tmp=65536-tmp;
    tmp=tmp+18;//补偿中断响应延时造成的误差
    T0RH=(uint8)(tmp>>8);
    T0RL=(uint8)tmp;
    TMOD&=0XF0;//清除T0的控制位
    TMOD|=0X01;//配置T0为模式1
    TH0=T0RH; //加载T0的重载值
    TL0=T0RL;
    ET0=1;
    TR0=1;  

}

void LedScan()//数码管动态扫描刷新函数,需在定时中断中调用
{
    if(irflag)
    {
        irflag=0;
        switch(ircode[2])
        {
        case 0X0C:DataPort=DuanMa[1];break;
        case 0X18:DataPort=DuanMa[2];break;
        case 0X5E:DataPort=DuanMa[3];break;
        case 0X08:DataPort=DuanMa[4];break;
        case 0X1C:DataPort=DuanMa[5];break;
        case 0X5A:DataPort=DuanMa[6];break;
        case 0X42:DataPort=DuanMa[7];break;
        case 0X52:DataPort=DuanMa[8];break;
        case 0X49:DataPort=DuanMa[9];break;
        }
    }       
}

void T0_Interrupt() interrupt 1
{
    TH0=T0RH;
    TL0=T0RL;
    LedScan();
}




//刚才的代码中的延时函数:
void DelayMs(unsigned int x) //0.14ms误差 0us
{
unsigned char i;
while(x--)
{
for (i = 0; i<13; i++)
{}
}
}

http://wenku.baidu.com/link?url=y6VyxKrdK632PYHn-i4QObMx4ckz0okJ7cVJPQab1dq7iulWIQbD0DnI0PRlgvXazGJNLD6a52wN3qlIhOdplU-oGXbB-egOjaoCF9USrWO

//楼主这个解码算法不够严谨,附上我的解码:
void ReadIr() interrupt 0
{
unsigned char j,k;
unsigned int err;
Time=0;

DelayMs(70);

if(IRIN==0)     //确认是否真的接收到正确的信号
{    

    err=1000;               //1000*10us=10ms,超过说明接收到错误的信号
    /*当两个条件都为真是循环,如果有一个条件为假的时候跳出循环,免得程序出错的时
    侯,程序死在这里*/  
    while((IRIN==0)&&(err>0))   //等待前面9ms的低电平过去         
    {           
        DelayMs(1);
        err--;
    } 
    if(IRIN==1)         //如果正确等到9ms低电平
    {
        err=500;
        while((IRIN==1)&&(err>0))        //等待4.5ms的起始高电平过去
        {
            DelayMs(1);
            err--;
        }
        for(k=0;k<4;k++)        //共有4组数据
        {               
            for(j=0;j<8;j++)    //接收一组数据
            {

                err=60;     
                while((IRIN==0)&&(err>0))//等待信号前面的560us低电平过去
                {
                    DelayMs(1);
                    err--;
                }
                err=500;
                while((IRIN==1)&&(err>0))    //计算高电平的时间长度。
                {
                    DelayMs(1);//0.14ms
                    Time++;
                    err--;
                    if(Time>30)
                    {
                        EX0=1;
                        return;
                    }
                }
                IrValue[k]>>=1;  //k表示第几组数据
                if(Time>=8)         //如果高电平出现大于565us,那么是1
                {
                    IrValue[k]|=0x80;
                }
                Time=0;     //用完时间要重新赋值                           
            }
        }
    }
    if(IrValue[2]!=~IrValue[3])
    {
        return;
    }
}           

}