rcv_dataproc.c

来自「该程序实现N4F接口程序」· C语言 代码 · 共 922 行 · 第 1/3 页

C
922
字号


#include "..\\inc\\comm.h"
#include "..\\inc\\n4f.h"


extern char       rcvbuf[BUFSIZE], sendbuf[BUFSIZE];
extern int        rcvlen,          sendstep;
extern IO_MB      io_mb[MAX_MODULE_NU];
extern char       scan_type_id;
extern YK_GRP     yk_grp[6];
extern int        soe_flag;
extern SOE_REC    soe_rec;
extern int        ANA_first_flag[MAX_MODULE_NU], SW_first_flag[MAX_MODULE_NU];
extern char       para_grp_num;
extern DB_ID      dbr_id;

int               rtu_scan_flag, max_send_len, imp_grp;
char              prs_data[8],   scan_f[8],   scan_type_id;
INT_STRU          int_stru;    
CMD_PACK          cmd_pack;
float             ff_value;          
int               cmd_option_flag=YES;
long              imp_flag;

void Rcv_data_proc()
{ int  i, j, n;   
  char iomb_addr, w_addr;
  char tmp[100];

  for(i=0;i<8;i++){ prs_data[i]=4; scan_f[i]=3; }

SYS_START_POINT:/* ---------------- RTU装置初始化 ----------------*/
  rtu_scan_flag = YES;   
  max_send_len  = 128;

  
  for(iomb_addr=0;iomb_addr<MAX_MODULE_NU;iomb_addr++)
  { //各模板(板地址)禁止使用
	io_mb[iomb_addr].mb_used               = NO;   
    //模板上各字(字地址)禁止使用
	for(w_addr=0;w_addr<8;w_addr++)
	{ io_mb[iomb_addr].yc[w_addr].scan_allow = NO; 	       
	  io_mb[iomb_addr].yx[w_addr].scan_allow = NO;
      io_mb[iomb_addr].yx[w_addr].soe_flag   = NO;
	}
  }
 
  //遥控组清零
  for(i=0;i<6;i++){ yk_grp[i].config = NO; }
  //SOE记录区清零
  for(i=0;i<MAX_SOE_REC;i++){ soe_rec.soe_buf[i].used = NO; } 

  scan_type_id=0;  //扫描类型缺省值为0
  para_grp_num=1;  //参数组号缺省值为1
  
  if( Read_in()!=OK ){ goto SYS_START_POINT; };	
  
  while( rcvbuf[1]!=TYPE_12H )
  { Send_POWER_ON( scan_type_id );  Read_in(); } 
  printf("PD_COMMAND: 电源合闸确认\n");
  Send_ACK( scan_type_id ); 
  

  
SYS_NORMAL_LOOP:/* ----------------- RTU装置接收网调指令 ----------------- */
  if( Read_in()!=OK ){ goto SYS_NORMAL_LOOP; }
  switch( rcvbuf[1] )
  { 
    case TYPE_01H:    /*  网调复位RTU  */
	  for(i=0;i<MAX_MODULE_NU;i++)
	  { ANA_first_flag[i] = YES; SW_first_flag[i] = YES;} 
      Send_ACK( scan_type_id ); 
	  para_grp_num=1;   
	  printf("\n@@@@@@@@@@@@@@@@@@@@@@@---- RTU RESET-----@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
	  goto SYS_START_POINT;
      break;

    case TYPE_02H:    /* 网调召唤故障模板 */
      Send_ACK( scan_type_id ); 
      break;

    case TYPE_03H:    /* 网调配置RTU模板 */     
	  Cfg_init_iomb();
 	  Send_ACK( scan_type_id );  
      break;

    case TYPE_04H:    /* 网调下达压缩因子, 压缩因子即模拟量不变不送的死区值*/
	  for(i=0;i<8;i++)
	  { prs_data[i]=rcvbuf[3+i]; 
	    printf("PD_COMMAND:  %d号压缩因子 prs_data[%d]=%d \n",i,i,rcvbuf[3+i]);
	  }
	  Send_ACK( scan_type_id ); 
      break;

    case TYPE_05H:    /* 网调通过扫查类别标志召唤数据 */
    case TYPE_1AH:    /* 网调重复通过扫查类别标志召唤数据 */
	  Proc_TYPE_05H_1AH();
      break;
	
	case TYPE_07H:    /* 停止RTU扫描所有模板 */
      rtu_scan_flag=NO;    
      printf("PD_COMMAND: 停止RTU扫描 ! \n");
	  Send_ACK( scan_type_id );
      break;

    case TYPE_08H:    /* 允许RTU扫描所有模板 */
      rtu_scan_flag=YES;   
      printf("PD_COMMAND: 启动RTU扫描 ! \n");
	  Send_ACK( scan_type_id );
  strcpy(tmp,"del "); strcat(tmp,IOMB_CONFIG_VALID);
  printf("%s",tmp); system(tmp);

      
	  break;

    case TYPE_09H:    /* 禁止RTU扫描某模板上指定的字地址 */
	  n = rcvbuf[2]/2;
	  for(i=0;i<n;i++)
      { iomb_addr = rcvbuf[3+i*2+0];
	    if( iomb_addr>=MAX_MODULE_NU )
		{ printf("no this(0x%0x) module address.\n",iomb_addr);
		  Send_NCK( scan_type_id ); goto SYS_NORMAL_LOOP;
		}
		
		if( io_mb[iomb_addr].mb_used==NO ){ continue; }

		for(j=0;j<8;j++)
		{ 
		  if( ( (rcvbuf[3+i*2+1]>>j) & 0x01 )!=0 )
		  { 
			if( io_mb[iomb_addr].mb_type==ANA )  
			{ io_mb[iomb_addr].yc[j].scan_allow = NO; } 
			else
			{ io_mb[iomb_addr].yx[j].scan_allow = NO; } 
		      printf("PD_COMMAND: 停止I/O模块%02d中字地址%d扫描!\n",iomb_addr,j);
		  } 
		}
	  }	
	  Send_ACK( scan_type_id );
      break;

    case TYPE_0AH:    /* 允许RTU扫描某模板上指定的字地址 */
	  n = rcvbuf[2]/2;
	  for(i=0;i<n;i++)
      { iomb_addr = rcvbuf[3+i*2+0];
	    if( iomb_addr>=MAX_MODULE_NU )
		{ printf("no this(0x%0x) module address.\n",iomb_addr);
		  Send_NCK( scan_type_id ); goto SYS_NORMAL_LOOP;
		}	

		if( io_mb[iomb_addr].mb_used==NO ){ continue; }
	 
		for(j=0;j<8;j++)
		{ 
		  if( ( (rcvbuf[3+i*2+1]>>j) & 0x01 )!=0 )
		  { scan_type_id = scan_type_id | ( 0x01<<io_mb[iomb_addr].mb_type_id );
		    io_mb[iomb_addr].mb_w_id = io_mb[iomb_addr].mb_w_id | ( 0x01<<j );
			if( io_mb[iomb_addr].mb_type==ANA )
			{ io_mb[iomb_addr].yc[j].scan_allow = YES; }
		    else
			{ io_mb[iomb_addr].yx[j].scan_allow = YES; }
            printf("PD_COMMAND: 启动I/O模块%02d中字地址%d扫描!\n",iomb_addr,j);
		  }
		} 
	  }	
	  Send_ACK( scan_type_id );
      break;
    
	case TYPE_0BH:    /* 网调通知RTU,需要查询某类别数据 */
	  for(i=0;i<8;i++)
	  { 
		if( ( (rcvbuf[3]>>i) & 0x01 )!=0 )
		{ 
		  for( j=0;j<MAX_MODULE_NU;j++ )
          { 
			if( io_mb[j].mb_used!=YES ){ continue; }
			if( io_mb[j].mb_type_id==i )
			{ 
		      io_mb[j].mb_data_chg = YES; 
              io_mb[j].mb_w_id     = ( char )0xff;
			  scan_type_id = scan_type_id | (0x01<<i);// or scan_type_id=rcvbuf[3];
			}
		  }
		}
	  }
      Send_ACK( scan_type_id );
	  break;
    
    case TYPE_0DH:    /* 网调召唤RTU数据 */     
      Proc_TYPE_0DH(); 	  
	  break;
 
    case TYPE_0EH:    /* 网调发送诊断报文 */   
      printf("PD_COMMAND:  diagose !\n");
	  memset( sendbuf, 0, BUFSIZE ); 
      sendbuf[0] = ( char )RTU_LOCAL_ADDR;
      sendbuf[1] = TYPE_0EH | soe_flag | RAM_OK;
      sendbuf[2] = rcvbuf[2]+1;
      sendbuf[3] = scan_type_id;
      for(i=0;i<rcvbuf[2];i++){ sendbuf[4+i]=rcvbuf[3+i]; } 
      Write_out_crc16( rcvbuf[2]+4 );
	  break;
    
    case TYPE_0FH:     /* 网调向RTU召唤SOE记录 */
	  Proc_TYPE_0FH();
      break;

	case TYPE_10H:    /* 网调设置RTU发送数据包的最大长度 */   
	  max_send_len = rcvbuf[3] & 0xff;  
      printf("PD_COMMAND: 设置数据区最大长度 max_send_len=%d\n",max_send_len);
	  Send_ACK( scan_type_id );
	  break;  

	case TYPE_11H:    /* 网调设置RTU个类别的扫描频率 */
	  for(i=0;i<8;i++)
	  { scan_f[i]=rcvbuf[3+i]; 
	    printf("PD_COMMAND: 类别%d扫描频率 scan_f[%d]=%d \n",i,i,rcvbuf[3+i]);
	  }
	  Send_ACK( scan_type_id ); 
      break;
       
    case TYPE_2DH:    /* 网调指定RTU工作的参数组号 */
      para_grp_num=rcvbuf[3];
	  printf("PD_COMMAND: 设置参数组号 = %d\n",para_grp_num);
      memset( sendbuf, 0, BUFSIZE ); 
      sendbuf[0] = ( char )RTU_LOCAL_ADDR;
      sendbuf[1] = TYPE_2FH | soe_flag | RAM_OK;
      sendbuf[2] = 2;
      sendbuf[3] = scan_type_id;
      sendbuf[4] = para_grp_num;
      Write_out_crc16( 5 );
	  break;
	
	case TYPE_2EH:    /* 网调查询RTU工作的参数组号  */
	  memset( sendbuf, 0, BUFSIZE ); 
      sendbuf[0] = ( char )RTU_LOCAL_ADDR;
      sendbuf[1] = TYPE_2FH | soe_flag | RAM_OK;
      sendbuf[2] = 2;
      sendbuf[3] = scan_type_id;
      sendbuf[4] = para_grp_num;
      Write_out_crc16( 5 );
	  break;
    
	  
	case TYPE_12H:    /* 网调查询RTU电源是否已合闸 */
      printf("PD_COMMAND: 电源合闸确认\n");
	  Send_ACK( scan_type_id );
	  break;

	case TYPE_0CH:    /* 网调向RTU设置时钟 */
      printf("PD_COMMAND: 设置时钟\n");
	  Send_ACK( scan_type_id );
	  break;

    case TYPE_13H:    /* 准备时钟同步  */
      printf("PD_COMMAND: 硬件时钟同步....> ");
      if( rcvbuf[6]==(char)0x01 )
	  { printf("PD_COMMAND: 对时和测延时\n"); } 
	  if( rcvbuf[6]==(char)0x02 )
	  { printf("PD_COMMAND: 对时\n"); soe_rec.syn_time=time(NULL); }
	  Send_ACK( scan_type_id );
	  break;

	
	case TYPE_14H:    /* 时钟同步  */
      printf("PD_COMMAND:  软件时钟同步\n");
      soe_rec.syn_time=time(NULL);
	  Send_ACK( scan_type_id );
	  break;

	case TYPE_19H:    /* 网调发送滤波系数 */                
      printf("PD_COMMAND: 设置滤波系数\n");
	  Send_ACK( scan_type_id );
	  break;

    case TYPE_1EH:    /* 带返送效核遥控  */                
      Proc_TYPE_1EH(); 	  
	  break;
    
	default: 
      Send_NCK( scan_type_id ); printf("invalid type format\n");
	  break;
  }
  goto SYS_NORMAL_LOOP;

}


void Proc_TYPE_05H_1AH() // 类别召唤处理
{ int    i, j, k, n, find_flag=NO;
  char   type_id, word_id, w_addr; 
  short  short_word;
  short  status_bit[8], chg_bit_id[8];
  
  if( rtu_scan_flag==NO )
  { printf("rtu_scan_flag=NO!\n"); Send_NCK( scan_type_id ); return; }      

  if( rcvbuf[1]==TYPE_1AH )
  { rcvbuf[2] = rcvbuf[2] | rcvbuf[3]; }//获得网调要召唤的全部类型

  type_id=rcvbuf[2];

  //当type_id=0时,表示主站询问RTU是否有SOE记录出现
  if( type_id==(char)0x00 ) 
  { 
    if( soe_flag!=SOE_YES ){ Send_ACK( scan_type_id ); return; }  
	for(i=0;i<MAX_MODULE_NU;i++)

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?