找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2107|回复: 1
收起左侧

关于载波环回的处理办法

[复制链接]
ID:82781 发表于 2015-6-13 15:49 | 显示全部楼层 |阅读模式

日照高科园
小ARM菜菜



      这几天被电力载波的环回数据搞得焦头烂额,起因是在一次测试中,发现有一个通道的数据时断时续,开始怀疑是终端控制器程序问题,后来锁定通道板的数据交换问题,随着一天天的测试查找,终于锁定问题的所在,是这样的,三相电每一相上都有一个载波接受的芯片在等待数据,但是,A相数据正常,BC两张的数据不正常,时断时续,正事那个现象!后来发现了问题那就是在A相发送载波的时候莫名其妙的耦合到了BC两相,但是为什么A像正常呢?因为A相启动载波发送后,马上转换成接受在搜索数据同步伪碎码,恰巧此事终端设备的回复来了,所以正好A相对其解码,正常工作而,但是BC就惨了他那里的波形是什么呢?A相出来的序列和终端回复的序列挤在一起,导致了B相直接不知道该怎么办了!这是因为载波的协议决定的,载波没有FIFO,所以。。。。可想而知,没有硬件的支持软件要显得很忙碌!但是此时的软件没有容错处理,他凌乱了!他不知道那里是帧头,因为至少有两个帧头!所以此时的现象时数据时有时无,我今晚对他进行了改进,首先用头的首位作为数据上行和下行的标志,然后在对数据长度进行容错处理,保证在协议允许范围内,如果不符合条件统统过滤并且重要的是重新启动硬件的枕头搜索,这样的结果是成功的滤除了A相的发射干扰保留了终端的回复!哈哈,当然还要测试一段时间!不过那个现象已经没有了!全是我想要 数据!正确的数据!真是!不容易啊!哈哈!加油啊!



回复

使用道具 举报

ID:82781 发表于 2015-6-13 15:49 | 显示全部楼层
此程序成功解决换回问题
奋战好几天几度陷入入僵局!
终于攻破!哈哈,高兴ing
2013年6月8日
小ARM菜菜
很好!
日照高科园
#include<string.h>
#include <PL3201_Addr_Map.h>
#include "pl3201.h"
#include "usart.h"
#include "string.h"
extern void Protocol_analysis (unsigned char *buf,unsigned char len) ;

sbit  PLC_RX=P1^5;
sbit USART_TX=P2^2;
sbit USART_RX=P3^3;


uchar  data    PLC_Rxd_pointer;           
uchar  data    PLC_Rxd_tlen;      
uchar  data    PLC_send_pointer;   
uchar  data    PLC_timer;           
uchar  data    PLC_total_len;      
uchar  data    PLC_Rxd_timer;   

uchar  data    WDI;                 

bit    bdata   PLC_Rxd_state;   
bit    bdata   PLC_Rxd_OK;        
bit    bdata   PLC_sending;         
bit  data    PLC_TX_EN=0;       
uchar    xdata PLC_recv_buf[50];   
uchar  xdata   PLC_Tx_Buf[50];  

  
uchar put_buf=0;
  uint8_t start_rec_data;
uint8_t  rec;

unsigned char nk;

void Check_sys_plc(void)
{
  WDI=0x9a;                  
      
       if(!(PLC_Rxd_timer||PLC_sending))        // no sending and receiving
       {
               PLC_rset();
       }

   
     //  initsys_ref();
}


extern void send_usart_data(char *ptr,char len) ;
uint8_t usart_send_ok=0;
uint8_t plc_ok=0;
void Input_Rx_Process(void)
{
       

//if((PLC_recv_buf[3]==0)&(PLC_recv_buf[4]==0xff))  //回应信号
//{       
        plc_ok=5;

while(plc_ok);
EA=0;       
send_usart_data("B",1);
send_usart_data(PLC_recv_buf,1);
send_usart_data(PLC_recv_buf,PLC_recv_buf[0]);
usart_send_ok=5;
        EA=1;
         
//}
PLC_Rxd_state=0;


}

extern uint8_t usart_rx_ok;

void  timeint0 ( void ) interrupt 1
{


if(usart_rx_ok>0)
{
        usart_rx_ok--;
USART_RX=0;

}
else
{
        USART_RX=1;
}



   if(usart_send_ok>0)
{

USART_TX=0;
usart_send_ok--;
}
else
{

USART_TX=1;

}

if(plc_ok>0)
{

PLC_RX=0;
plc_ok--;

}else
{

   PLC_RX=1;
}



   
   if ( PLC_Rxd_timer>0 )
   {
      PLC_Rxd_timer--;
   }
   else
   {
      PLC_Rxd_timer=0;
      
     PLC_Rxd_state=0;        // resume receive state
   }
   
   if ( PLC_timer>0 )       
           PLC_timer--;

//nk++;
//if(nk==20){nk=0;PLC_TX_EN=1;}


   TH0=0x63;                                // 置定时器计数 100ms 中断一次 ( 4.8MHz )
   TL0=0xcc;

   if ( WDI == 0x9a )
   {
      WDT_RST=0xa1;                 // 清看门狗
      WDI=0;
   }
}
   uint8_t n,len;
  
   
void  PLC_int ( void ) interrupt 7
{
     uchar  data state;              
uchar data SSC_adr_bak;
uchar check;
SSC_adr_bak=SSC_ADR;       
     SSC_ADR=0x00;                           
     state= SSC_DAT;
   if ( ( state&0x01 ) == 1 )              //载波发送状态
   { // 载波发送

   if ( PLC_send_pointer !=PLC_total_len )
     
    {
       SSC_BUF=PLC_Tx_Buf[PLC_send_pointer];                  //发送下一个字节
       PLC_send_pointer++;
    }
    else
    {  //发送完成
      PLC_sending=0;                        // 清正在发送标志
       SSC_ADR=0X0;       
        SSC_DAT=0X0;                 // 发送指示灯灭
    }
  }
  else
{

PLC_Rxd_timer=20;              // 最大字节接收延时时间为1S
    if ( ( state&0x04 ) == 0x04 )     //如果接收的是祯头标志
    {
//帧


      if ( PLC_Rxd_state == 0 )      //如果处于等待接收状态
      {
          //接收第一个字节,并准备接收后面的字节
         PLC_recv_buf[0]=SSC_BUF;
         PLC_Rxd_pointer=0;       
         PLC_Rxd_state=1;
PLC_Rxd_tlen=PLC_recv_buf[0];
check=PLC_recv_buf[0];
if((check&0x80)!=0x80)
{
PLC_Rxd_state=0;
      SSC_ADR=0X0;       
        SSC_DAT=0X0;

}
else
if((check&0x80)==0x80) //1shangxing 0xiaxing
{
  
PLC_Rxd_tlen&=0x7f;
if(PLC_Rxd_tlen>30)
{
  PLC_Rxd_state=0;
      SSC_ADR=0X0;          //^@%$#^%$&%*&(*&)*()(%$#$@#%@#
        SSC_DAT=0X0;
}
}



      }
      else // translate to rec
      {             
      PLC_Rxd_state=0;
      SSC_ADR=0X0;       
        SSC_DAT=0X0;
      }



    }

   //数据流
    else
    {
      if ( PLC_Rxd_state == 1 )       // 如果已经接收了祯头,继续接收后续字节
      {
      
        PLC_recv_buf[PLC_Rxd_pointer]=SSC_BUF;
if(PLC_Rxd_pointer==0)
{       
PLC_recv_buf[0]&=0x7f;        //%$%$#^&%$&^%*%^(&*(*&)&*)^&%^#$
}
        PLC_Rxd_pointer++;
        if ( PLC_Rxd_pointer==PLC_Rxd_tlen )
        {
           PLC_Rxd_OK=1;
           PLC_Rxd_state=0;
           SSC_ADR=0;       
           SSC_DAT=0;
        }
      }
      else       
      {
      PLC_Rxd_state=0;
      SSC_ADR=0X0;       
        SSC_DAT=0X0;
      }
    }
         
  }
  
SSC_ADR=SSC_adr_bak;
}
/*void set_PLC_3200 ( void )
{
SSC_ADR=0XFF;        
SSC_DAT=0XFF;        // 禁止写保护

        SSC_ADR=0x01;        // 选择3201载波通讯控制寄存器1       
        SSC_DAT=40;        // ZZZ 2007-10-15 前导1bit为40个

SSC_ADR=0x03;        // 选择3201载波通讯控制寄存器3       
SSC_DAT=0xc0;        // 开启载波通讯功能,打开中断,选择接收状态置为3200模式

SSC_ADR=0x04;        // 设置捕获门限
SSC_DAT=LIMIT_3200;

SSC_ADR=0XFF;
SSC_DAT=0XAA;        // 使能写保护  
}  */
void set_PLC_3105 ( void )
{
SSC_ADR=0XFF;        // 2005.11.29 LXW
  SSC_DAT=0XFF;        // 禁止写保护
       
        SSC_ADR=0x01;        // 选择3105载波通讯控制寄存器1       
        SSC_DAT=64;        // ZZZ 2007-10-15 前导1bit为64个

        SSC_ADR=0x03;        // 选择3201载波通讯控制寄存器3       
        SSC_DAT=0xe0;        // 开启载波通讯功能,打开中断,选择接收状态置为3105模式
         
        SSC_ADR=0x04;        // 设置捕获门限
  SSC_DAT=LIMIT_3105;
  
  SSC_ADR=0XFF;
  SSC_DAT=0XAA;        // 使能写保护  
}
void initsys ( void )
{  // 控制看门狗喂狗时间长度                         
  CKCON=0xfF;
  // 8位/16位运算模式选择位设置
  ALU_MOD=0;      // 设置成8位运算模式
  //载波通讯配置
//************   3201的载波寄存器设置  **********//
  set_PLC_3105 ( );        //上电为3105模式
  
  SSC_ADR=0xFF;
  SSC_DAT=0xFF;
  SSC_ADR=0x02;
  SSC_DAT=0x1F;
  SSC_ADR=0xFF;
  SSC_DAT=0x00;
  
//************   3201的载波寄存器设置  **********//
  EIE=0X01;       //  ( A9H 使能INT2中断(EX2=1)
  IT2=1;                  //  ( C8H ) 为边沿触发方式(IT2=1)
  
//串口通讯配置
  TMOD1 = 0x10 ;                     // 设 T/C1 为1分频模式,ZZZ
  TMOD = 0x21 ;                     // 设 T/C1 为定时方式2 设置为8位自装载计数器  T/C0 为定时方式 1
  SCON=0x50;                           // 工作方式1
  
  PCON=0x80;                           // 波特率加倍
  TH1=BPS2400;
  TL1=BPS2400;                        // 加倍设定波特率 9.6MHz ( 按1分频2400计算)
  TR1=1;                               // 启动定时器1
   



  // 定时器0中断配置
  TH0=0x63;
  TL0=0xcc;   // 定时 50 ms 一个定时中断
  TR0 = 1;               // 启动 T0 定时器
  // 中断级别设置
  IP=0x42;                      // 定时器 T0 中断为高级中断
  EIP=1;                 // 外部中断2 为高级中断
  // 中断允许设置
  IE=0x82;

  ES=1;

  EA=1;


                      // 允许ET0=1定时器 T0 中断;  开放中断
  }


void initsys_ref( void )
{  // 载波设置重置
   uchar  data s1;
   uchar  data GOLD_KSAMI;

   if ( EIE!=1 )
      EIE=0X01;       //  ( A9H 使能INT2中断(EX2=1)
   if ( IT2!=1 )       
      IT2=1;                 //  ( C8H ) 为边沿触发方式(IT2=1)

   SSC_ADR=0x02;
   GOLD_KSAMI=SSC_DAT;
   if ( GOLD_KSAMI!=0x1F )
   {
      SSC_ADR=0xFF;
      SSC_DAT=0xFF;
      SSC_ADR=0x02;
      SSC_DAT=0x1F;
      SSC_ADR=0xFF;
      SSC_DAT=0x00;
   }

   // 串口设置重置
   if ( TMOD1!=0x10 )        //2007-10-15 ZZZ
      TMOD1 = 0x10 ;   //1分频模式
   if ( TMOD!=0x21 )
      TMOD = 0x21 ;   // 设 T/C1 为定时方式2 设置为8位自装载计数器  T/C0 为定时方式 14
   if ( PCON!=0x80 )
      PCON=0X80;      // 波特率加倍

   s1=SCON;
   s1=s1&0xf0;
   if ( s1!=0x50 )
     initsys ();

   if ( TH1!=BPS2400 )
      TH1=BPS2400;
   if ( TR1!=1 )
      TR1=1;          // 启动定时器1
      // 定时器0重置


  /*嘻嘻,*/
/*                
  TMOD1=0x32; //time2方式2
  SCON1=0x50; //
  TH2=OMG;
  TL2=OMG;
  TR2 =1;
*/
  
   if ( TR0!=1 )
     TR0 = 1;        // 启动 T0 定时器

   // 中断设置重置
   if ( IE!=0x82 )
      IE=0x82;
   if ( IP!=2 )
      IP=2;
   if ( EIP!=1 )
      EIP=1;         // 外部中断2 为高级中断


ES=1;
}


void PLC_rset(void)
{
  uchar s1;

/*if( function_now == 0 )         
        {
           // MEAN 3200 FUNCTION
SSC_ADR=0x03;
s1=SSC_DAT;
if ( ( s1&0xf0 )!=0xc0 )
set_PLC_3200 ();
} */
//else if ( function_now == 0xff )        //3105
   //{
SSC_ADR=0x03;
s1=SSC_DAT;
if ( ( s1&0xf0 )!=0xe0 )
set_PLC_3105 ();
  // }
}
  void init_PLC3201(void)
  {
  
  uchar data i;
   uchar data j;

   for ( i=0; i<5; i++ )        //wait for the stabilization of power
   {
      for ( j=0; j<0xff; j++ );
   }  

   for ( i=0; i<5; i++ )
   {
      for ( j=0; j<0xff; j++ );
   }         
   
   PLC_Rxd_OK=0;
   PLC_sending=0;
//   PLC_Rxd_state=0;
    PLC_Rxd_timer=0x00;

  
  
  }
uint8_t Send_PLC_Data( const uint8_t *Src,uint8_t len)
{

memcpy (PLC_Tx_Buf ,Src, len);
   PLC_total_len=len ;
         PLC_send_pointer=0;                                           
         PLC_sending=1;                   
         SSC_ADR=0x03;
        SSC_DAT= ( SSC_DAT|0x01 );
SSC_BUF= PLC_Tx_Buf[PLC_send_pointer];  
         PLC_timer=30;         // 载波发送过程延时控制1.5秒


while (PLC_sending)
  {
  
  if( 0==PLC_timer) return 0;//超时

  }
    if ( PLC_timer == 0 )        // PLC sending finish
  {
  SSC_ADR=0x03;
  SSC_DAT= (SSC_DAT&0xFE);       // 设置3201为REC状态REDUNDANCY
  PLC_sending=0;

  }
return 1;//成功




}
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表