51单片机解码PT2262出现问题

2020-01-18 18:48发布

大家好,我的单片机负荷比较重,但必须接收PT2262信号,我设计如下程序,为什么不能接收到一串数据?


在定时器1中断中判断同步码,接收到同步码之后,开启外部中断0,在外部中断0里面接收数据,可是最后都出现错误,通过串口发送出来的结果是j = 0;i = 0,dd = 1或2,很迷茫当中。

请教大家问题出在哪里?谢谢


程序如下:

sbit wireless_code_in        = P3 ^ 2; // 无线信号接收端


/************************************************
* 函数: int0_Interrupt_Server
* 功能: 外部中断0中断服务程序
* 入口: 无
* 出口: 无
***********************************************/
void int0_Interrupt_Server(void) interrupt 0
{
        unsigned char i,j,dd;
        EA = 0;
        EX0=0;
        ///////////////////////////////接收数据///////////////////////////////////////////
        for(j = 0; j < 3; j++)
        {
                for(i = 0; i < 8; i++)
                {
                        TH0 = 0xFD;  // 在11.0592MHZ定时700us
                        TL0 = 0x7B;
                        TF0 = 0;
                        TR0 = 1;
                        wirelessRecvTemp[j] <<= 1;                // 装入数据
                        while(!wireless_code_in)                  // 等待高电平
                        {
                                if(TF0)
                                {
                                        break;
                                }
                        }
                        TR0 = 0;
                        if(!TF0)
                        {
                                wirelessRecvTemp[j] |= 0x01;
                        }
                        else
                        {
                                TH0 = 0xFA;  // 在11.0592MHZ定时1500us
                                TL0 = 0x9A;
                                TF0 = 0;
                                TR0 = 1;
                                while(!wireless_code_in)                  // 等待高电平
                                {
                                        if(TF0)
                                        {
                                                dd = 1;
                                                goto recError;
                                        }
                                }
                        }
                        TR0 = 0;
                        TH0 = 0xFA;  // 在11.0592MHZ定时1500us
                        TL0 = 0x9A;
                        TF0 = 0;
                        TR0 = 1;
                        while(wireless_code_in)                  // 等待高电平
                        {
                                if(TF0)
                                {
                                        dd = 2;
                                        goto recError;
                                }
                        }
                }
        }
        wireless_recv_flg = 1;
recError:
        #ifdef DEBUG
        ES = 0;
        SBUF = j;
        while(!TI)
        {
                ;
        }
        TI = 0;
        SBUF = i;
        while(!TI)
        {
                ;
        }
        TI = 0;
        SBUF = dd;
        while(!TI)
        {
                ;
        }
        TI = 0;
        ES = 1;
        #endif
        start_recv_flg = 0;
        TR0 = 0;
        TF0 = 0;
        EA = 1;
}

/************************************************
* 函数: timer1_Interrupt_Server
* 功能: 定时器1中断服务程序
* 入口: 无
* 出口: 无
***********************************************/
void timer1_Interrupt_Server(void) interrupt 3
{
        EA = 0;
        TH1=0xFC;                                 //定时1ms
        TL1=0x63;
        if(!start_recv_flg)
        {
                if(wireless_code_in)
                {
                        wirelessRecvDelay++;
                        if(wirelessRecvDelay > 9)
                        {
                                wirelessRecvDelay = 0;
                                start_recv_flg = 1;
                                IT0 = 1;
                                EX0 = 1;
                        }
                }
                else
                {
                        wirelessRecvDelay = 0;
                }
        }
        EA = 1;
}


我用来接收PT2262的程序ourdev_680089B7PNBK.rar(文件大小:817字节) (原文件名:pt2262.rar)
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
19条回答
zheng_wei339
1楼-- · 2020-01-20 09:34
用单片机单一软解功能还行,多功能加软解码很不好弄,还是加一个硬解吧,除非你能合理的解决相关中断,干扰及各种功能程序的时序问题
szxszx
2楼-- · 2020-01-20 10:08
软解码2262数据要求实时性很高
JZcrystalwlh888
3楼-- · 2020-01-20 10:17
楼主还不如用PT2272
baimawangzi
4楼-- · 2020-01-20 15:09
PT2262和PT2272本来就是一对儿,为什么要拆散人家?
tonyone
5楼-- · 2020-01-20 15:38
 精彩回答 2  元偷偷看……
coleyao
6楼-- · 2020-01-20 20:14
//===========================无线接收信号检测================================
//-------------------------外部中断1------------------------------
void int_ext1(void) interrupt 2
   {
      if (TWlReceive)
        {
           if (TR1&(Mode_T1==2))
                  {
                         TL1=0x00;   Mode_T1=1;    TH1=0xfc; // TH1=0xfe;
                  } //注释中的TH值可用于接收守财神系列产品信息,否则只接收夜狼系列
                    //如果已开始接收并且定时器1正在2mS定时方式,重新设置定时器1为300uS定时
           EX1=0;   //关闭外部中断1
         }
      if (!TWlReceive)
         {
              TL1=0x00;    Mode_T1=3;  ReInTimer=0; TH1=0xd8;  TR1=1;//TH1=0xec;
         }     //定时10mS
                    //如果没有开始接收,则打开无线接收线程
   }
//------------------------外部中断1结束-----------------------------

//--------------------------定时中断1--------------------------
void int_time_300uS(void) interrupt 3   using 2
   {
    if(TWlSend)          //发送无线信号
     {
      if(ReOutTimer==25)
        {  TWlSend=0;   TR1=0; }
      if(ReOutTimer==24)
       {
        if(Re_SendH)
         {
          Rmodel_Out=1; Re_SendH=0;  Re_SendL=1;
          TH1=0xfe; TL1=0xc0;
         }
        else
         {
          Rmodel_Out=0; Re_SendH=1;  Re_SendL=0;
          TH1=0xc8; TL1=0x00;
          ReOutTimer++;
         }
       }    // end   if(ReOutTimer==25)
      if(ReOutTimer<24)
       {
        if(Re_SendH)
         {
          Rmodel_Out=1; Re_SendH=0;  Re_SendL=1;
          if(ReIHead1) { TH1=0xfe; TL1=0xc0; }  else  { TH1=0xfa; TL1=0xf6; }
         }
        else
         {
          Rmodel_Out=0; Re_SendH=1;  Re_SendL=0;
          if(ReIHead1) { TH1=0xfa; TL1=0xf6; }  else  { TH1=0xfe; TL1=0xc0; }
          R1.Re_InBufC[0]>>=1;  ReITail1=ReIHead2;  R1.Re_InBufC[1]>>=1; ReITail2=ReIHead3;
          R1.Re_InBufC[2]>>=1;
          ReOutTimer++;
         }
       }    // end   if(ReOutTimer<24)
     }
    else                 //接收无线信号
     {
     if(Mode_T1==3)
                       { TWlReceive=1;  }
     if (TWlReceive)
      {
       if(Mode_T1==1)
          {
             ReInputB=Rmodel_In;
             R1.Re_InBufC[0]>>=1;  ReITail1=ReIHead2;  R1.Re_InBufC[1]>>=1; ReITail2=ReIHead3;
             R1.Re_InBufC[2]>>=1;  ReITail3=ReIHead4;  R1.Re_InBufC[3]>>=1; ReITail4=ReInputB;
             ReInTimer++;
          }              //如果由300uS定时进入,则读入无线接收数据,读入数据计数器加1
       if(Mode_T1==2)
          {  if (ReInTimer==25)
               {
                 Re_RecOver=1;
                 ReInputB=ReITail2;
                 R1.Re_InBufC[1]<<=1;  ReIHead2=ReITail1;
                 R1.Re_InBufC[0]=R1.Re_InBufC[1];  ReITail2=ReInputB; ReInputB=ReITail3;
                 R1.Re_InBufC[2]<<=1;  ReIHead3=ReITail2;
                 R1.Re_InBufC[1]=R1.Re_InBufC[2];  ReITail3=ReInputB;
                 R1.Re_InBufC[3]<<=1;  ReIHead4=ReITail3;    R1.Re_InBufC[2]=R1.Re_InBufC[3];
                 Re_InBuf1[0].Re_InBufL=R1.Re_InBufL;
                }
              TWlReceive=0;   TR1=0;
           }            //如果由10mS定时进入,判断是否接收完毕,如是则保存并处理数据,否则丢弃数据
       Mode_T1=2;   TL1=0x00;   EX1=1;    TH1=0xd8;  // TH1=0xec;    //如果在无线接收线程中,则置定时器1为10mS定时
      }
     }
   }
//------------------------定时中断1结束-----------------------------------------




/*==============时钟计算、防区输入、按钮输入、出入延时、盗警确认===================*/
//-------------------定时中断1,使用定时器0-----------------------
void int_time_20ms(void) interrupt 1  //using 3   // 20ms timer
   {
     TH0 = 0xb8 ;           //TH0=0xee, 5ms定时;   TH0=0x4c, 50ms定时
     H_Load=0;  H_Load=1;  SCON=0x10;            //启动串口数据输入
//时间基准部分
   if (Time_st>80)                                      //50mS定时
     {   Time_Temp++;  Time_st-=80;   MSecChange=1;
         if (Time_Temp>20)                              //1S定时
          {   Second++;     Time_Temp-=20; SecChange=1;
             if (Second>59)                             //1Min定时
              {   Minute++;     Second-=60;    MinChange=1;  }
          }
     }
    if (Minute>59)                                      //1Hour定时
      {   Hour++;       Minute-=60;    HouChange=1;
        if (Hour>23)                                    //1Day定时
          {   Day++;        Hour-=24;      DayChange=1;
              Leap=(YearL%4==0&&(YearL%100!=0||YearH%4==0));
              if (Day>Daytab[Leap][Month])
                 { Month++; Day=1;
                   if (Month>12)   { YearL++; Month-=12; }
                   if (YearL>100)  { YearH++; YearL-=100;}
                 }
           }
       }
  if(TF2)  Expandint2();
//跟时间基准有关的计数器部分
      Timer_1S++;  BeepTimer++;    Timer_Det--;   Timer_8870++;
     if ((VoiceLength>60000)&&(VoiceLength<60200))  VoiceLength=0xffff;
     if ((VoiceLength==0)||(VoiceLength>60000))
       { VoicePlay=1;  VoiceOn=0;  }              //语音播放定时关闭
     if (MSecChange)  {                                   //每约50mS执行一次
                        Dial_Delay++;   Timer_Rec++;
                        if(!VoiceOn&!VoiceSpare)  Timer_Spare++;
                        if (Timer_Spare==0xff) Timer_Spare=201;
                        MSecChange=0;
                      }
     if (SecChange)                                      //每秒执行一次
      {
         if(!ArmLed) RunLed=1;  else RunLed=!RunLed;
         if(ProgLed)  { if(!ArmLed) { ArmLed=1; RunLed=0; }
                         else ArmLed=!RunLed;  }
         if ((Second%2)==1)  HornTimer--;
         if (HornTimer==0)   AlarmHorn=1;
          Timer_PWPhone++;  Timer_Dial++;  Timer_CodeRem++;
          SecChange=0;
      }
     if (MinChange)                                      //每分钟执行一次
      {
        Timer_WContact++;
        if(Timer_WContact>10)  { Timer_WContact-=10;  Wcontact=1;  }
        MinChange=0;
      }
  if(TF2)  Expandint2();
//摘机检测部分
  if(TPickup)
   {
    if (!Onring&TelDetctingL&(Picked_CounterL>160))
                    { Timer_PhonePicked++; Picked_CounterL-=160;  }        //振铃端信号持续100mS累加一次
    if (Timer_PhonePicked>6)                                                //振铃端信号持续0.6S判断摘机性质
      {
        if((Picked_Counter>4)||(BellNum_Buf!=BellNumber))
                Timer_PhonePicked-=6;                           //摘机前响过铃则等挂机
         else { PhonePicked=1;   Timer_PhonePicked=0;  Picked_Counter=0;     BellNum_Buf=BellNumber;  }  //否则认为本地摘机
                TelDetctingL=0;  TelDetctingH=0;       Picked_CounterL=0;    Picked_CounterH=0;  TPickup=0;  TDeCode=1;
      }
    if((Timer_NoPulse>10)&&(Picked_Counter>8))                            //检测到8个以上的振铃脉冲并且无脉冲持续1S以上认为一次振铃
          { Picked_Counter=0;    BellNum_Buf--;     TelDetctingL=0;  TelDetctingH=0;
            Picked_CounterL=0;   Picked_CounterH=0; Timer_NoPulse=0;   }       //每振铃一次后计数器递减
    if (Onring&TelDetctingH&(Picked_CounterH>160))
               { Timer_NoPulse++;   Picked_CounterH-=160; }        //振铃端100mS无信号累加一次
    if (BellNum_Buf==0)   {  TelDetctingL=0;  TelDetctingH=0;  Picked_CounterL=0; Picked_CounterH=0;   TDeCode=1;
           OutLineInConfirmed=1; Picked_Counter=0;   BellNum_Buf=BellNumber;  TPickup=0; }   //振铃次数到达后外线摘机
   }
  if(TF2)  Expandint2();
//挂机检测部分
  if(THandup)
   {
    if (Onring)  Timer_PhoneHandup++;    else   Timer_PhoneHandup=0;
    if (Timer_PhoneHandup==0xff)  Timer_PhoneHandup-=100;
    if (Timer_PhoneHandup==100)
                                 {  PhonePicked=0;      OutLineInConfirmed=0; Timer_PhoneHandup++;   THandup=0;
                                    TelDetctingL=0;     TelDetctingH=0;       Picked_CounterL=0;     TDeCode=0;
                                    Picked_CounterH=0;  Picked_Counter=0;     BellNum_Buf=BellNumber;   }   //5S无摘机或振铃信号后挂机
   }
  if(TF2)  Expandint2();
//Mt8870收号部分
  if(TDeCode)
   {
     if (Mt8870_rxd&!CodeReceiveTriggered&!Mt8870Confirmed)                                                 //触发收号过程
                   { Timer_Det=5; CodeReceiveTriggered=1;  }
     if (CodeReceiveTriggered&(Timer_Det==0))                                                                //保持100mS开始收号
           {    Dataof8870=P0;           Dataof8870>>=4;
                if(Dataof8870==10)       Dataof8870=0;
                Mt8870Confirmed=1;       CodeReceiveTriggered=0;
                Timer_Spare=0;          //语句间隙在收到号码时停止
           }
     if (Timer_Det==100)      Timer_Det=0xff;                                                     //复位收号计数器
     if (Timer_8870==3)                                     //收取号码在按键松开后保持60ms(需大于40ms)
                            { Mt8870Confirmed=0;  Dataof8870=0xff;  Jumped=0; }
     if (Timer_8870==0xff)     Timer_8870=100;                        //复位保持计数器
  }
//有线防区报警检测部分
    AlarmData=SBUF;
    RI=0;
    AlarmBuf=AlarmData&ZoneNormal;          //如果没有防区故障或报警,应为0
    ALedBuf=AlarmBuf;
  if(WireZoneOn)              //有线防区由菜单中选项打开或关闭,前面7个为常闭防区,最后一个为常开防区
    {
       if(RemoteArmConfirmed&(AlarmBuf==0))  Armed=1;
       if (Armed)
         {
           ArmLed=0;
           if(AlarmBuf!=0)
             { if(!AlarmRecover) ThiefInConfirmed=1;  AlarmRecover=1; }
            else AlarmRecover=0;
         }
       else ArmLed=1;
    }
  else
    {
       if (RemoteArmConfirmed)   { RemoteArmConfirmed=0;  Armed=1;  }
       if (Armed)    ArmLed=0;    else ArmLed=1;
    }
//无线解码部分
  if (Re_RecOver)
   {
    if ((Re_InBuf1[0].Re_InBufL!=Re_InBuf1[1].Re_InBufL)&!Re_ReValid) { Re_InBuf1[1].Re_InBufL=Re_InBuf1[0].Re_InBufL;    }
     else
      {
        Re_ReValid=1;
        Re_InAddress=Re_InBuf1[1].Re_InBufL&0xffff;
        Re_InOper=Re_InBuf1[1].Re_InBufC[3];
      }
     Re_RecOver=0;
   }
}
//----------------------------定时中断1结束-------------------------


//-------------------定时中断5,使用定时器2-----------------------
void int_time_st(void) interrupt 5   using 1       // 0.625ms timer
{
   Time_st++;
//摘机检测部分
   if (!Onring&!OutLineInConfirmed&!PhonePicked)  TPickup=1;
    if(TPickup)
     {
     if (!TelDetctingL&!TelDetctingH)   //判断内外线摘机开始
              { TelDetctingL=1; Picked_CounterL=0; Picked_CounterH=0;  }              //开始低电平计数
     if(TelDetctingL)
       {
         if (!Onring)   Picked_CounterL++;
         else  {Picked_CounterH=Picked_CounterL; TelDetctingL=0; TelDetctingH=1;   Picked_CounterL=0; } //转入高电平计数
       }
     if(TelDetctingH)
      {
        if (Onring)   Picked_CounterH++;
         else
          {
            if ((Picked_CounterH<10)||(Picked_CounterH>179))        //去除周期在6.25mS以下和50mS以上的脉冲
               { TelDetctingH=0; Picked_CounterH=0; }
            if ((Picked_CounterH>9)&&(Picked_CounterH<180))         //计入周期在6.25mS和50mS之间的脉冲
                { Picked_Counter++; TelDetctingH=0; Picked_CounterH=0; }
          }
       }
     if (Onring)   { Timer_PhonePicked=0;  Picked_CounterL=0;  }  else   Timer_NoPulse=0;
     }                                                                             //判断内外线摘机结束

//MT8870收号部分
  if(TDeCode)
   {
     if (!Mt8870_rxd)   CodeReceiveTriggered=0;                                    //消除脉冲干扰
     if (Mt8870Confirmed&!Mt8870_rxd&!Jumped)
                                              { Timer_8870=0; Jumped=1; }          //进入收号保持状态
   }
//Isd2532语音播放部分
     VoiceLength--;     Timer_Voice++;
     Time_delay++;
     TF2=0;
}                                                                            //224us
//--------------------------定时中断3结束------------------------------------


//-------------------------定时中断3扩展函数-----------------------
void Expandint2(void)
{
   Time_st++;
//摘机检测部分
   if (!Onring&!OutLineInConfirmed&!PhonePicked)  TPickup=1;
    if(TPickup)
     {
     if (!TelDetctingL&!TelDetctingH)   //判断内外线摘机开始
              { TelDetctingL=1; Picked_CounterL=0; Picked_CounterH=0;  }              //开始低电平计数
     if(TelDetctingL)
       {
         if (!Onring)   Picked_CounterL++;
         else  {Picked_CounterH=Picked_CounterL; TelDetctingL=0; TelDetctingH=1;   Picked_CounterL=0; } //转入高电平计数
       }
     if(TelDetctingH)
      {
        if (Onring)   Picked_CounterH++;
         else
          {
            if ((Picked_CounterH<10)||(Picked_CounterH>179))        //去除周期在6.25mS以下和50mS以上的脉冲
               { TelDetctingH=0; Picked_CounterH=0; }
            if ((Picked_CounterH>9)&&(Picked_CounterH<180))         //计入周期在6.25mS和50mS之间的脉冲
                { Picked_Counter++; TelDetctingH=0; Picked_CounterH=0; }
          }
       }
     if (Onring)   { Timer_PhonePicked=0;  Picked_CounterL=0;  }  else   Timer_NoPulse=0;
     }                                                                             //判断内外线摘机结束

//MT8870收号部分
  if(TDeCode)
   {
     if (!Mt8870_rxd)   CodeReceiveTriggered=0;                                    //消除脉冲干扰
     if (Mt8870Confirmed&!Mt8870_rxd&!Jumped)
                                              { Timer_8870=0; Jumped=1; }          //进入收号保持状态
   }
//Isd2532语音播放部分
     VoiceLength--;     Timer_Voice++;
     Time_delay++;
     TF2=0;
}

一周热门 更多>