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 + -
显示快捷键?