rcv_dataproc.c

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

C
922
字号
	 Float_to_int( &int_stru );     //将遥调浮点值转换成H9000格式
	 
	 cmd_pack.h9000_status=0x0000;
	 if( int_stru.sign==DATA_NEGATIVE )
	 { cmd_pack.h9000_status = cmd_pack.h9000_status | 0x0080; }
     cmd_pack.h9000_status  = cmd_pack.h9000_status | ( int_stru.format << 5 );    
	 cmd_pack.h9000_value   = int_stru.value;
     cmd_pack.pd_FLvalue    = io_mb[iomb_addr_SET].yc[w_addr_SET].yc_pid[0].f_value;
     cmd_pack.pd_ADvalue    = io_mb[iomb_addr_SET].yc[w_addr_SET].yc_pid[0].AD_value ;
     strcpy( cmd_pack.cmd_name, io_mb[iomb_addr_SET].yc[w_addr_SET].yc_pid[0].c_name ); 

     printf("PD_CMD:(%02d_%d) %s %s %d %7.2f (h9000: %d 0x%x)\n",
			       iomb_addr_SET, w_addr_SET, 
		           io_mb[iomb_addr_SET].yc[w_addr_SET].yc_pid[0].c_name,
				   io_mb[iomb_addr_SET].yc[w_addr_SET].yc_pid[0].l_name,
				   io_mb[iomb_addr_SET].yc[w_addr_SET].yc_pid[0].AD_value, 
				   io_mb[iomb_addr_SET].yc[w_addr_SET].yc_pid[0].f_value,
				   cmd_pack.h9000_value, cmd_pack.h9000_status                );	    
     
	 printf("!!!!!!!!执行省调命令: %s value=%d status=0x%x\n",
	            cmd_pack.cmd_name, cmd_pack.h9000_value, cmd_pack.h9000_status );
     
	 //广播网调的人工遥调命令
	 DBread_id( io_mb[iomb_addr_SET].yc[w_addr_SET].yc_pid[0].l_name );
     Brd_YT( dbr_id.dev_id,         dbr_id.data_type,     dbr_id.point_id, 
		     cmd_pack.h9000_value,  cmd_pack.h9000_status                  );
     //发送调功命令( 直接对发电机发调功令 )
	 //P_adj_cmd( dbr_id.dev_id,         dbr_id.data_type,     dbr_id.point_id, 
	 //	     cmd_pack.h9000_value,  cmd_pack.h9000_status                  );

	 Cmd_record( io_mb[iomb_addr_SET].yc[w_addr_SET].yc_pid[0].c_name,
		         io_mb[iomb_addr_SET].yc[w_addr_SET].yc_pid[0].l_name,
				 (int)io_mb[iomb_addr_SET].yc[w_addr_SET].yc_pid[0].f_value );

	 break;
  
   case YK_TYPE://模板类型为遥控板   
     //setp_1: 主站以“0D”报文发出反码命令
     iomb_addr_SET   = rcvbuf[3] & 0x1f;        
	 word_id_SET     = rcvbuf[4];
	 for(i=0;i<8;i++){ if( (word_id_SET >> i) != 1 )continue; else break; }
  	 w_addr_SET = i;

	 tmp[0]=rcvbuf[5];  tmp[1]=rcvbuf[6];   
     io_mb[iomb_addr_SET].yc[w_addr_SET].yc_pid[0].fan_code
	     =( *((short *)tmp) );//得到遥控命令反码
     io_mb[iomb_addr_SET].yc[w_addr_SET].yc_pid[0].AD_value 
	     =(~(io_mb[iomb_addr_SET].yc[w_addr_SET].yc_pid[0].fan_code)) ;     
    
	 Send_ACK( scan_type_id );

     //step_2: 主站以“0D”召唤RTU的返送校核码
	 if( Read_in()!=OK ){ return; }
	 if( rcvbuf[1]!=(char)0x0D ){ printf("@@@@@ 0D shoud be receive!\n"); return; }
	 iomb_addr_RET   = rcvbuf[3] & 0x1f;        
	 word_id_RET     = rcvbuf[4];
	 for(i=0;i<8;i++){ if( (word_id_RET >> i) != 1 )continue; else break; }
	 w_addr_RET = i;

     io_mb[iomb_addr_RET].yc[w_addr_RET].yc_pid[0].AD_value 
	     = io_mb[iomb_addr_SET].yc[w_addr_SET].yc_pid[0].AD_value;  //把遥控命令码写到返送区
	 
     Proc_TYPE_1CH( iomb_addr_RET, word_id_RET, 0x0d );//RTU以“1C”报文,用正码回答主站     

	 //step_3: 主站以“0D”报文发出正码,执行命令
	 if( Read_in()!=OK ){ return; }
	 if( rcvbuf[1]!=(char)0x0D ){ printf("@@@@@ 0D shoud be receive!\n"); return; }
	 iomb_addr_SET   = rcvbuf[3] & 0x1f;        
	 word_id_SET     = rcvbuf[4];
	 for(i=0;i<8;i++){ if( (word_id_SET >> i) != 1 )continue; else break; }
	 w_addr_SET = i;
     
     tmp[0]=rcvbuf[5];  tmp[1]=rcvbuf[6];        
     io_mb[iomb_addr_SET].yc[w_addr_SET].yc_pid[0].AD_value
	     =( *((short *)tmp) ) ; 
	 
     if(   io_mb[iomb_addr_SET].yc[w_addr_SET].yc_pid[0].AD_value 
         !=io_mb[iomb_addr_RET].yc[w_addr_RET].yc_pid[0].AD_value  )
     { Send_NCK( scan_type_id );  printf("反送校核错\n"); return; }
	 else 
     { Send_ACK( scan_type_id ); }//RTU发出确认报文    以上参见补充协议71页

	 grp_addr_id = (io_mb[iomb_addr_SET].yc[w_addr_SET].yc_pid[0].AD_value >> 10 ) & 0x003f;//取控制组ID
	 ctrl_pnt_id = (io_mb[iomb_addr_SET].yc[w_addr_SET].yc_pid[0].AD_value >> 2 )  & 0x00ff;//取控制点ID
	 opr_id      =  io_mb[iomb_addr_SET].yc[w_addr_SET].yc_pid[0].AD_value & 0x003;//取操作内容

     for(i=0;i<6;i++){ if( (grp_addr_id >> i) != 1 )continue; else break; }
  	 grp_addr = i;//取控制组号

     for(i=0;i<8;i++)
	 { if( (ctrl_pnt_id >> i) != 1 )continue; 
	   
	   if( opr_id==(char)0x02 ){ cmd_pack.h9000_status=0x0000; }
	   else
       if( opr_id==(char)0x01 ){ cmd_pack.h9000_status=0x0004; }
	   else
       { cmd_pack.h9000_status=0x0003; }

       printf("PD_CMD:(Group=%d_%d) %s %s (h9000: 0x%x)\n",
				   grp_addr, i, 
		           yk_grp[grp_addr].ctrl_pnt[i].c_name,
                   yk_grp[grp_addr].ctrl_pnt[i].l_name,
				   cmd_pack.h9000_status                        );	 
	   printf("!!!!!!!!执行省调命令: %s status=0x%x  opr_id=%0x\n",
	            cmd_pack.cmd_name, cmd_pack.h9000_status, opr_id     );
         
	   //广播网调的遥控命令
	   DBread_id( yk_grp[grp_addr].ctrl_pnt[i].l_name );
       Brd_YK( dbr_id.dev_id, dbr_id.data_type, dbr_id.point_id, cmd_pack.h9000_status );		        
     }	 
	 break;
   
     default:
       printf("\nProc_TYPE_0D(): 模板%d没定义\n",iomb_addr_SET);		          
	   Send_ACK( scan_type_id );
       break;
  }
 
}


/* ----------- 向主站回答电度数 ----------- */
void Proc_TYPE_1CH_imp( char iomb_addr1, char iomb_addr2, char word_id1, char word_id2 )
{ 
  int        i;
  long int   long_word;
  printf("------- addr1=%d addr2=%d  w_id1=%d  w_id2=%d\n",iomb_addr1,iomb_addr2,word_id1,word_id2);
  memset( sendbuf, 0, BUFSIZE ); 
  sendbuf[0] = ( char )RTU_LOCAL_ADDR;
  sendbuf[1] = 0x1C; sendbuf[1] = sendbuf[1] | RAM_OK | soe_flag;
  sendbuf[3] = 0x00;
  sendstep   = 4;

  for( i=0;i<8;i++ ) 
  { if( ( (word_id1>>i) & 0x01 )==0 )continue; 
    if( io_mb[iomb_addr1].yc[i].scan_allow != YES )continue;
    
    long_word = io_mb[iomb_addr1].yc[i].yc_pid[0].l_value;
    long_word = ( long_word & 0x00ffffff ) | IMP_GRP_A | IMP_FREEZE;
	Bufs_merge( sendstep, (char *)&long_word, 4 ); sendstep=sendstep+4;//A组脉冲数
  }

  for( i=0;i<8;i++ ) 
  { if( ( (word_id2>>i) & 0x01 )==0 )continue; 
    if( io_mb[iomb_addr2].yc[i].scan_allow != YES )continue;
    
    long_word = io_mb[iomb_addr2].yc[i].yc_pid[0].l_value;
    long_word = ( long_word & 0x00ffffff ) | IMP_GRP_B | IMP_FREEZE;
    Bufs_merge( sendstep, (char *)&long_word, 4 ); sendstep=sendstep+4;//B组脉冲数
  }
  sendbuf[2] = sendstep-3;
  Write_out_crc16( sendstep );    
}

void Proc_TYPE_1CH( char iomb_addr, char word_id, char answer_for ) 
{ int   i;
  short short_word;
  int   long_word;
  

  memset( sendbuf, 0, BUFSIZE ); 
  sendbuf[0] = ( char )RTU_LOCAL_ADDR;
  sendbuf[1] = 0x1C; sendbuf[1] = sendbuf[1] | RAM_OK | soe_flag;
  sendbuf[3] = 0x00;
  sendstep   = 4;

  if( answer_for==(char)0x0f )//回答“0F”报文. 即上送SOE记录
  { Bufs_merge( sendstep, (char *)&(soe_rec.syn_time),  4 ); sendstep=sendstep+4;//同步时间
    //-----1
    for(i=0;i<MAX_SOE_REC;i++)
	{ if( soe_rec.soe_buf[i].used!=YES ) continue;
	  if( soe_rec.soe_buf[i].iomb_addr!=iomb_addr ) continue;
      
	  soe_rec.soe_buf[i].used = NO;		
      Bufs_merge( sendstep, (char *)&(soe_rec.soe_buf[i].status_id),1 ); sendstep=sendstep+1;
	  Bufs_merge( sendstep, (char *)&(soe_rec.soe_buf[i].status),   1 ); sendstep=sendstep+1;
      long_word=soe_rec.soe_buf[i].time_val & 0x0fffffff;//相对时间,28位
	  long_word=long_word | ( soe_rec.soe_buf[i].location << 28 );//填写高、低字节标志
      long_word=long_word | ( soe_rec.soe_buf[i].word_addr << 29 );//填写字地址
      Bufs_merge( sendstep, (char *)&long_word, 4 );                     sendstep=sendstep+4;
	  break;//以上参见规约第16页,时标数据
	}
	if( i>=MAX_SOE_REC )//全部SOE记录送完后, 加加送一空记录
    { short_word = 0x0000;   
      Bufs_merge( sendstep, (char *)&short_word, 2 );         sendstep=sendstep+2;
      long_word  = 0x00000000;
      Bufs_merge( sendstep, (char *)&long_word, 4 );          sendstep=sendstep+4;
	}
    //-----2
    for(i=0;i<MAX_SOE_REC;i++)
	{ if( soe_rec.soe_buf[i].used!=YES ) continue;
	  if( soe_rec.soe_buf[i].iomb_addr!=iomb_addr ) continue;
	  
	  soe_rec.soe_buf[i].used = NO;		
      Bufs_merge( sendstep, (char *)&(soe_rec.soe_buf[i].status_id),1 ); sendstep=sendstep+1;
      Bufs_merge( sendstep, (char *)&(soe_rec.soe_buf[i].status),   1 ); sendstep=sendstep+1;
      long_word=soe_rec.soe_buf[i].time_val & 0x0fffffff;
	  long_word=long_word | ( soe_rec.soe_buf[i].location << 28 );
      long_word=long_word | ( soe_rec.soe_buf[i].word_addr << 29 );
      Bufs_merge( sendstep, (char *)&long_word, 4 );                     sendstep=sendstep+4;
	  break;
	}
	if( i>=MAX_SOE_REC )
    { short_word = 0x0000;   
      Bufs_merge( sendstep, (char *)&short_word, 2 );         sendstep=sendstep+2;
      long_word  = 0x00000000;
      Bufs_merge( sendstep, (char *)&long_word, 4 );          sendstep=sendstep+4;
	}

    sendbuf[2] = sendstep-3;
    Write_out_crc16( sendstep );
    return;
  }
  
  if( answer_for==(char)0x0d )//回答“0D”报文
  { io_mb[iomb_addr].mb_data_chg= NO;
    switch( io_mb[iomb_addr].def_type )
	{ case YX_TYPE:
        for( i=0;i<8;i++ )
		{ if( ( (word_id>>i) & 0x01 )==0 )continue; 
	      short_word = io_mb[iomb_addr].yx[i].status_bit;
	      Bufs_merge( sendstep, (char *)&short_word, 2 ); sendstep=sendstep+2;
		}
	    sendbuf[2] = sendstep-3;
        Write_out_crc16( sendstep );
        break;
	  
      case YK_TYPE:
        for( i=0;i<8;i++ )
		{ if( ( (word_id>>i) & 0x01 )==0 )continue; 
	      short_word = io_mb[iomb_addr].yc[i].yc_pid[0].AD_value;
		  Bufs_merge( sendstep, (char *)&short_word, 2 ); sendstep=sendstep+2;
		}
	    sendbuf[2] = sendstep-3;
        Write_out_crc16( sendstep );
		  break;

	  case YC_TYPE:
	    for( i=0;i<8;i++ )
		{ if( ( (word_id>>i) & 0x01 )==0 )continue; 
	      short_word = io_mb[iomb_addr].yc[i].yc_pid[0].AD_value & 0x0fff;
		  if( io_mb[iomb_addr].yc[i].yc_pid[0].AD_signe==(char)NEGATIVE )
          { short_word = short_word | 0x1000; }
	      Bufs_merge( sendstep, (char *)&short_word, 2 ); sendstep=sendstep+2;
		}
	    sendbuf[2] = sendstep-3;
        Write_out_crc16( sendstep );
	    break;          
      case YT_TYPE:
        for( i=0;i<8;i++ )
		{ if( ( (word_id>>i) & 0x01 )==0 )continue; 
	      short_word= io_mb[iomb_addr].yc[i].yc_pid[0].AD_value;
	      Bufs_merge( sendstep, (char *)&short_word, 2 ); sendstep=sendstep+2;
		}
	    sendbuf[2] = sendstep-3;
        Write_out_crc16( sendstep );
        break;
	  case BCD_TYPE:
        for( i=0;i<8;i=i+2 ) // BCD CARD config 0 ,2 , 4 ,6 only
		{ if( ( (word_id>>i) & 0x01 )==0 )continue; 
		  if( io_mb[iomb_addr].yc[i].scan_allow != YES )continue;
	      long_word = io_mb[iomb_addr].yc[i].yc_pid[0].l_value;
	      long_word = long_word & 0x0fffffff;
		  Bufs_merge( sendstep, (char *)&long_word, 4 ); sendstep=sendstep+4;
		}
	    sendbuf[2] = sendstep-3;
        Write_out_crc16( sendstep );
        break;
      
	}
  }
  return;
}


void Proc_TYPE_1EH()
{ char   iomb_addr_SET, iomb_addr_RET, word_id, w_addr;
  char   tmp[8];
  short  short_word;

  iomb_addr_SET = (rcvbuf[3+0]>>3) & 0x1f; 
  word_id       = 2;
  w_addr        = 1;
  tmp[0]    =rcvbuf[3+2];  
  tmp[1]    =rcvbuf[3+3];
  short_word= ~( *((short *)tmp) );

  iomb_addr_RET = rcvbuf[3+0] & 0x1f;
  io_mb[iomb_addr_RET].yx[4].status_bit=short_word;
  Proc_TYPE_1CH( iomb_addr_RET, word_id, 0x1e ); 
  return;
}


void Proc_TYPE_0FH()
{ char   iomb_addr,  word_id;
  int    addr;
  
  addr = rcvbuf[3] & 0x1f;
  if( ( addr % 2 )==1 ){ iomb_addr=addr-1; }else{ iomb_addr=addr; }
  word_id = rcvbuf[4];
  word_id = (char)0xff;  
  Proc_TYPE_1CH( iomb_addr, word_id, 0x0f );     
  return;
}

⌨️ 快捷键说明

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