chenyonken 2016-10-15 03:08 采纳率: 0%
浏览 1984
已结题

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

有一个问题,是关于红外线接收的,在外部中断函数里出错了,功能是按下遥控器的一个键,在数码管上显示相应数字,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();
}




  • 写回答

3条回答 默认 最新

  • LiasMs 2016-10-15 03:33
    关注

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

    评论

报告相同问题?

悬赏问题

  • ¥15 用visual studi code完成html页面
  • ¥15 聚类分析或者python进行数据分析
  • ¥15 逻辑谓词和消解原理的运用
  • ¥15 三菱伺服电机按启动按钮有使能但不动作
  • ¥15 js,页面2返回页面1时定位进入的设备
  • ¥50 导入文件到网吧的电脑并且在重启之后不会被恢复
  • ¥15 (希望可以解决问题)ma和mb文件无法正常打开,打开后是空白,但是有正常内存占用,但可以在打开Maya应用程序后打开场景ma和mb格式。
  • ¥20 ML307A在使用AT命令连接EMQX平台的MQTT时被拒绝
  • ¥20 腾讯企业邮箱邮件可以恢复么
  • ¥15 有人知道怎么将自己的迁移策略布到edgecloudsim上使用吗?