⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 real_dataproc.c

📁 该程序实现N4F接口程序
💻 C
字号:

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

extern IO_MB      io_mb[MAX_MODULE_NU];
extern int        rtu_scan_flag, 
                  ANA_first_flag[MAX_MODULE_NU], SW_first_flag[MAX_MODULE_NU]; 
extern char       prs_data[8];      
extern int        soe_flag;
extern time_t     timer_src;

char              scan_type_id;
SOE_REC           soe_rec;

void Real_data_proc()
{ int  i, j, k;  
  int  SW_acc=0, ANA_acc=0;

 scan_type_id=0x00;

 NEXT_LOOP: /*------- 周期扫查RTU各模板上是否有数据变化 ------*/
  
  SW_acc++; ANA_acc++;
  if( ANA_acc>=(2*60*5+7) ) //5 minute
  { ANA_acc = 0;
	printf("ANA板全送**\n",i);
    for(i=0;i<MAX_MODULE_NU;i++){ ANA_first_flag[i]=YES; }
  }
  if( SW_acc>=(2*60*3 ) ) //3 minute
  { SW_acc = 0;
	printf("SW板全送**\n",i); 
    for(i=0;i<MAX_MODULE_NU;i++){ SW_first_flag[i]=YES; } 
  }
  
  for(i=0;i<MAX_MODULE_NU;i++)     
  {        
	if( io_mb[i].mb_used!=YES )
	{ continue; } 
    if(   ( io_mb[i].def_type==(char)YT_TYPE )
		||( io_mb[i].def_type==(char)YK_TYPE )   )
	{ continue; }

	switch( io_mb[i].mb_type )
    { case BCD: //模板类型为BCD板
	    
	    for(j=0;j<8;j++)
		{ 
	      if( io_mb[i].yc[j].scan_allow!=YES )
		  { io_mb[i].mb_w_id =io_mb[i].mb_w_id & ( ~(0x01 << j) );  continue; } //模板字标志置零
		  
		  for( k=0;k<1;k++ )
		  { if( strstr(io_mb[i].yc[j].yc_pid[k].l_name,"----")!=NULL ){ continue; }
		    Get_yc_value( io_mb[i].yc[j].yc_pid[k].l_name, i, j, k );
		  }
        }
		break;

      case IMP: //模板类型为脉冲计数板
	    
	    for(j=0;j<8;j++)
		{ 
	      if( io_mb[i].yc[j].scan_allow!=YES )
		  { io_mb[i].mb_w_id =io_mb[i].mb_w_id & ( ~(0x01 << j) );  continue; } //模板字标志置零
		  
		  for( k=0;k<1;k++ )
		  { if( strstr(io_mb[i].yc[j].yc_pid[k].l_name,"----")!=NULL ){ continue; }
		    Get_yc_value( io_mb[i].yc[j].yc_pid[k].l_name, i, j, k );
		  }
        }
		break;


	  case ANA: //模板类型为模拟量输入板
		
	    for(j=0;j<8;j++)
		{ 
	      if( io_mb[i].yc[j].scan_allow!=YES )
		  { io_mb[i].mb_w_id =io_mb[i].mb_w_id & ( ~(0x01 << j) );  continue; } //模板字标志置零
		  
		  for( k=0;k<1;k++ )
		  { if( strstr(io_mb[i].yc[j].yc_pid[k].l_name,"----")!=NULL ){ continue; }
		    Get_yc_value( io_mb[i].yc[j].yc_pid[k].l_name, i, j, k );
		  }
		            
		  if( io_mb[i].yc[j].chg_flag==YES )
		  { io_mb[i].yc[j].chg_flag = NO; 
		    io_mb[i].mb_w_id        = io_mb[i].mb_w_id | (0x01<<j);//字地址内容有变化,模板字标志对应bit置1
          }
		}
		
		if( ANA_first_flag[i]==YES ) //程序首次启动,模拟量数据全送
		{ soe_flag=SOE_NO;  
		 //zm /*   
		  io_mb[i].mb_data_chg= YES; 
		  io_mb[i].mb_w_id    = (char)0x00;
		  for(j=0;j<8;j++)
          { 
			if( io_mb[i].yc[j].scan_allow==YES )
			{ io_mb[i].mb_w_id = io_mb[i].mb_w_id | ( 0x01 << j ); }
          }
          scan_type_id        = scan_type_id | ( 0x01 << io_mb[i].mb_type_id );
		 //zm */
		  ANA_first_flag[i]       = NO;
		}
		
		if( io_mb[i].mb_w_id!=0x00 )
        { 
          io_mb[i].mb_data_chg= YES;  //模板i中数据有变化,置标志 
		  scan_type_id        = scan_type_id | ( 0x01 << io_mb[i].mb_type_id );
		}		  
	    break;

      case SW:   //模板类型为开关量输入板
	  case TIME_SW:
		
        for(j=0;j<8;j++)
		{ 
		  if( io_mb[i].yx[j].scan_allow!=YES )
		  { io_mb[i].mb_w_id =io_mb[i].mb_w_id & ( ~(0x01 << j) );  continue; } //模板字标志置零
          
		  io_mb[i].yx[j].status_bit=0x00;
		  for( k=0;k<16;k++ )
		  { if( strstr(io_mb[i].yx[j].yx_pid[k].l_name,"----")!=NULL ){ continue; }
		    Get_yx_value( io_mb[i].yx[j].yx_pid[k].l_name, i, j, k );
		  }
    
		  if( io_mb[i].yx[j].chg_flag==YES ) 
          { io_mb[i].yx[j].chg_flag = NO;
		    io_mb[i].mb_w_id        = io_mb[i].mb_w_id | (0x01<<j);//字地址内容有变化,模板字标志对应bit置1
            
			if(io_mb[i].mb_type==TIME_SW)//如果开关量是 SOE
			{ soe_flag = SOE_YES; //有SOE记录产生, 设置SOE标志
			  io_mb[i].yx[j].soe_flag = YES;  
            }
		  }         		  
		}
        if( SW_first_flag[i]==YES )//程序首次启动,开关量数据全送
		{ 
		  soe_flag=SOE_NO; 
		  for(j=0;j<MAX_SOE_REC;j++){ soe_rec.soe_buf[j].used = NO; }
		 //zm/*	
		  io_mb[i].mb_data_chg= YES;
		  io_mb[i].mb_w_id    = 0x00;
		  for(j=0;j<8;j++)
		  { 
			if( io_mb[i].yx[j].scan_allow==YES )
			{ io_mb[i].mb_w_id          = io_mb[i].mb_w_id | ( 0x01 << j );  
              io_mb[i].yx[j].chg_bit_id = ( short )0xffff; 		    			
			}
          }
		  scan_type_id  = scan_type_id | ( 0x01 << io_mb[i].mb_type_id );
	      //zm*/
		  SW_first_flag[i] = NO;
		}

        if( io_mb[i].mb_w_id!=0x00 )
        { 
          io_mb[i].mb_data_chg= YES;  //模板i中数据有变化,置标志 
		  scan_type_id        = scan_type_id | ( 0x01 << io_mb[i].mb_type_id );
		}

		break;

	  default:
        printf("Real_data_proc(): iomb_addr=0x%0x: no this type( 0x%x )\n",i,io_mb[i].mb_type);		                                   
        break;
    }
  }

  Sleep( SCAN_PERIOD ); goto NEXT_LOOP; 
}

// 开关量数据处理过程调用
void Get_yx_value( char long_name[100], int iomb_addr, int w_addr, int pid )
{ short       new_status;
  struct tm   *timeptr;		
  time_t      timevalue;  
  DB_DATA     db_data_space, *db_data;
  int         i;

  db_data = &db_data_space;
  if( (db_data = DBread_by_name( long_name ))==NULL ){ return; }//读实时数据库

  new_status= (db_data->status & 0x000c);
  if( new_status!=0x04 )new_status=0; else new_status=1;

  io_mb[iomb_addr].yx[w_addr].status_bit  
	  = ( short )( io_mb[iomb_addr].yx[w_addr].status_bit | (new_status << pid) ); //在状态字上置位         
     
  if( new_status!=io_mb[iomb_addr].yx[w_addr].yx_pid[pid].status )
  { //开关状态有变化
	io_mb[iomb_addr].yx[w_addr].yx_pid[pid].status     =new_status;
	timevalue=time(NULL);
    timeptr=localtime( &timevalue );
    io_mb[iomb_addr].yx[w_addr].yx_pid[pid].time.year  = ( char )timeptr->tm_year;  
    io_mb[iomb_addr].yx[w_addr].yx_pid[pid].time.month = ( char )timeptr->tm_mon+1; 	
    io_mb[iomb_addr].yx[w_addr].yx_pid[pid].time.day   = ( char )timeptr->tm_mday;
    io_mb[iomb_addr].yx[w_addr].yx_pid[pid].time.hour  = ( char )timeptr->tm_hour;   
    io_mb[iomb_addr].yx[w_addr].yx_pid[pid].time.minute= ( char )timeptr->tm_min;  
    io_mb[iomb_addr].yx[w_addr].yx_pid[pid].time.second= ( char )timeptr->tm_sec;  
    io_mb[iomb_addr].yx[w_addr].yx_pid[pid].time.value = timevalue;
    io_mb[iomb_addr].yx[w_addr].chg_bit_id 
		= ( short )( (0x01<<pid) | io_mb[iomb_addr].yx[w_addr].chg_bit_id ); //在变位标志状态字上置位        
    io_mb[iomb_addr].yx[w_addr].chg_flag              =YES;
    printf("(%02d_%d_%02d) %s %s  stat=0x%x %4d/%02d/%02d %02d:%02d:%02d",
		    iomb_addr, w_addr, pid,
		    io_mb[iomb_addr].yx[w_addr].yx_pid[pid].c_name,
            io_mb[iomb_addr].yx[w_addr].yx_pid[pid].l_name,
			db_data->status, 
            timeptr->tm_year+1900, timeptr->tm_mon+1, 
			timeptr->tm_mday,      timeptr->tm_hour,
            timeptr->tm_min,       timeptr->tm_sec       );
	if( new_status==0 ){ printf(" OPEN\n"); }else{ printf(" CLOSE\n"); } 

	if(io_mb[iomb_addr].mb_type==TIME_SW )
    { //此开关量为SOE量
	  for(i=0;i<MAX_SOE_REC;i++){ if(soe_rec.soe_buf[i].used==NO)break; }//在SOE记录区找空位置
	  if( i>=MAX_SOE_REC ){ printf("SOE_BUF OVERFLOW !!!\n;" ); return; }
	  
	  soe_rec.soe_buf[i].used      = YES;
	  soe_rec.soe_buf[i].iomb_addr = iomb_addr;
	  soe_rec.soe_buf[i].word_addr = w_addr;
      soe_rec.soe_buf[i].bit_addr  = pid;
	  if( pid<8 )
      { soe_rec.soe_buf[i].status_id = 0x01 << pid; 
	    soe_rec.soe_buf[i].status    = 0x00 | (new_status << pid); 
        soe_rec.soe_buf[i].location  = 0; // 0表明是低字节
	  } 
      else
      { soe_rec.soe_buf[i].status_id = ( 0x01 << pid) >> 8; 
	    soe_rec.soe_buf[i].status    = ( 0x00 | (new_status << pid) ) >> 8; 
        soe_rec.soe_buf[i].location  = 1; // 0表明是高字节
	  } 
	  soe_rec.soe_buf[i].time_val    = timevalue - soe_rec.syn_time; //以上参见规约第16页,时标数据格式
	  printf("++++ SOE_BUF=%d (%02d_%d_%02d), syn_time=%ld, abs_time=%ld\n",
		      i, iomb_addr, w_addr, pid, 
		      soe_rec.syn_time, soe_rec.soe_buf[i].time_val                  );    
	}
  }   
}


//模拟量数据处理过程调用
float     f_value;
void Get_yc_value( char long_name[100], int iomb_addr, int w_addr, int pid )
{ short       AD_value;
  INT_STRU    int_stru;
  int         i, left;
  DB_DATA     db_data_space, *db_data;
  
  db_data = &db_data_space;
  if( (db_data = DBread_by_name( long_name ))==NULL ){ return; }//读实时数据库
  
  if(   (db_data->status==io_mb[iomb_addr].yc[w_addr].yc_pid[pid].status)
      &&(db_data->value ==io_mb[iomb_addr].yc[w_addr].yc_pid[pid].value)  )
  {  //模拟量无变化则返回
	  return;
  }
  else
  {  io_mb[iomb_addr].yc[w_addr].yc_pid[pid].status = db_data->status;
     io_mb[iomb_addr].yc[w_addr].yc_pid[pid].value  = db_data->value;
  }

  /*---- 处理BCD数据, 如:上下游水位  ----*/
  if( io_mb[iomb_addr].mb_type==BCD )  
  { //io_mb[iomb_addr].yc[w_addr].yc_pid[pid].l_value  = db_data->value;  
    io_mb[iomb_addr].yc[w_addr].yc_pid[pid].l_value  = db_data->value - 8800; //水位减8000cm  
    printf("(%02d_%01d) %s %s  value=%d \n",
		   iomb_addr, w_addr,
		   io_mb[iomb_addr].yc[w_addr].yc_pid[pid].c_name,
           io_mb[iomb_addr].yc[w_addr].yc_pid[pid].l_name,
           db_data->value                                   );
	io_mb[iomb_addr].yc[w_addr].chg_flag  = YES;	
	return;
  }

  /*---- 处理脉冲量数据,电调需要脉冲个数 ----*/
  if( io_mb[iomb_addr].mb_type==IMP ) 
  { io_mb[iomb_addr].yc[w_addr].yc_pid[pid].imp_new  = db_data->value;
    //计算脉冲数增值
    if( io_mb[iomb_addr].yc[w_addr].yc_pid[0].imp_old <= io_mb[iomb_addr].yc[w_addr].yc_pid[0].imp_new )
	{ i = io_mb[iomb_addr].yc[w_addr].yc_pid[0].imp_new 
	      - io_mb[iomb_addr].yc[w_addr].yc_pid[0].imp_old; 
	}
	else
    { i = io_mb[iomb_addr].yc[w_addr].yc_pid[0].imp_new + 32767 
	      - io_mb[iomb_addr].yc[w_addr].yc_pid[0].imp_old; 
	}

	if( (i*io_mb[iomb_addr].yc[w_addr].yc_pid[0].EMS_imp_cvt)<=
           io_mb[iomb_addr].yc[w_addr].yc_pid[0].PD_imp_cvt       )
    { return; }
    else
    { io_mb[iomb_addr].yc[w_addr].yc_pid[0].imp_old = io_mb[iomb_addr].yc[w_addr].yc_pid[0].imp_new; }
    
	
	left = (int)(io_mb[iomb_addr].yc[w_addr].yc_pid[0].EMS_imp_cvt * i) %
           (int)io_mb[iomb_addr].yc[w_addr].yc_pid[0].PD_imp_cvt;
    io_mb[iomb_addr].yc[w_addr].yc_pid[0].imp_old 
		 = io_mb[iomb_addr].yc[w_addr].yc_pid[0].imp_old - left; //余数留下次

	//将脉冲数增值折算成网调的脉冲数
	i = (int)( (io_mb[iomb_addr].yc[w_addr].yc_pid[0].EMS_imp_cvt * i) / 
               io_mb[iomb_addr].yc[w_addr].yc_pid[0].PD_imp_cvt );  
	//将脉冲数增值加到网调脉冲计数器中
    io_mb[iomb_addr].yc[w_addr].yc_pid[pid].l_value=io_mb[iomb_addr].yc[w_addr].yc_pid[pid].l_value + i;
	if( io_mb[iomb_addr].yc[w_addr].yc_pid[pid].l_value > 16777215 /* 0xffffff */ )//网调的电度计数器为24位bit
	{ io_mb[iomb_addr].yc[w_addr].yc_pid[pid].l_value
      = io_mb[iomb_addr].yc[w_addr].yc_pid[pid].l_value - 16777216;
    } 

    printf("(%02d_%01d) %s %s  h9000_imp=%ld  n4f_imp=%ld \n",
		   iomb_addr, w_addr,
		   io_mb[iomb_addr].yc[w_addr].yc_pid[pid].c_name,
           io_mb[iomb_addr].yc[w_addr].yc_pid[pid].l_name,
           db_data->value, 
		   io_mb[iomb_addr].yc[w_addr].yc_pid[pid].l_value  );
	io_mb[iomb_addr].yc[w_addr].chg_flag = YES;  
	return;
  }

  /*---- 处理模拟量数据 ----*/
  if( io_mb[iomb_addr].mb_type==ANA )  
  { int_stru.value = db_data->value;
    int_stru.sign  = db_data->status & 0x80;
    int_stru.format= (db_data->status>>5) & 0x03;
    Int_to_float( &int_stru ); //把H9000格式模拟量转成浮点数,放在外部变量f_value中    
  
    AD_value=Get_ADvalue( iomb_addr, w_addr, pid );//模拟量浮点数转成电调要求的AD码
    i = prs_data[io_mb[iomb_addr].yc[w_addr].yc_pid[pid].prs_id];
    if( abs( AD_value - io_mb[iomb_addr].yc[w_addr].yc_pid[pid].AD_value ) >= i )	  
	{ //数值变化大于死区值
      io_mb[iomb_addr].yc[w_addr].yc_pid[pid].AD_value  =AD_value;
      io_mb[iomb_addr].yc[w_addr].yc_pid[pid].f_value   =f_value;
      io_mb[iomb_addr].yc[w_addr].yc_pid[pid].value     =db_data->value;   
      io_mb[iomb_addr].yc[w_addr].yc_pid[pid].status    =db_data->status;   
      io_mb[iomb_addr].yc[w_addr].chg_flag              =YES;
      printf("(%02d_%01d) %s %s  val=%d stat=0x%x f_val=%7.3f AD_val=%d\n",
	    	 iomb_addr, w_addr,
		     io_mb[iomb_addr].yc[w_addr].yc_pid[pid].c_name,
             io_mb[iomb_addr].yc[w_addr].yc_pid[pid].l_name,
             db_data->value, 
		     db_data->status,
             io_mb[iomb_addr].yc[w_addr].yc_pid[pid].f_value,
             io_mb[iomb_addr].yc[w_addr].yc_pid[pid].AD_value   ); 
	}   
    return;
  }
}


int Get_ADvalue( int iomb_addr, int w_addr, int pid )
{ float x, y, z, data_up, data_low, mea_up, mea_low, mea_zero;
  int   iii;  
  if(   (io_mb[iomb_addr].yc[w_addr].yc_pid[pid].data_up ==0) 
      &&(io_mb[iomb_addr].yc[w_addr].yc_pid[pid].data_low==0) 
      &&(io_mb[iomb_addr].yc[w_addr].yc_pid[pid].mea_up  ==0)
      &&(io_mb[iomb_addr].yc[w_addr].yc_pid[pid].mea_low ==0)
      &&(io_mb[iomb_addr].yc[w_addr].yc_pid[pid].mea_zero==0) )
  { return( ( int )-9999 ); }
  
  if(   (io_mb[iomb_addr].yc[w_addr].yc_pid[pid].mea_up  != -1)
      &&(io_mb[iomb_addr].yc[w_addr].yc_pid[pid].mea_low != -1)
      &&(io_mb[iomb_addr].yc[w_addr].yc_pid[pid].mea_zero!= -1) )
  {
    data_up = ( float )io_mb[iomb_addr].yc[w_addr].yc_pid[pid].data_up;
    data_low= ( float )io_mb[iomb_addr].yc[w_addr].yc_pid[pid].data_low;
    mea_up  = ( float )io_mb[iomb_addr].yc[w_addr].yc_pid[pid].mea_up;
    mea_low = ( float )io_mb[iomb_addr].yc[w_addr].yc_pid[pid].mea_low;
    mea_zero= ( float )io_mb[iomb_addr].yc[w_addr].yc_pid[pid].mea_zero;
    y = data_up - data_low;
    z = mea_up - mea_low;
    x = f_value * ( z/y ) + mea_zero; //浮点数转换到AD码
  }
  else
  {
    x = f_value; //浮点数不转换到AD码,直接使用
  }

  iii = (int)x; 
  
  if( iii<0 )
  { io_mb[iomb_addr].yc[w_addr].yc_pid[pid].AD_signe = (char)NEGATIVE; iii=iii*(-1); }
  else
  { io_mb[iomb_addr].yc[w_addr].yc_pid[pid].AD_signe = (char)POSITIVE; }

  return( iii );    
}

⌨️ 快捷键说明

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