📄 real_dataproc.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 + -