rcv_dataproc.c

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

C
922
字号
	{ if( (io_mb[i].mb_used!=YES)||(io_mb[i].def_type!=YX_TYPE) )continue;
	  for(j=0;j<8;j++)
	  { 
	    if( io_mb[i].yx[j].soe_flag==YES )
		{ 
		  for(k=0;k<8;k++){io_mb[i].yx[k].soe_flag=NO; }
		  soe_flag=SOE_NO;
		  sendstep=0;
	      memset( sendbuf, 0, BUFSIZE ); 
	      sendbuf[0] = ( char )RTU_LOCAL_ADDR;
	      sendbuf[1] = 0x17; sendbuf[1] = sendbuf[1] | RAM_OK ;
	      sendbuf[2] = 2;
		  sendbuf[3] = 0x00;
		  sendbuf[4] = 0x00 | (i << 3);
          sendstep   = 5;
		  Write_out_crc16( sendstep ); //若有SOE记录出现,以17H报文回答主站
		  return;
		}
      }
    }
	if(i>=MAX_MODULE_NU)
    { soe_flag = SOE_NO; Send_ACK( scan_type_id ); }  
    else
	{ return; }
  }
  
  //当type_id!=0时,表示主站询问RTU是否有其他扫描类型的数据发生变化
  if( type_id!=(char)0x00 )
  { 
	sendstep=0;
  
	memset( sendbuf, 0, BUFSIZE ); 
	sendbuf[0] = ( char )RTU_LOCAL_ADDR;
	sendbuf[1] = 0x1B; sendbuf[1] = sendbuf[1] | RAM_OK | soe_flag;
	sendbuf[3] = 0x00;
    sendstep   = 4+sendstep;
	for(i=0;i<8;i++)
    { 
      if( ( (type_id>>i) & 0x01 )==0 )continue;
      scan_type_id = scan_type_id & ( ~( 0x01 << i ) );//计算得到扫描类型id
      
	  for(n=0;n<MAX_MODULE_NU;n++) 
      { //查找符合扫描类型id的模板
        if( (io_mb[n].mb_used!=YES)||(io_mb[n].mb_data_chg!=YES)||(io_mb[n].mb_type_id!=i) )
		{ continue; }    
		
		word_id = io_mb[n].mb_w_id; //保存模板n的字标志  
        for(j=0;j<8;j++)            //保存模板n中,字地址的状态位标志和状态变化位标志
		{  status_bit[j]=io_mb[n].yx[j].status_bit;  io_mb[n].yx[j].status_bit=0x0000;
		   chg_bit_id[j]=io_mb[n].yx[j].chg_bit_id;  io_mb[n].yx[j].chg_bit_id=0x0000;
		}
		
		io_mb[i].mb_data_chg = NO;  
                    	
		switch( io_mb[n].mb_type )
		{ case SW:
		  case TIME_SW:
		    sendbuf[sendstep] = (0x00 | n) | (SW << 5);       sendstep=sendstep+1;
			sendbuf[sendstep] = io_mb[n].mb_w_id;             sendstep=sendstep+1;
			for( j=0;j<8;j++ )
			{ if( ( (word_id>>j) & 0x01 )==0 )continue; //计算得到模板n中有变化的字地址 
			  w_addr = j;
			  if( io_mb[n].yx[w_addr].scan_allow == NO )continue;
			  
			  find_flag = YES;//参见规约第16页,开关量格式
			  short_word= status_bit[j];
			  Bufs_merge( sendstep, (char *)&short_word, 2 ); sendstep=sendstep+2;
           	  short_word = chg_bit_id[j];
         	  Bufs_merge( sendstep, (char *)&short_word, 2 ); sendstep=sendstep+2;
			}
			io_mb[n].mb_w_id    =0x00; //模板字标志各bit置0
            io_mb[n].mb_data_chg=NO;
	        break;
		  case ANA:
		    sendbuf[sendstep] = (0x00 | n) | (ANA << 5);      sendstep=sendstep+1;
			sendbuf[sendstep] = io_mb[n].mb_w_id;             sendstep=sendstep+1;
			for( j=0;j<8;j++ )
			{ if( ( (word_id>>j) & 0x01 )==0 )continue; //计算得到模板n中有变化的字地址 
              w_addr = j;
			  if( io_mb[n].yc[w_addr].scan_allow == NO )continue;

			  find_flag = YES;
			  short_word= io_mb[n].yc[j].yc_pid[0].AD_value & 0x0fff;
			  if( io_mb[n].yc[j].yc_pid[0].AD_signe==(char)NEGATIVE )
              { short_word = short_word | 0x1000; } //以上参见规约第16页,模拟量格式
			  Bufs_merge( sendstep, (char *)&short_word, 2 ); sendstep=sendstep+2;
           	}
		    io_mb[n].mb_w_id    =0x00; //模板字标志各bit置0
            io_mb[n].mb_data_chg=NO;
			break;          
		  case BCD:
            
            break;
		}
      }
    }
	sendbuf[2] = sendstep-3;
	
    if( find_flag==YES )
	{ Write_out_crc16( sendstep ); }
	else
	{ Send_ACK( scan_type_id );    }    
    return;
  } 
}


/* -------- 网调遥控、遥调会话 -------- */
void Proc_TYPE_0DH() 
{ char   iomb_addr_SET, word_id_SET, w_addr_SET, grp_addr_id, grp_addr, 
         iomb_addr_RET, word_id_RET, w_addr_RET, ctrl_pnt_id, opr_id; 
  char   tmp[8];
  short  short_word1, short_word2;
  float  y, z, data_up, data_low, mea_up, mea_low, mea_zero;
  int    i;

  iomb_addr_SET = rcvbuf[3] & 0x1f; //获得模板地址
  
  switch( io_mb[iomb_addr_SET].def_type ) 
  {    
    case IMP_TYPE://模板类型为脉冲计数板    	 
	 tmp[0]=rcvbuf[5]; tmp[1]=rcvbuf[6];  short_word1=( *((short *)tmp) );//取得电度量控制命令	 
	 if( short_word1==(short)IMP_B_FREEZE )
	 { imp_flag=IMP_FREEZE;
	   Send_ACK( scan_type_id ); printf("@@@@@@@@@@ 省调电度_冻结_命令 @@@@@@@@@\n"); 
	   break;
	 }
     if( short_word1==(short)IMP_B_FREE   )
	 { imp_flag=0x00000000;
	   Send_ACK( scan_type_id ); printf("@@@@@@@@@@ 省调电度_解冻_命令 @@@@@@@@@\n"); 
	   break;
	 }
     
	 
     tmp[0]=rcvbuf[5];  tmp[1]=rcvbuf[6];   short_word1=( *((short *)tmp) );	 
     tmp[0]=rcvbuf[13]; tmp[1]=rcvbuf[14];  short_word2=( *((short *)tmp) );	 
     iomb_addr_SET = rcvbuf[7]  & 0x1f; 
	 word_id_SET = rcvbuf[8];
     //iomb_addr_RET = rcvbuf[15] & 0x1f; 
	 word_id_RET = rcvbuf[16];
	 
	 if( (short_word1==IMP_READ_A)&&(short_word2==IMP_READ_B) )//读A组电度数,和B组电度数
     { Proc_TYPE_1CH_imp( iomb_addr_SET, iomb_addr_SET+1, word_id_SET, word_id_RET  ); 
	   break; 
	 }


	case BCD_TYPE://模板类型为BCD板   
     iomb_addr_RET   = rcvbuf[3] & 0x1f;        
	 word_id_RET     = rcvbuf[4];
	 for(i=0;i<8;i=i++){ if( (word_id_RET >> i) != 1 )continue; else break; }
	 w_addr_RET = i;  
     Proc_TYPE_1CH( iomb_addr_RET, word_id_RET, 0x0d );   
	 break;
	  
	case YT_TYPE://模板类型为遥调板   
     //++++++++++++++ 网调主站自动下达遥调命令
     if( rcvbuf[2]==8 ) 
     { 
	   iomb_addr_SET   = rcvbuf[3] & 0x1f;//取模板地址      
	   word_id_SET     = rcvbuf[4];//取字地址ID     
	   for(i=0;i<8;i++){ if( (word_id_SET >> i) != 1 )continue; else break; }
	   w_addr_SET = i;//取字地址
       iomb_addr_RET   = rcvbuf[7] & 0x1f;//取返校模板地址 
	   word_id_RET     = rcvbuf[8];//取返校字地址ID  
	   for(i=0;i<8;i++){ if( (word_id_RET >> i) != 1 )continue; else break; }
	   w_addr_RET = 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) ) & 0x0fff;//取遥调值反码
       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)) & 0x0fff;

       tmp[0]=rcvbuf[9];  tmp[1]=rcvbuf[10]; 
       
	   io_mb[iomb_addr_RET].yc[w_addr_RET].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  )
       {  // 遥调值反码与正码匹配
	     if( ((~(io_mb[iomb_addr_SET].yc[w_addr_SET].yc_pid[0].fan_code)) & 0x1000)==0x1000 )
		 { io_mb[iomb_addr_SET].yc[w_addr_SET].yc_pid[0].AD_signe = (char)NEGATIVE; }
	     else
		 { io_mb[iomb_addr_SET].yc[w_addr_SET].yc_pid[0].AD_signe = (char)POSITIVE; }
	 
         data_up  = (float)io_mb[iomb_addr_SET].yc[w_addr_SET].yc_pid[0].data_up;
         data_low = (float)io_mb[iomb_addr_SET].yc[w_addr_SET].yc_pid[0].data_low;
         mea_up   = (float)io_mb[iomb_addr_SET].yc[w_addr_SET].yc_pid[0].mea_up;
         mea_low  = (float)io_mb[iomb_addr_SET].yc[w_addr_SET].yc_pid[0].mea_low;
         mea_zero = (float)io_mb[iomb_addr_SET].yc[w_addr_SET].yc_pid[0].mea_zero;
         y = data_up - data_low;
         z = mea_up - mea_low;
       /*  if( io_mb[iomb_addr_SET].yc[w_addr_SET].yc_pid[0].AD_signe==(char)NEGATIVE )
		 { 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].AD_value * (-1);
		 }*/
	     io_mb[iomb_addr_SET].yc[w_addr_SET].yc_pid[0].f_value
  	           = io_mb[iomb_addr_SET].yc[w_addr_SET].yc_pid[0].AD_value*(y/z)-mea_zero;//计算遥调浮点值	
	 	 
         ff_value=io_mb[iomb_addr_SET].yc[w_addr_SET].yc_pid[0].f_value;
	     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                );
		 
		 Send_ACK( 0x00 ); 
         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 );		 	   
	   }  
	   else
       {
         Send_NCK( scan_type_id ); 
       }
	   return;
     }

  
     //++++++++++++++ 网调主站人工下达遥调命令 ++++++++++++++++++//
	 //setp_1: 主站以“0D”报文发出反码命令
	 iomb_addr_SET   = rcvbuf[3] & 0x1f; //取模板地址        
	 word_id_SET     = rcvbuf[4];//取字地址ID 
	 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) ) & 0x0fff;//取遥调值反码
     
     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)) & 0x0fff;     
     
	 Send_ACK( 0x00 ); //RTU发出确认报文

	 //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;
     
     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) ) & 0x0fff;
     
	 if( w_addr_SET==2 ){ w_addr_RET=1; }
	 if( w_addr_SET==6 ){ w_addr_RET=5; }
	 
     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发出确认报文    以上参见补充协议76页

     
	 data_up  = (float)io_mb[iomb_addr_SET].yc[w_addr_SET].yc_pid[0].data_up;
     data_low = (float)io_mb[iomb_addr_SET].yc[w_addr_SET].yc_pid[0].data_low;
     mea_up   = (float)io_mb[iomb_addr_SET].yc[w_addr_SET].yc_pid[0].mea_up;
     mea_low  = (float)io_mb[iomb_addr_SET].yc[w_addr_SET].yc_pid[0].mea_low;
     mea_zero = (float)io_mb[iomb_addr_SET].yc[w_addr_SET].yc_pid[0].mea_zero;
     y = data_up - data_low;
     z = mea_up - mea_low;
    /* if( io_mb[iomb_addr_SET].yc[w_addr_SET].yc_pid[0].AD_signe==(char)NEGATIVE )
     { 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].AD_value * (-1);
	 }*/
	 io_mb[iomb_addr_SET].yc[w_addr_SET].yc_pid[0].f_value
  	   = io_mb[iomb_addr_SET].yc[w_addr_SET].yc_pid[0].AD_value*(y/z)-mea_zero;	
	 	 
     ff_value=io_mb[iomb_addr_SET].yc[w_addr_SET].yc_pid[0].f_value;

⌨️ 快捷键说明

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