xinuaile2003 发表于 2011-9-27 12:22:53

51单片机解码PT2262出现问题

大家好,我的单片机负荷比较重,但必须接收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 <<= 1;                // 装入数据
                        while(!wireless_code_in)                  // 等待高电平
                        {
                                if(TF0)
                                {
                                        break;
                                }
                        }
                        TR0 = 0;
                        if(!TF0)
                        {
                                wirelessRecvTemp |= 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)

kingwaykingway 发表于 2011-9-27 12:55:59

看不懂。。帮顶

517456 发表于 2011-9-27 13:15:44

如果是处理无线信号还是用其它的单片机比较好。

hongruidz 发表于 2011-9-27 13:55:15

PT2262一直有干扰信号输出,不适合用中断来检波,最好是用主程序。51也可以做,如果是检不过来可能是你架构没有搭好哦

xinuaile2003 发表于 2011-9-27 13:56:58

程序量大概有40几K,确实是忙不过来啊。

shi_90 发表于 2011-9-27 13:59:51

如果忙不过来的话!那直接用硬件解码就是了!

NowCan 发表于 2011-9-27 17:03:18

我也很想知道办法。主要是干扰脉冲太多,确实不好处理。

chalcle 发表于 2011-9-28 13:09:21

顶下,为求通过

xinuaile2003 发表于 2011-10-6 11:03:25

就被卡在了无线接收啊。

86793 发表于 2012-7-13 21:24:35

无线软件解码处理很头痛

风雨无阻88 发表于 2015-10-18 16:18:15

我有个汇编的很好用

YAOZHE 发表于 2015-10-18 22:49:44

就是,51挺不好解码的,到现在也有弄好!哪位大侠给个有效的例程

Vmao 发表于 2015-10-19 07:48:02

搞错了,,dd

zheng_wei339 发表于 2015-11-27 22:45:51

用单片机单一软解功能还行,多功能加软解码很不好弄,还是加一个硬解吧,除非你能合理的解决相关中断,干扰及各种功能程序的时序问题

szxszx 发表于 2015-11-27 23:09:47

软解码2262数据要求实时性很高

JZcrystalwlh888 发表于 2015-11-29 11:09:18

楼主还不如用PT2272

baimawangzi 发表于 2015-11-29 11:47:20

PT2262和PT2272本来就是一对儿,为什么要拆散人家?

tonyone 发表于 2015-12-22 22:55:13

风雨无阻88 发表于 2015-10-18 16:18
我有个汇编的很好用

独乐乐不如众乐乐{:lol:}

coleyao 发表于 2015-12-23 08:45:00

//===========================无线接收信号检测================================
//-------------------------外部中断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>>=1;ReITail1=ReIHead2;R1.Re_InBufC>>=1; ReITail2=ReIHead3;
          R1.Re_InBufC>>=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>>=1;ReITail1=ReIHead2;R1.Re_InBufC>>=1; ReITail2=ReIHead3;
             R1.Re_InBufC>>=1;ReITail3=ReIHead4;R1.Re_InBufC>>=1; ReITail4=ReInputB;
             ReInTimer++;
          }            //如果由300uS定时进入,则读入无线接收数据,读入数据计数器加1
       if(Mode_T1==2)
          {if (ReInTimer==25)
               {
               Re_RecOver=1;
               ReInputB=ReITail2;
               R1.Re_InBufC<<=1;ReIHead2=ReITail1;
               R1.Re_InBufC=R1.Re_InBufC;ReITail2=ReInputB; ReInputB=ReITail3;
               R1.Re_InBufC<<=1;ReIHead3=ReITail2;
               R1.Re_InBufC=R1.Re_InBufC;ReITail3=ReInputB;
               R1.Re_InBufC<<=1;ReIHead4=ReITail3;    R1.Re_InBufC=R1.Re_InBufC;
               Re_InBuf1.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)
               { 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.Re_InBufL!=Re_InBuf1.Re_InBufL)&!Re_ReValid) { Re_InBuf1.Re_InBufL=Re_InBuf1.Re_InBufL;    }
   else
      {
      Re_ReValid=1;
      Re_InAddress=Re_InBuf1.Re_InBufL&0xffff;
      Re_InOper=Re_InBuf1.Re_InBufC;
      }
   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;
}

风雨无阻88 发表于 2015-12-25 23:11:36

tonyone 发表于 2015-12-22 22:55
独乐乐不如众乐乐

实际上是BIN反过来的我水平低看不懂
页: [1]
查看完整版本: 51单片机解码PT2262出现问题