#include "head.h" #ifdef __IEC61850_GOOSE_FUNC__ #include "app_61850.h" #endif #include "goose.h" int g_bgseEnable; const struct gse_tbl g_goose_send_tbl[GOOSE_SEND_TBL_NUMBER]= { {"节点故障", "GSE_KO_FAULT"}, {"故障隔离成功", "GSE_KO_GLOK"}, {"开关拒跳", "GSE_KO_JT"}, {"过流闭锁", "GSE_KO_GLBS"}, #if defined GD_AREA_ZHONGSHAN || defined GD_AREA_ZHONGSHAN_2020 //中山要求通信异常,全系统均异常 {"状态闭锁值", "GSE_KO_BS_STATUS"}, {"状态复归值", "GSE_KO_BS_FG"}, #endif }; const struct gse_tbl g_goose_recv_tbl[GOOSE_RECV_TBL_NUMBER]= { {"M侧节点故障01", "GSE_KI_M01"}, {"M侧节点故障02", "GSE_KI_M02"}, {"M侧节点故障03", "GSE_KI_M03"}, {"M侧节点故障04", "GSE_KI_M04"}, {"M侧节点故障05", "GSE_KI_M05"}, {"M侧节点故障06", "GSE_KI_M06"}, {"M侧节点故障07", "GSE_KI_M07"}, {"M侧节点故障08", "GSE_KI_M08"}, {"N侧节点故障01", "GSE_KI_N01"}, {"N侧节点故障02", "GSE_KI_N02"}, {"N侧节点故障03", "GSE_KI_N03"}, {"N侧节点故障04", "GSE_KI_N04"}, {"M侧障隔离成功01", "GSE_KI_GLCG01"}, {"M侧障隔离成功02", "GSE_KI_GLCG02"}, {"M侧障隔离成功03", "GSE_KI_GLCG03"}, {"M侧障隔离成功04", "GSE_KI_GLCG04"}, {"M侧障隔离成功05", "GSE_KI_GLCG05"}, {"M侧障隔离成功06", "GSE_KI_GLCG06"}, {"M侧障隔离成功07", "GSE_KI_GLCG07"}, {"M侧障隔离成功08", "GSE_KI_GLCG08"}, {"N侧障隔离成功01", "GSE_KI_GLCG09"}, {"N侧障隔离成功02", "GSE_KI_GLCG10"}, {"N侧障隔离成功03", "GSE_KI_GLCG11"}, {"N侧障隔离成功04", "GSE_KI_GLCG12"}, {"M侧开关拒跳01", "GSE_KI_JT01"}, {"M侧开关拒跳02", "GSE_KI_JT02"}, {"M侧开关拒跳03", "GSE_KI_JT03"}, {"M侧开关拒跳04", "GSE_KI_JT04"}, {"M侧开关拒跳05", "GSE_KI_JT05"}, {"馈线开关拒跳01", "GSE_KI_JT06"}, {"馈线开关拒跳02", "GSE_KI_JT07"}, {"馈线开关拒跳03", "GSE_KI_JT08"}, {"N侧开关拒跳01", "GSE_KI_JT09"}, {"N侧开关拒跳02", "GSE_KI_JT10"}, {"N侧开关拒跳03", "GSE_KI_JT11"}, {"馈线开关拒跳04", "GSE_KI_JT12"}, {"馈线过流闭锁01", "GSE_KI_GLBS01"}, {"馈线过流闭锁02", "GSE_KI_GLBS02"}, {"馈线过流闭锁03", "GSE_KI_GLBS03"}, {"馈线过流闭锁04", "GSE_KI_GLBS04"}, {"馈线过流闭锁05", "GSE_KI_GLBS05"}, {"馈线过流闭锁06", "GSE_KI_GLBS06"}, {"馈线过流闭锁07", "GSE_KI_GLBS07"}, {"馈线过流闭锁08", "GSE_KI_GLBS08"}, {"馈线过流闭锁09", "GSE_KI_GLBS09"}, {"馈线过流闭锁10", "GSE_KI_GLBS10"}, {"馈线过流闭锁11", "GSE_KI_GLBS11"}, {"馈线过流闭锁12", "GSE_KI_GLBS12"}, #if defined GD_AREA_ZHONGSHAN || defined GD_AREA_ZHONGSHAN_2020 //中山要求通信异常,全系统均异常 {"状态闭锁值01", "GSE_KI_BS_STATUS01"}, {"状态闭锁值02", "GSE_KI_BS_STATUS02"}, {"状态闭锁值03", "GSE_KI_BS_STATUS03"}, {"状态闭锁值04", "GSE_KI_BS_STATUS04"}, {"状态闭锁值05", "GSE_KI_BS_STATUS05"}, {"状态闭锁值06", "GSE_KI_BS_STATUS06"}, {"状态闭锁值07", "GSE_KI_BS_STATUS07"}, {"状态闭锁值08", "GSE_KI_BS_STATUS08"}, {"状态闭锁值09", "GSE_KI_BS_STATUS09"}, {"状态闭锁值10", "GSE_KI_BS_STATUS10"}, {"状态闭锁值11", "GSE_KI_BS_STATUS11"}, {"状态闭锁值12", "GSE_KI_BS_STATUS12"}, {"状态复归值01", "GSE_KI_FG_STATUS01"}, {"状态复归值02", "GSE_KI_FG_STATUS02"}, {"状态复归值03", "GSE_KI_FG_STATUS03"}, {"状态复归值04", "GSE_KI_FG_STATUS04"}, {"状态复归值05", "GSE_KI_FG_STATUS05"}, {"状态复归值06", "GSE_KI_FG_STATUS06"}, {"状态复归值07", "GSE_KI_FG_STATUS07"}, {"状态复归值08", "GSE_KI_FG_STATUS08"}, {"状态复归值09", "GSE_KI_FG_STATUS09"}, {"状态复归值10", "GSE_KI_FG_STATUS10"}, {"状态复归值11", "GSE_KI_FG_STATUS11"}, {"状态复归值12", "GSE_KI_FG_STATUS12"}, #endif }; FA_GOOSE tFAg; bool bFAgInit=false; void fa_g_init(void) { int i; if(!bFAgInit) // 61850 初始化会调用 fa_g_extinit ,将初始化部分tFAg的变量,两处调用可能先后顺序不确定,保证只初始化一次 { bFAgInit=true; memset(&tFAg,0,sizeof(tFAg)); } for(i=0;idT_sendext*100, 0); InitTR(&tFAg.tGooseStillTime,T_20ms,T_20ms); #if defined GD_AREA_ZHONGSHAN || defined GD_AREA_ZHONGSHAN_2020 InitTR(&tFAg.tErrfgtime,tRunPara.gse_T1,0); #endif fa_g_packet(true); //发送数据初始化 } // buf 为32个遥信的起始位置 void fa_g_unpack(void) { int i; bool bgzglok=0; int sw=0; TGOC_T *poc=&g_tRelay[ sw].tgoc; TRELAY_T *pR=&g_tRelay[sw]; if(BH_GOOSE_EN_YB(sw)) //智能FA 不投入时,不处理订阅信息 { for(i=0;i<=GOOSE_RECV_LOGIC_NUM;i++) { int soeno=EV_GOOSE_BGN+i; if(tFAg.inval[i]>0) { if(soe_check(soeno)==false) { soe_record_ev(soeno, 1, 0,0,0 ); ResetTR(&tFAg.tRstTime); } } else { if(soe_check(soeno)==true) { soe_record_ev(soeno, 0, 0,0,0 ); } } } for(i=0;i0)?1:0; tFAg.ugside[i].bFlag.bgzglok=(tFAg.inval[GOOSE_RECV_TBL_GL01+i]>0)?1:0; tFAg.ugside[i].bFlag.bglbs=(tFAg.inval[GOOSE_RECV_TBL_GLBS01+i]>0)?1:0; bgzglok|=tFAg.ugside[i].bFlag.bgzglok; } for(i=0;i0)?1:0; } #if defined GD_AREA_ZHONGSHAN || defined GD_AREA_ZHONGSHAN_2020 //中山要求通信异常,全系统均异常 { u32 st,fg; uint32_t flags; st=0; fg=0; for(i=0;itSWST.uSWST.bFlag.bTZWZ) //开关在跳位不转发 { return; } if(pRunSet->tSwSet[sw].tGocSet.bsw_fz) //分支开关不转发 { return; } if(g_tRelay[sw].tgoc.bTzout) // 本装置处于跳闸状态,不转发故障隔离信号 { RunTR(&poc->tgzglokForbitTime, true, 1); //故障隔离发送闭锁 return; } if(!poc->tgzglokForbitTime.boolTrip) //故障隔离发送未闭锁 { RunTR(&poc->tgzglokextTime, true, 1); poc->psta.bFlag.bgzglok=poc->tgzglokextTime.boolTrip; RunTR(&poc->tgzglokForbitTime, poc->psta.bFlag.bgzglok, 1); //故障隔离发送闭锁 } } if(soe_check(EV_GOOSE_DECODE)==true) { soe_record_ev(EV_GOOSE_DECODE,0, 0,0,0 ); } } } void fa_g_decode(int commstate) { int sw=0; // TGOC_T *poc=&g_tRelay[ sw].tgoc; if((commstate==-1)&&BH_GOOSE_EN_YB(sw)) { if(soe_check(EV_GOOSE_DECODE)==false) { soe_record_ev(EV_GOOSE_DECODE,1, 0,0,0 ); } return; } #if 0 if((commstate>0)&&BH_GOOSE_EN_YB(sw)) { if(soe_check(EV_GOOSE_ERR)==false) { soe_record_ev(EV_GOOSE_ERR,1, 0,0,0 ); poc->psta.bFlag.bcomerr=1; } if(soe_check(EV_SYS_GOOSE_ERR)==false) //置系统通信异常soe { soe_record_ev(EV_SYS_GOOSE_ERR, 1, 0,0,0 ); tFAg.syscomerr=1; //goose系统通信异常 } tFAg.commerr=1; } else { if(soe_check(EV_GOOSE_ERR)==true) { soe_record_ev(EV_GOOSE_ERR,0, 0,0,0 ); } tFAg.commerr=0; } #endif } void fa_g_extinit(int num,int firstaddr) // app_goose.c中调用fa_g.c中的变量初始化 { int i; if(num>=GOOSE_RECV_GOLBNUM)num=GOOSE_RECV_GOLBNUM; if(!bFAgInit) { bFAgInit=true; memset(&tFAg,0,sizeof(tFAg)); } tFAg.recvgolbnum=num; for(i=0;i=GOOSE_RECV_TBL_N01)tFAg.bNside=true; // 若输入控制块只有一个,判断是M侧还是N侧 } void fa_g_gocbrecvdT(int index) // app_goose.c中接收后调用,用于通信超时处理 { if(indextSwSet[sw]; TGOC_T *poc=&g_tRelay[ sw].tgoc; if( pR->tSWST.uSWST.bFlag.bTZWZ&&(!pSet->tGocSet.bsw_ll&&!pSet->tGocSet.bsw_fz)) { if(poc->bgooseGz) { if(soe_check(EV_GOOSE_GZBS_FA)==false) // goose故障闭锁 { soe_record_ev(EV_GOOSE_GZBS_FA, 1, 0,0,0 ); } } else { if(soe_check(EV_GOOSE_TZBS_FA)==false) // goose故障闭锁 { soe_record_ev(EV_GOOSE_TZBS_FA, 1, 0,0,0 ); } } poc->bgooseBsHz=true; } else { poc->bgooseGz=false; poc->bgooseBsHz=false; } } #ifdef GOOSE_NETTYPE_SET extern unsigned char fec_get_hsr_prp_flag(void);//返回订阅点组网类型 #endif void fa_g_app_time(int sw) // 1s 执行一次函数 { sw=0; #ifdef DFA_MESH_ERR_SOE // 单一网口网线掉了,需弹soe if( rt_get_net_linkstatus(0) && BH_GOOSE_EN_YB(sw)&&g_goose_net_type) //普通模式,不报单网卡掉线 { if(soe_check(EV_NET1_DOWN)==false) { soe_record_ev(EV_NET1_DOWN,1, 0,0,0 ); } } else { if(soe_check(EV_NET1_DOWN)==true) { soe_record_ev(EV_NET1_DOWN,0, 0,0,0 ); } } if( rt_get_net_linkstatus(1) && BH_GOOSE_EN_YB(sw)&&g_goose_net_type) { if(soe_check(EV_NET2_DOWN)==false) { soe_record_ev(EV_NET2_DOWN,1, 0,0,0 ); } } else { if(soe_check(EV_NET2_DOWN)==true) { soe_record_ev(EV_NET2_DOWN,0, 0,0,0 ); } } #endif #ifdef GOOSE_NETTYPE_SET u8 temp; static u8 nettype; static u32 count; //unsigned char fec_get_hsr_prp_flag() //return 1--hsr;return 2--prp;return 3--hsr&prp if(BH_GOOSE_EN(sw)&&g_goose_net_type)// { //nettype temp=fec_get_hsr_prp_flag(); if(temp) { nettype |= temp; } //10s判一次 count++; if(count%10==0) { if(nettype) { if(nettype&g_goose_net_type) { if(soe_check(EV_GOOSE_NETTYPE_ERR)==true) { soe_record_ev(EV_GOOSE_NETTYPE_ERR,0, 0,0,0 ); } } else { if(soe_check(EV_GOOSE_NETTYPE_ERR)==false) { soe_record_ev(EV_GOOSE_NETTYPE_ERR,1, 0,0,0 ); } } } nettype=0; } } else { if(soe_check(EV_GOOSE_NETTYPE_ERR)==true) { soe_record_ev(EV_GOOSE_NETTYPE_ERR,0, 0,0,0 ); } } #endif #ifdef GD_AREA_ZHONGSHAN_2020// 中山局 { bool bCfgerr; bCfgerr=pRunSet->tSwSet[sw].tGocSet.bKg_mainloop // 主环开关 &&(tFAg.recvgolbnum==0) //接收控制块未配置 &&(gi_platelib_state ==IEC61850_LIB_INIT_SUCCESS); // 61850初始化完毕 if(bCfgerr) { if(soe_check(EV_GOOSE_CONFIG_ERR)==false) { soe_record_ev(EV_GOOSE_CONFIG_ERR,1, 0,0,0 ); } } else { if(soe_check(EV_GOOSE_CONFIG_ERR)==true) { soe_record_ev(EV_GOOSE_CONFIG_ERR,0, 0,0,0 ); } } } #endif } void fa_g_commcheck(DWORD dStep) // 防止goose信息丢失,相关置位信息延时复归 { int i; bool bret=false; bool boverdT=false; int sw=0; for(i=0;i<=GOOSE_RECV_LOGIC_NUM;i++) { bret|=(tFAg.inval[i]>0)?true:false; } RunTR(&tFAg.tRstTime, bret, dStep); // 信息延迟复归 if(tFAg.tRstTime.boolTrip) { for(i=0;i<=GOOSE_RECV_LOGIC_NUM;i++) { if(tFAg.tRstTime.boolTrip&&(tFAg.inval[i]>0))tFAg.inval[i]=0; } ResetTR(&tFAg.tRstTime); fa_g_unpack(); } #if defined GD_AREA_ZHONGSHAN || defined GD_AREA_ZHONGSHAN_2020 if(tFAg.commerr) { tFAg.commerrst|=(1<0) // { if(soe_check(EV_SYS_GOOSE_ERR)==false) //置系统通信异常soe { soe_record_ev(EV_SYS_GOOSE_ERR, 1, 0,0,0 ); tFAg.syscomerr=1; //goose系统通信异常 fa_g_bs_fa(sw); if(tFAg.commerr) { InitTR(&tFAg.tErrfgtime,tRunPara.gse_T1,0); // 若是本机通信异常,发送时间为T1 } else { InitTR(&tFAg.tErrfgtime,tRunPara.gse_T2,0); // 若不是本机通信异常,发送时间为T2 } } } else { if(soe_check(EV_SYS_GOOSE_ERR)==true) //置系统通信异常soe { soe_record_ev(EV_SYS_GOOSE_ERR, 0, 0,0,0 ); tFAg.syscomerr=0; //goose系统通信异常 } } RunTR(&tFAg.tErrfgtime, tFAg.commerrfg, dStep); // 分布式功能投入 if(tFAg.tErrfgtime.boolTrip) //复归发送时间到,清复归标志:条件 无通信异常 { tFAg.commerrfg&=tFAg.commerrst; ResetTR(&tFAg.tErrfgtime); } #endif for(i=0;iT_1s*20)?true:false; if(!BH_GOOSE_EN_YB(sw)) { tFAg.dTrecv[i]=dTCounter; } #ifdef DFA_MESH_ERR_SOE // 单一网口网线掉了,需弹soe { bool berr=((dTCounter-tFAg.dTrecv[i])>T_1s*20)?true:false; if(berr&&BH_GOOSE_EN_YB(sw)) { if(((i==tFAg.recvgolbnum-1)&&(tFAg.recvgolbnum>1))||tFAg.bNside) { if(soe_check(EV_GOOSE_ERR_N)==false) { soe_record_ev(EV_GOOSE_ERR_N,1, 0,0,0 ); } } else { if(soe_check(EV_GOOSE_ERR_M)==false) { soe_record_ev(EV_GOOSE_ERR_M,1, 0,0,0 ); } } } else { if(((i==tFAg.recvgolbnum-1)&&(tFAg.recvgolbnum>1))||tFAg.bNside) { if(soe_check(EV_GOOSE_ERR_N)==true) { soe_record_ev(EV_GOOSE_ERR_N,0, 0,0,0 ); } } else if(soe_check(EV_GOOSE_ERR_M)==true) { int j; bool berr1=false; for(j=0;jT_1s*20)?true:false; } if(berr1==false) { soe_record_ev(EV_GOOSE_ERR_M,0, 0,0,0 ); } } } } #endif } if(boverdT&&BH_GOOSE_EN_YB(sw)) { if(soe_check(EV_GOOSE_ERR)==false) { soe_record_ev(EV_GOOSE_ERR,1, 0,0,0 ); } tFAg.commerr=1; } else { if(soe_check(EV_GOOSE_ERR)==true) { soe_record_ev(EV_GOOSE_ERR,0, 0,0,0 ); //本机通信恢复 #if defined GD_AREA_ZHONGSHAN || defined GD_AREA_ZHONGSHAN_2020 tFAg.commerrfg|=(1<tgoc; bool bcommerrsend=false; pug->bFlag.bzx=poc->psta.bFlag.bZX; // 本线路正向故障 pug->bFlag.bfx=poc->psta.bFlag.bFX; // 本线路反向故障 pug->bFlag.blx=poc->psta.bFlag.bLX; //本线路无方向故障 #if defined GD_AREA_ZHONGSHAN || defined GD_AREA_ZHONGSHAN_2020 || defined GD_AREA_MAIN_2020 pug->bFlag.bgl=poc->psta.bFlag.bWX||poc->psta2.bFlag.bWX; // 本线路跳闸失败 #else pug->bFlag.bgl=poc->psta.bFlag.bWX; // 本线路跳闸失败 #endif pug->bFlag.bgzglok=poc->psta.bFlag.bgzglok; // 本线路跳闸失败 pug->bFlag.btzsb=poc->psta.bFlag.btzsb||(pR->uBHDZ.bFlag.bTZSB&&pRunSet->bTT_fhkg_pub); // 本线路跳闸失败 pug->bFlag.bglbs=poc->psta.bFlag.bGLBS; //负荷开关 #if defined GD_AREA_ZHONGSHAN || defined GD_AREA_ZHONGSHAN_2020 //中山要求通信异常,全系统均异常 if(tFAg.commerrst!=tFAg.commerrstsave||tFAg.commerrfg!=tFAg.commerrfgsave) { bcommerrsend=true; tFAg.commerrstsave=tFAg.commerrst; tFAg.commerrfgsave=tFAg.commerrfg; } #endif g_bgseEnable=BH_GOOSE_EN_YB(sw)||pRunSet->bTT_fhkg_pub; if((pug->wfFlag!=tFAg.ug_save)||bfirst||bcommerrsend) //启动goose 发送 { int *dat=tFAg.outval; tFAg.ug_save=pug->wfFlag; dat[GOOSE_SEND_TBL_GZ]=(pug->bFlag.bgl||pug->bFlag.blx||pug->bFlag.bTstgz); dat[GOOSE_SEND_TBL_GL]=(pug->bFlag.bgzglok||pug->bFlag.bTstglok); dat[GOOSE_SEND_TBL_JT]=(pug->bFlag.btzsb)||pug->bFlag.bTstjt; //开关拒跳:智能FA逻辑或负荷开关常规动作拒跳 dat[GOOSE_SEND_TBL_GLBS]=pug->bFlag.bglbs||pug->bFlag.bTstglbs; //负荷开关 #if defined GD_AREA_ZHONGSHAN || defined GD_AREA_ZHONGSHAN_2020 //中山要求通信异常,全系统均异常 dat[GOOSE_SEND_TBL_STATUS]=tFAg.commerrstsave; // 通信状态 dat[GOOSE_SEND_TBL_FG]=tFAg.commerrfgsave; //复归值 #endif if(!bfirst) { tFAg.bSend=true; #ifdef __IEC61850_GOOSE_FUNC__ goose_send_wakeup(); #endif } } } // A相电流方向判断 void GOc_dir_phA(int sw) { TGOC_T *poc=&g_tRelay[ sw].tgoc; GOC_SET *pSet = &pRunSet->tSwSet[sw].tGocSet; int indexI; bool bzx,bfx; u32 dIgl,dIgl_fh; dIgl=pSet->dIgl; dIgl_fh=pSet->dIgl_fh; indexI=UI_SW_INDEX(sw,SW_AC_IA); poc->psta.bFlag.bQDA = OverRelay(g_ui[indexI ].m2[0], dIgl, dIgl_fh, poc->psta.bFlag.bQDA); // A相过流启动 bzx=CalDir_A(sw,poc->psta.bFlag.bQDA&&pSet->bTT_DIR,false); bfx=(!bzx)&&poc->psta.bFlag.bQDA&&pSet->bTT_DIR; poc->psta.bFlag.bZXA=poc->psta.bFlag.bQDA // A相电流启动 &&bzx // 正方向 &&pSet->bTT_DIR //功率方向投入 &&(!tPT.uPT1DX.bFlag.bPTYC); poc->psta.bFlag.bFXA=poc->psta.bFlag.bQDA // A相电流启动 &&(bfx) //反方向 &&pSet->bTT_DIR //功率方向投入 &&(!tPT.uPT1DX.bFlag.bPTYC); poc->psta.bFlag.bWXA=poc->psta.bFlag.bQDA // A相电流启动 &&(!pSet->bTT_DIR||tPT.uPT1DX.bFlag.bPTYC); // 功率方向退出或功率方向投入,PT异常退方向) #if defined GD_AREA_ZHONGSHAN || defined GD_AREA_ZHONGSHAN_2020 dIgl=pSet->dIgl2; dIgl_fh=pSet->dIgl2_fh; poc->psta2.bFlag.bQDA = OverRelay(g_ui[indexI ].m2[0], dIgl, dIgl_fh, poc->psta2.bFlag.bQDA); // A相过流启动 bzx=CalDir_A(sw,poc->psta2.bFlag.bQDA&&pSet->bTT_DIR,false); bfx=(!bzx)&&poc->psta2.bFlag.bQDA&&pSet->bTT_DIR; poc->psta2.bFlag.bZXA=poc->psta2.bFlag.bQDA // A相电流启动 &&bzx // 正方向 &&pSet->bTT_DIR //功率方向投入 &&(!tPT.uPT1DX.bFlag.bPTYC); poc->psta2.bFlag.bFXA=poc->psta2.bFlag.bQDA // A相电流启动 &&(bfx) //反方向 &&pSet->bTT_DIR //功率方向投入 &&(!tPT.uPT1DX.bFlag.bPTYC); poc->psta2.bFlag.bWXA=poc->psta2.bFlag.bQDA // A相电流启动 &&(!pSet->bTT_DIR||tPT.uPT1DX.bFlag.bPTYC); // 功率方向退出或功率方向投入,PT异常退方向) #endif } // B相电流方向判断 void GOc_dir_phB(int sw) { TGOC_T *poc=&g_tRelay[ sw].tgoc; GOC_SET *pSet = &pRunSet->tSwSet[sw].tGocSet; int indexI; bool bzx,bfx; u32 dIgl,dIgl_fh; dIgl=pSet->dIgl; dIgl_fh=pSet->dIgl_fh; indexI=UI_SW_INDEX(sw,SW_AC_IB); poc->psta.bFlag.bQDB = OverRelay(g_ui[indexI ].m2[0], dIgl, dIgl_fh, poc->psta.bFlag.bQDB); // A相过流启动 bzx=CalDir_B(sw,poc->psta.bFlag.bQDB&&pSet->bTT_DIR,false); bfx=(!bzx)&&poc->psta.bFlag.bQDB&&pSet->bTT_DIR; poc->psta.bFlag.bZXB=poc->psta.bFlag.bQDB // A相电流启动 &&bzx // 正方向 &&pSet->bTT_DIR //功率方向投入 &&(!tPT.uPT1DX.bFlag.bPTYC); // 无TV异常 poc->psta.bFlag.bFXB=poc->psta.bFlag.bQDB // A相电流启动 &&(bfx) //反方向 &&pSet->bTT_DIR //功率方向投入 &&(!tPT.uPT1DX.bFlag.bPTYC); // 无TV异常 poc->psta.bFlag.bWXB=poc->psta.bFlag.bQDB // A相电流启动 &&(!pSet->bTT_DIR||tPT.uPT1DX.bFlag.bPTYC); // 功率方向退出或功率方向投入,PT异常退方向) #if defined GD_AREA_ZHONGSHAN || defined GD_AREA_ZHONGSHAN_2020 dIgl=pSet->dIgl2; dIgl_fh=pSet->dIgl2_fh; poc->psta2.bFlag.bQDB = OverRelay(g_ui[indexI ].m2[0], dIgl, dIgl_fh, poc->psta2.bFlag.bQDB); // A相过流启动 bzx=CalDir_B(sw,poc->psta2.bFlag.bQDB&&pSet->bTT_DIR,false); bfx=(!bzx)&&poc->psta2.bFlag.bQDB&&pSet->bTT_DIR; poc->psta2.bFlag.bZXB=poc->psta2.bFlag.bQDB // A相电流启动 &&bzx // 正方向 &&pSet->bTT_DIR //功率方向投入 &&(!tPT.uPT1DX.bFlag.bPTYC); // 无TV异常 poc->psta2.bFlag.bFXB=poc->psta2.bFlag.bQDB // A相电流启动 &&(bfx) //反方向 &&pSet->bTT_DIR //功率方向投入 &&(!tPT.uPT1DX.bFlag.bPTYC); // 无TV异常 poc->psta2.bFlag.bWXB=poc->psta2.bFlag.bQDB // A相电流启动 &&(!pSet->bTT_DIR||tPT.uPT1DX.bFlag.bPTYC); // 功率方向退出或功率方向投入,PT异常退方向) #endif } // C相电流方向判断 void GOc_dir_phC(int sw) { TGOC_T *poc=&g_tRelay[ sw].tgoc; GOC_SET *pSet = &pRunSet->tSwSet[sw].tGocSet; int indexI; bool bzx,bfx; u32 dIgl,dIgl_fh; dIgl=pSet->dIgl; dIgl_fh=pSet->dIgl_fh; indexI=UI_SW_INDEX(sw,SW_AC_IC); poc->psta.bFlag.bQDC = OverRelay(g_ui[indexI ].m2[0], dIgl, dIgl_fh, poc->psta.bFlag.bQDC); // A相过流启动 bzx=CalDir_C(sw,poc->psta.bFlag.bQDC&&pSet->bTT_DIR,false); bfx=(!bzx)&&poc->psta.bFlag.bQDC&&pSet->bTT_DIR; poc->psta.bFlag.bZXC=poc->psta.bFlag.bQDC // A相电流启动 &&bzx // 正方向 &&pSet->bTT_DIR //功率方向投入 &&(!tPT.uPT1DX.bFlag.bPTYC); // 无TV异常 poc->psta.bFlag.bFXC=poc->psta.bFlag.bQDC // A相电流启动 &&(bfx) //反方向 &&pSet->bTT_DIR //功率方向投入 &&(!tPT.uPT1DX.bFlag.bPTYC); // 无TV异常 poc->psta.bFlag.bWXC=poc->psta.bFlag.bQDC // A相电流启动 &&(!pSet->bTT_DIR||tPT.uPT1DX.bFlag.bPTYC); // 功率方向未投入,或PT异常 #if defined GD_AREA_ZHONGSHAN || defined GD_AREA_ZHONGSHAN_2020 dIgl=pSet->dIgl2; dIgl_fh=pSet->dIgl2_fh; poc->psta2.bFlag.bQDC = OverRelay(g_ui[indexI ].m2[0], dIgl, dIgl_fh, poc->psta2.bFlag.bQDC); // A相过流启动 bzx=CalDir_C(sw,poc->psta2.bFlag.bQDC&&pSet->bTT_DIR,false); bfx=(!bzx)&&poc->psta2.bFlag.bQDC&&pSet->bTT_DIR; poc->psta2.bFlag.bZXC=poc->psta2.bFlag.bQDC // A相电流启动 &&bzx // 正方向 &&pSet->bTT_DIR //功率方向投入 &&(!tPT.uPT1DX.bFlag.bPTYC); // 无TV异常 poc->psta2.bFlag.bFXC=poc->psta2.bFlag.bQDC // A相电流启动 &&(bfx) //反方向 &&pSet->bTT_DIR //功率方向投入 &&(!tPT.uPT1DX.bFlag.bPTYC); // 无TV异常 poc->psta2.bFlag.bWXC=poc->psta2.bFlag.bQDC // A相电流启动 &&(!pSet->bTT_DIR||tPT.uPT1DX.bFlag.bPTYC); // 功率方向未投入,或PT异常 #endif } void GOc_lx_check(int sw) { TGOC_T *poc=&g_tRelay[ sw].tgoc; GOC_SET *pSet = &pRunSet->tSwSet[sw].tGocSet; int indexI; indexI=UI_SW_INDEX(sw,SW_AC_I0); poc->psta.bFlag.bQDLX = OverRelay(g_ui[indexI ].m2[0], pSet->dIlx, pSet->dIlx_fh, poc->psta.bFlag.bQDLX); //零序启动 } bool GOC_bh_all(int sw) { int i; for(i=BH_GL1;i<=FA_LX2;i++) { if(g_tRelay[sw].tOC[i].sta.bFlag.bQD)return true; } return false; } void GOC_dir_check(int sw,u32 dStep) { bool bY1; TGOC_T *poc=&g_tRelay[ sw].tgoc; GOc_dir_phA(sw); GOc_dir_phB(sw); GOc_dir_phC(sw); GOc_lx_check(sw); //正方向判断,保持2秒 bY1=(poc->psta.bFlag.bZXA||poc->psta.bFlag.bZXB||poc->psta.bFlag.bZXC)&&(!poc->sta.bFlag.bXBbs)&&BH_GOOSE_EN_YB(sw); RunTR(&poc->tTZX_300ms, bY1, dStep); poc->psta.bFlag.bZX=poc->tTZX_300ms.boolTrip; //反方向判断,保持2秒 bY1=(poc->psta.bFlag.bFXA||poc->psta.bFlag.bFXB||poc->psta.bFlag.bFXC)&&(!poc->sta.bFlag.bXBbs)&&BH_GOOSE_EN_YB(sw); RunTR(&poc->tTFX_300ms, bY1, dStep); poc->psta.bFlag.bFX=poc->tTFX_300ms.boolTrip; //无方向判断,保持2秒 bY1=(poc->psta.bFlag.bWXA||poc->psta.bFlag.bWXB||poc->psta.bFlag.bWXC)&&(!poc->sta.bFlag.bXBbs)&&BH_GOOSE_EN_YB(sw); RunTR(&poc->tTWX_300ms, bY1, dStep); poc->psta.bFlag.bWX=poc->tTWX_300ms.boolTrip; //零序判断,保持2秒 bY1=poc->psta.bFlag.bQDLX&&BH_GOOSE_EN_YB(sw); RunTR(&poc->tTLX_300ms, bY1, dStep); poc->psta.bFlag.bLX=poc->tTLX_300ms.boolTrip; //过流闭锁 bY1=(GOC_bh_all(sw)&&pRunSet->bTT_fhkg_pub); //负荷开关 RunTR(&poc->tTGLBS_300ms, bY1, dStep); poc->psta.bFlag.bGLBS=poc->tTGLBS_300ms.boolTrip; poc->psta.bFlag.bGZ=poc->psta.bFlag.bZX|poc->psta.bFlag.bFX|poc->psta.bFlag.bWX|poc->psta.bFlag.bLX; //线路有故障 #if defined GD_AREA_ZHONGSHAN || defined GD_AREA_ZHONGSHAN_2020 //正方向判断,保持2秒 bY1=(poc->psta2.bFlag.bZXA||poc->psta2.bFlag.bZXB||poc->psta2.bFlag.bZXC)&&(!poc->sta.bFlag.bXBbs2)&&BH_GOOSE_EN_YB(sw); RunTR(&poc->tTZX2_300ms, bY1, dStep); poc->psta2.bFlag.bZX=poc->tTZX2_300ms.boolTrip; //反方向判断,保持2秒 bY1=(poc->psta2.bFlag.bFXA||poc->psta2.bFlag.bFXB||poc->psta2.bFlag.bFXC)&&(!poc->sta.bFlag.bXBbs2)&&BH_GOOSE_EN_YB(sw); RunTR(&poc->tTFX2_300ms, bY1, dStep); poc->psta2.bFlag.bFX=poc->tTFX2_300ms.boolTrip; //无方向判断,保持2秒 bY1=(poc->psta2.bFlag.bWXA||poc->psta2.bFlag.bWXB||poc->psta2.bFlag.bWXC)&&(!poc->sta.bFlag.bXBbs2)&&BH_GOOSE_EN_YB(sw); RunTR(&poc->tTWX2_300ms, bY1, dStep); poc->psta2.bFlag.bWX=poc->tTWX2_300ms.boolTrip; poc->psta2.bFlag.bGZ=poc->psta2.bFlag.bZX|poc->psta2.bFlag.bFX|poc->psta2.bFlag.bWX|poc->psta2.bFlag.bLX; //线路有故障 poc->psta.bFlag.bGZ|=poc->psta2.bFlag.bGZ; #endif } bool fag_goosecheck_gzqc(int sw) //故障切除邻域故障信息判断 { TGOC_T *poc=&g_tRelay[ sw].tgoc; TSETSW *pSet = &pRunSet->tSwSet[sw]; UGOOSE_STU *pg; int i; if(pSet->tGocSet.bTT_DIR&&(!tPT.uPT1DX.bFlag.bPTYC))// 带方向判断 { if(poc->psta.bFlag.bZX) //本线路有正向故障,L邻域 { bool bY1=false; for(i=GOOSE_EQU_SIDE;ibFlag.bfx; // L邻域 有反向故障 } return (!bY1); } if(poc->psta.bFlag.bFX) //本线路有反向故障, B邻域 无正向向故障 { bool bY1=false; for(i=0;ibFlag.bzx; // B邻域 正向向故障 } return (!bY1); } return false; } #if defined GD_AREA_ZHONGSHAN || defined GD_AREA_ZHONGSHAN_2020 || defined GD_AREA_MAIN_2020 if(poc->psta.bFlag.bWX||poc->psta2.bFlag.bWX||poc->psta.bFlag.bLX) //本线路有无方向故障 ,或零序故障 #else if(poc->psta.bFlag.bWX||poc->psta.bFlag.bLX) //本线路有无方向故障 ,或零序故障 #endif { bool bY1=false; bool bY2=false; bool ret=false; for(i=0;ibFlag.bgl|pg->bFlag.blx|pg->bFlag.bzx|pg->bFlag.bfx|pg->bFlag.bglbs|pg->bFlag.blxbs); } for(i=GOOSE_EQU_SIDE;ibFlag.bgl|pg->bFlag.blx|pg->bFlag.bzx|pg->bFlag.bfx|pg->bFlag.bglbs|pg->bFlag.blxbs); } if(pRunSet->tSwSet[sw].tGocSet.bsw_fz) //末端开关 { ret=(bY1||bY2) ; // 末端开关,邻域有故障 } else if(pRunSet->tSwSet[sw].tGocSet.bsw_sd) //首端开关 { ret=(!(bY1||bY2)); //任一侧有故障(首开关) } else { ret=(bY1^bY2); //非首末端,邻域有一侧无故障 } return ret; } return false; } bool fag_goosecheck_gzgl(int sw) //故障隔离邻域故障信息判断 { TSETSW *pSet = &pRunSet->tSwSet[sw]; UGOOSE_STU *pg; int i; if(pSet->tGocSet.bTT_DIR&&(!tPT.uPT1DX.bFlag.bPTYC)) { return false; //合环方式下,无故障隔离故障产生 } else { bool bY1=false; int num=0; for(i=0;ibFlag.bgl|pg->bFlag.blx|pg->bFlag.bzx|pg->bFlag.bfx|pg->bFlag.bglbs|pg->bFlag.blxbs); if(bY1) { num++; } } return (num==1); } return false; } bool fag_goosecheck_ll(int sw) // 联络开关动作,邻域条件判断 { int i; UGOOSE_STU *pg; bool bgzglok=false; TSETSW *pSet = &pRunSet->tSwSet[sw]; if(pSet->tGocSet.bTT_DIR&&(!tPT.uPT1DX.bFlag.bPTYC))// 带方向判断,无故障隔离发送,条件自动满足 { bgzglok=true; } else { for(i=0;ibFlag.bgzglok; //收到故障隔离成功信息 } } return bgzglok; } void fag_get_side_dz(int sw) //获取相邻侧故障信息 { TGOC_T *poc=&g_tRelay[ sw].tgoc; UGOOSE_STU *pg; bool bdz=false; bool btzsb=false; int i; for(i=0;ibFlag.bgl||pg->bFlag.blx||pg->bFlag.bzx||pg->bFlag.bfx|pg->bFlag.bglbs|pg->bFlag.blxbs); btzsb|=pg->bFlag.btzsb; } poc->b_side_gz=bdz; poc->b_side_tzsb=btzsb; } void fag_cd(int sw,DWORD dStep) // { TRELAY_T *pR=&g_tRelay[sw]; TGOC_T *poc=&g_tRelay[ sw].tgoc; TSETSW *pSet = &pRunSet->tSwSet[sw]; FA_CD *pcd; bool bQD; bool bY1; fag_get_side_dz(sw); // 获取开关临域信息 poc->psta.bFlag.bYY1 = OverRelay(g_sw_pub.m2_max[2], pSet->dU_fa_YY,pSet->dU_fa_YY_fh, poc->psta.bFlag.bYY1); // 有压 poc->psta.bFlag.bYY2 = OverRelay(g_sw_pub.m2_max[3], pSet->dU_fa_YY,pSet->dU_fa_YY_fh, poc->psta.bFlag.bYY2); poc->psta.bFlag.bWY1 = LowRelay(g_sw_pub.m2_max[2], pSet->dU_fa_WY,pSet->dU_fa_WY_fh, poc->psta.bFlag.bWY1); //无压 poc->psta.bFlag.bWY2 = LowRelay(g_sw_pub.m2_max[3], pSet->dU_fa_WY,pSet->dU_fa_WY_fh, poc->psta.bFlag.bWY2); // 故障切除充电判断 pcd=&pR->tgoc.tqccd; RunTR(&pcd->tWYTime, (poc->psta.bFlag.bWY1&&poc->psta.bFlag.bWY2), dStep); // 放电两侧无压60秒 pcd->sta.bFlag.bFD=(!BH_GOOSE_EN(sw)) // 分布式退出 || pR->tSWST.uSWST.bFlag.bTZWZ //开关跳位 ||pcd->tWYTime.boolTrip; // 两侧无压超过60秒 bQD=(BH_GOOSE_EN(sw)) //&&!poc->b_side_gz //邻域无故障 //&&!poc->psta.bFlag.bGZ //本开关无故障 &&(poc->psta.bFlag.bYY1||poc->psta.bFlag.bYY2||(pRunSet->dT_cd==0)) //一侧有电压 && pR->tSWST.uSWST.bFlag.bHZWZ &&!pcd->sta.bFlag.bFD; RunTR(&pcd->tCDTime, bQD, dStep); pcd->sta.bFlag.bCD=(pcd->tCDTime.boolTrip||pcd->sta.bFlag.bCD)&&(!pcd->sta.bFlag.bFD); //充电完成 pR->run_stu.goose_qccd=pcd->sta.bFlag.bCD; // 隔离充电判断 pcd=&pR->tgoc.tglcd; RunTR(&pcd->tWYTime, (poc->psta.bFlag.bWY1&&poc->psta.bFlag.bWY2), dStep); // 放电两侧无压60秒 pcd->sta.bFlag.bFD=(!BH_GOOSE_EN(sw)) // 分布式退出 || pR->tSWST.uSWST.bFlag.bTZWZ //开关跳位 ||poc->psta.bFlag.bGZ //本开关有故障,故障隔离立即放电 ||pcd->tWYTime.boolTrip; // 两侧无压超过60秒 bQD=(BH_GOOSE_EN(sw)) &&!poc->b_side_gz //邻域无故障 &&!poc->psta.bFlag.bGZ //本开关无故障 &&(poc->psta.bFlag.bYY1||poc->psta.bFlag.bYY2||(pRunSet->dT_cd==0)) //一侧有电压 && pR->tSWST.uSWST.bFlag.bHZWZ &&!pcd->sta.bFlag.bFD; RunTR(&pcd->tCDTime, bQD, dStep); pcd->sta.bFlag.bCD=(pcd->tCDTime.boolTrip||pcd->sta.bFlag.bCD)&&(!pcd->sta.bFlag.bFD); //充电完成 pR->run_stu.goose_glcd=pcd->sta.bFlag.bCD; //联络充电判断 pcd=&pR->tgoc.tllcd; RunTR(&pcd->tWYTime, (poc->psta.bFlag.bWY1&&poc->psta.bFlag.bWY2), dStep); //无压判断 pcd->sta.bFlag.bFD=(!BH_GOOSE_EN(sw)) // 分布式退出 ||!pSet->tGocSet.bTT_ll //联络功能退出 //#if defined GD_AREA_ZHONGSHAN || defined GD_AREA_ZHONGSHAN_2020 //中山要求联络开关固定 #if defined GD_AREA_ZHONGSHAN //中山要求联络开关固定 ||!pSet->tGocSet.bsw_ll #endif ||pcd->tWYTime.boolTrip // 两侧无压超过15秒 ||poc->b_side_gz //领域故障 ||pR->tgoc.b_side_tzsb//领域拒动 //||!g_run_stu.yf //KK把手非远方 ||poc->sta.bFlag.bllhz; //本开关联络动作 bQD=(BH_GOOSE_EN(sw)) //充电条件:保护投入 &&(poc->psta.bFlag.bYY1&&poc->psta.bFlag.bYY2) //两侧有压 && pR->tSWST.uSWST.bFlag.bTZWZ // 开关跳位 &&!pcd->sta.bFlag.bFD; //无放电 RunTR(&pcd->tCDTime, bQD, dStep); pcd->sta.bFlag.bCD=(pcd->tCDTime.boolTrip||pcd->sta.bFlag.bCD) //充电完成,并自保持 &&(!pcd->sta.bFlag.bFD); //无放电标志 pR->run_stu.goose_ll_cd=pcd->sta.bFlag.bCD; //充电标志 //缓动型无压无流判断 poc->bslowEn=(!pSet->tGocSet.bFA_slow) ||(pSet->tGocSet.bFA_slow //缓动型 &&poc->psta.bFlag.bWY1 //无压 &&poc->psta.bFlag.bWY2 &&pR->tSWST.uSWST.bFlag.bSXWL); //无流 bY1=soe_check(EV_GOOSE_GZBS_FA)||soe_check(EV_GOOSE_TZBS_FA); RunTR(&poc->tTHz1s,pR->tSWST.uSWST.bFlag.bHZWZ&&bY1, dStep); //合闸后1秒,清动作标志 if(poc->tTHz1s.boolTrip&&BH_GOOSE_EN(sw)) { pR->tgoc.bgooseGz=false; pR->tgoc.bgooseBsHz=false; if(soe_check(EV_GOOSE_GZBS_FA)==true) // goose故障闭锁 { soe_record_ev(EV_GOOSE_GZBS_FA, 0, 0,0,0 ); } if(soe_check(EV_GOOSE_TZBS_FA)==true) // goose故障闭锁 { soe_record_ev(EV_GOOSE_TZBS_FA, 0, 0,0,0 ); } } } void fag_oc_gl(int sw,u32 dStep) { TGOC_T *poc=&g_tRelay[ sw].tgoc; GOC_SET *pSet = &pRunSet->tSwSet[sw].tGocSet; bool bgl,bGoose,bTz; // 电流启动 bgl = OverRelay(g_sw[sw].m2_max, pSet->dIgl, pSet->dIgl_fh, poc->sta.bFlag.bglQD); bGoose=(fag_goosecheck_gzqc(sw))||(tFAg.commerr>0); //goose判断满足要求,中山通信异常后,BH_GOOSE_EN 不满足要求,不会启动 poc->sta.bFlag.bglQD= (BH_GOOSE_EN(sw) &&poc->tqccd.sta.bFlag.bCD //故障隔离充电完成 && (bgl) #if defined GD_AREA_ZHONGSHAN || defined GD_AREA_ZHONGSHAN_2020 //中山要求联络开关固定 &&(!pSet->bsw_fz) // 中山局要求分支走常规保护逻辑 #endif &&!poc->sta.bFlag.bXBbs); //谐波闭锁 if(poc->sta.bFlag.bglQD) //幅值启动 { if(!poc->sta.bFlag.bglQDWave) { rcd_start(sw,RECORD_TYPE_GLGZ, RECORD_LEN_TZQD); //录波类型:跳闸类 poc->sta.bFlag.bglQDWave=true; } } RunTR(&poc->tglQDTime, poc->sta.bFlag.bglQD, dStep); RunTR(&poc->tglQD25ms, poc->sta.bFlag.bglQD, dStep); // 如果速断时间到,启动时间未到,调用幅值启动加速模块 if(poc->sta.bFlag.bglQD&& poc->tglQDTime.boolTrip && !poc->tglQD25ms.boolTrip) { if(protect_amp_qd_js(sw)) { // 预置25ms,让下个循环再出口 PreSetTime(&poc->tglQD25ms, T_25ms); } } bTz = poc->tglQDTime.boolTrip&&bGoose // 电流启动 && poc->tglQD25ms.boolTrip; //启动后25ms RunTR(&poc->tglslowTime,(bTz&&pSet->bFA_slow), dStep); // 缓动型,跳闸信息自动延长 poc->sta.bFlag.bglTz=(bTz&&(!pSet->bFA_slow))// 非缓动型,直接出口 ||(poc->bslowEn&&poc->tglslowTime.boolTrip); if(poc->sta.bFlag.bglTz) //启动信息 { int ui_begin; DWORD Ia,Ib,Ic; ui_begin = UI_SW_INDEX_BEGIN(sw); Ia = _Mul_Div_U(sqrt_32fix(g_ui[ui_begin + SW_AC_IA].m2[0]), 256, g_ui[ui_begin + SW_AC_IA].m2_factor_k); Ib = _Mul_Div_U(sqrt_32fix(g_ui[ui_begin + SW_AC_IB].m2[0]), 256, g_ui[ui_begin + SW_AC_IB].m2_factor_k); Ic = _Mul_Div_U(sqrt_32fix(g_ui[ui_begin + SW_AC_IC].m2[0]), 256, g_ui[ui_begin + SW_AC_IC].m2_factor_k); if(soe_check(EV_GOOSE_GL_TZ+sw*EV_SW_NUM)==false) //过流跳闸 { soe_record_ev( EV_GOOSE_GL_TZ+sw*EV_SW_NUM,1, Ia,Ib,Ic ); poc->bglTzLed=true; poc->sta.bFlag.bglTzH=true; poc->bgooseGz=true; } if(soe_check(EV_GOOSE_QC_QD+sw*EV_SW_NUM)==false) // 故障隔离启动 { soe_record_ev( EV_GOOSE_QC_QD+sw*EV_SW_NUM,1, 0,0,0 ); } } else { if(soe_check(EV_GOOSE_GL_TZ+sw*EV_SW_NUM)==true) // 过流跳闸 { soe_record_ev( EV_GOOSE_GL_TZ+sw*EV_SW_NUM,0, 0,0,0 ); } } #if defined GD_AREA_ZHONGSHAN || defined GD_AREA_ZHONGSHAN_2020 // 电流启动 bgl = OverRelay(g_sw[sw].m2_max, pSet->dIgl2, pSet->dIgl2_fh, poc->sta.bFlag.bgl2QD); bGoose=(fag_goosecheck_gzqc(sw))||(tFAg.commerr>0); //goose判断满足要求,或通信异常 poc->sta.bFlag.bgl2QD= (BH_GOOSE_EN(sw) &&poc->tqccd.sta.bFlag.bCD //故障隔离充电完成 && (bgl) &&(!pSet->bsw_fz) // 中山局要求分支走常规保护逻辑 &&!poc->sta.bFlag.bXBbs2); //谐波闭锁 if(poc->sta.bFlag.bgl2QD) //幅值启动 { if(!poc->sta.bFlag.bgl2QDWave) { rcd_start(sw,RECORD_TYPE_GLGZ, RECORD_LEN_TZQD); //录波类型:跳闸类 poc->sta.bFlag.bgl2QDWave=true; } } RunTR(&poc->tgl2QDTime, poc->sta.bFlag.bgl2QD, dStep); RunTR(&poc->tgl2QD25ms, poc->sta.bFlag.bgl2QD, dStep); // 如果速断时间到,启动时间未到,调用幅值启动加速模块 if(poc->sta.bFlag.bgl2QD && poc->tgl2QDTime.boolTrip && !poc->tgl2QD25ms.boolTrip) { if(protect_amp_qd_js(sw)) { // 预置25ms,让下个循环再出口 PreSetTime(&poc->tgl2QD25ms, T_25ms); } } bTz = poc->tgl2QDTime.boolTrip&&bGoose // 电流启动 && poc->tgl2QD25ms.boolTrip; //启动后25ms RunTR(&poc->tgl2slowTime,(bTz&&pSet->bFA_slow), dStep); // 缓动型,跳闸信息自动延长 poc->sta.bFlag.bgl2Tz=(bTz&&(!pSet->bFA_slow))// 非缓动型,直接出口 ||(poc->bslowEn&&poc->tgl2slowTime.boolTrip); if(poc->sta.bFlag.bgl2Tz) //启动信息 { int ui_begin; DWORD Ia,Ib,Ic; ui_begin = UI_SW_INDEX_BEGIN(sw); Ia = _Mul_Div_U(sqrt_32fix(g_ui[ui_begin + SW_AC_IA].m2[0]), 256, g_ui[ui_begin + SW_AC_IA].m2_factor_k); Ib = _Mul_Div_U(sqrt_32fix(g_ui[ui_begin + SW_AC_IB].m2[0]), 256, g_ui[ui_begin + SW_AC_IB].m2_factor_k); Ic = _Mul_Div_U(sqrt_32fix(g_ui[ui_begin + SW_AC_IC].m2[0]), 256, g_ui[ui_begin + SW_AC_IC].m2_factor_k); if(soe_check(EV_GOOSE_GL2_TZ+sw*EV_SW_NUM)==false) //过流跳闸 { soe_record_ev( EV_GOOSE_GL2_TZ+sw*EV_SW_NUM,1, Ia,Ib,Ic ); poc->bglTzLed=true; poc->sta.bFlag.bglTzH=true; poc->bgooseGz=true; } if(soe_check(EV_GOOSE_QC_QD+sw*EV_SW_NUM)==false) // 故障隔离启动 { soe_record_ev( EV_GOOSE_QC_QD+sw*EV_SW_NUM,1, 0,0,0 ); } } else { if(soe_check(EV_GOOSE_GL2_TZ+sw*EV_SW_NUM)==true) // 过流跳闸 { soe_record_ev( EV_GOOSE_GL2_TZ+sw*EV_SW_NUM,0, 0,0,0 ); } } #endif } void fag_oc_lx(int sw,u32 dStep) { TGOC_T *poc=&g_tRelay[ sw].tgoc; GOC_SET *pSet = &pRunSet->tSwSet[sw].tGocSet; bool blx,bGoose,bTz; // 电流启动 blx = OverRelay(g_ui[UI_SW_INDEX(sw,SW_AC_I0)].m2[0], pSet->dIlx, pSet->dIlx_fh, poc->sta.bFlag.blxQD); bGoose=(fag_goosecheck_gzqc(sw))||(tFAg.commerr>0); //goose判断满足要求,或通信异常 poc->sta.bFlag.blxQD = (BH_GOOSE_EN(sw) &&poc->tqccd.sta.bFlag.bCD //故障隔离充电完成 #if defined GD_AREA_ZHONGSHAN || defined GD_AREA_ZHONGSHAN_2020 //中山要求联络开关固定 &&(!pSet->bsw_fz) // 中山局要求分支走常规保护逻辑 #endif && (blx)); if(poc->sta.bFlag.blxQD) //幅值启动 { if(!poc->sta.bFlag.blxQDWave) { rcd_start(sw,RECORD_TYPE_LXGL, RECORD_LEN_TZQD); //录波类型:跳闸类 poc->sta.bFlag.blxQDWave=true; } } RunTR(&poc->tlxQDTime, poc->sta.bFlag.blxQD, dStep); RunTR(&poc->tlxQD25ms, poc->sta.bFlag.blxQD, dStep); // 如果速断时间到,启动时间未到,调用幅值启动加速模块 if(poc->sta.bFlag.blxQD && poc->tlxQDTime.boolTrip && !poc->tlxQD25ms.boolTrip) { if(protect_amp_lx_js(sw)) { // 预置25ms,让下个循环再出口 PreSetTime(&poc->tlxQD25ms, T_25ms); } } bTz = poc->tlxQDTime.boolTrip&&bGoose // 电流启动 && poc->tlxQD25ms.boolTrip; //启动后25ms RunTR(&poc->tlxslowTime,(bTz&&pSet->bFA_slow), dStep); // 缓动型,跳闸信息自动延长 poc->sta.bFlag.blxTz=(bTz&&(!pSet->bFA_slow))// 非缓动型,直接出口 ||(poc->bslowEn&&poc->tlxslowTime.boolTrip); if(poc->sta.bFlag.blxTz) //启动信息 { int ui_begin; DWORD I0; ui_begin = UI_SW_INDEX_BEGIN(sw); I0= _Mul_Div_U(sqrt_32fix(g_ui[ui_begin + SW_AC_I0].m2[0]), 256, g_ui[ui_begin + SW_AC_I0].m2_factor_k); if(soe_check(EV_GOOSE_LX_TZ+sw*EV_SW_NUM)==false) //零序跳闸 { soe_record_ev( EV_GOOSE_LX_TZ+sw*EV_SW_NUM,1, I0,0,0 ); poc->blxTzLed=true; poc->sta.bFlag.blxTzH=true; poc->bgooseGz=true; } if(soe_check(EV_GOOSE_QC_QD+sw*EV_SW_NUM)==false) // 故障切除启动 { soe_record_ev( EV_GOOSE_QC_QD+sw*EV_SW_NUM,1, 0,0,0 ); } } else { if(soe_check(EV_GOOSE_LX_TZ+sw*EV_SW_NUM)==true) // 零序跳闸 { soe_record_ev( EV_GOOSE_LX_TZ+sw*EV_SW_NUM,0, 0,0,0 ); } } } // 缓动型故障扩展发送时间,需大于变电站出口时间,保证无压无流后,领域故障还存在 void fag_gzgl(int sw,DWORD dStep) // 故障隔离 { TRELAY_T *pR=&g_tRelay[sw]; GOC_SET *pSet = &pRunSet->tSwSet[sw].tGocSet; TGOC_T *poc=&pR->tgoc; UGOOSE_STU *pg; bool bY1,bY2,bGoose,bfztz; int i; bool bWY1, bWY2; // 无压判断 bWY1 = LowRelay(g_sw_pub.m2_max[2], pRunSet->tSwSet[sw].dU_fa_WY,pRunSet->tSwSet[sw].dU_fa_WY_fh, false); //无压 bWY2 = LowRelay(g_sw_pub.m2_max[3], pRunSet->tSwSet[sw].dU_fa_WY,pRunSet->tSwSet[sw].dU_fa_WY_fh, false); bY1=false; for(i=0;ibFlag.bgl|pg->bFlag.blx|pg->bFlag.bzx|pg->bFlag.bfx|pg->bFlag.bglbs|pg->bFlag.blxbs); } bfztz=(!pSet->bsw_fz)||pSet->bTT_mxTfz; //非分支或分支线且母线故障跳分支未投入 bY2=(BH_GOOSE_EN(sw)) &&bfztz &&bY1 // 邻域有故障产生 &&poc->bslowEn //缓动型,需无压无流,速动自动满足 && pR->tSWST.uSWST.bFlag.bHZWZ //在合闸位置 &&pR->tgoc.tglcd.sta.bFlag.bCD; //充电完成,无放电条件 RunTR(&poc->tgoose15ms_gzgl, bY2, dStep); // 电流启动 15ms后,goose 判断有效 bGoose=fag_goosecheck_gzgl(sw) &&poc->tgoose15ms_gzgl.boolTrip &&(tFAg.commerr==0); // 故障隔离,通信正常时处理,异常,靠失压跳闸 if(poc->tgoose15ms_gzgl.boolTrip&&!poc->sta.bFlag.bgzglQD) //goose 判断时间到,若条件不满足,放电,防止邻域开关故障撤销后,由于发送间隔问题,goose条件又满足导致误动 { if(!bGoose) //外部条件不满足 { pR->tgoc.tglcd.sta.bFlag.bCD=false; ResetTR(&poc->tglcd.tCDTime); } } #ifdef GD_AREA_ZHONGSHAN_2020 // 中山要求,动作后,通信异常不起作用,继续动作 poc->sta.bFlag.bgzglQD=((bGoose&&bY2)||poc->sta.bFlag.bgzglQD)&&bWY1&&bWY2; //故障隔离启动, 增加无压条件 #else poc->sta.bFlag.bgzglQD=((bGoose&&bY2)||poc->sta.bFlag.bgzglQD)&&pR->tgoc.tglcd.sta.bFlag.bCD&&bWY1&&bWY2; //故障隔离启动, 增加无压条件 #endif RunTR(&poc->tgzglTime,poc->sta.bFlag.bgzglQD, dStep); // 故障隔离时间到,出口 poc->sta.bFlag.bgzglTz=poc->tgzglTime.boolTrip; //故障隔离启动 if(poc->sta.bFlag.bgzglTz) { if(soe_check(EV_GOOSE_GL_QD+sw*EV_SW_NUM)==false) // 故障隔离启动 { soe_record_ev( EV_GOOSE_GL_QD+sw*EV_SW_NUM,1, 0,0,0 ); } poc->bgzglTzLed=true; poc->sta.bFlag.bgzglTzH=true; poc->sta.bFlag.bgzglQD=false; poc->bgooseGz=true; } } void fag_lostvol_sd(int sw,DWORD dStep) // 首端开关失压跳闸 { TRELAY_T *pR=&g_tRelay[sw]; TGOC_T*poc = &pR->tgoc; GOC_SET *pSet = &pRunSet->tSwSet[sw].tGocSet; bool bWY1, bWY2,bEnble; /***********启动 **********************************/ bWY1 = LowRelay(g_sw_pub.m2_max[2], pRunSet->tSwSet[sw].dU_fa_WY,pRunSet->tSwSet[sw].dU_fa_WY_fh, poc->sta.bFlag.bsdQD); //无压 bWY2 = LowRelay(g_sw_pub.m2_max[3], pRunSet->tSwSet[sw].dU_fa_WY,pRunSet->tSwSet[sw].dU_fa_WY_fh, poc->sta.bFlag.bsdQD); #ifdef GD_AREA_ZHONGSHAN_2020 // 中山要求,动作后,通信异常不起作用,继续动作 bEnble=(pSet->bTT_sdlost&&pSet->bsw_sd) ; //首端开关,失压投退投入,无通信异常 poc->sta.bFlag.bsdQD = bEnble && (BH_GOOSE_EN_YB(sw)) &&(tFAg.bComErr==0||poc->sta.bFlag.bsdQD) && pR->tgoc.psta.bFlag.bCYY // 曾有压 && pR->tSWST.uSWST.bFlag.bHZWZ //在合闸位置 && pR->tSWST.uSWST.bFlag.bSXWL //三相无流; &&(poc->tqccd.sta.bFlag.bCD||poc->sta.bFlag.bsdQD) && bWY1 && bWY2; #else bEnble=(pSet->bTT_sdlost&&pSet->bsw_sd&&(tFAg.commerr==0)) ; //首端开关,失压投退投入,无通信异常 poc->sta.bFlag.bsdQD = bEnble && (BH_GOOSE_EN(sw)) && pR->tgoc.psta.bFlag.bCYY // 曾有压 && pR->tSWST.uSWST.bFlag.bHZWZ //在合闸位置 && pR->tSWST.uSWST.bFlag.bSXWL //三相无流; &&poc->tqccd.sta.bFlag.bCD && bWY1 && bWY2; #endif /***********失压分闸*********************************/ RunTR(&poc->tsdlostTime, poc->sta.bFlag.bsdQD, dStep); poc->sta.bFlag.bsdTz = poc->tsdlostTime.boolTrip; if(poc->sta.bFlag.bsdTz) //启动信息 { if(soe_check(EV_GOOSE_SDLOST_TZ+sw*EV_SW_NUM)==false) // 故障隔离启动 { soe_record_ev( EV_GOOSE_SDLOST_TZ+sw*EV_SW_NUM,1, 0,0,0 ); } if(soe_check(EV_GOOSE_GL_QD+sw*EV_SW_NUM)==false) // 故障隔离启动 { soe_record_ev( EV_GOOSE_GL_QD+sw*EV_SW_NUM,1, 0,0,0 ); } poc->bsdTzLed=true; poc->sta.bFlag.bsdTzH=true; pR->tgoc.psta.bFlag.bCYY =false; poc->bgooseGz=true; ResetTR(&pR->tgoc.tCYY3sdelayms); } else { if(soe_check(EV_GOOSE_SDLOST_TZ+sw*EV_SW_NUM)==true) // 故障隔离启动 { soe_record_ev( EV_GOOSE_SDLOST_TZ+sw*EV_SW_NUM,0, 0,0,0 ); } } } void fag_lostvol_commer(int sw,DWORD dStep) // 通信异常失压跳闸 { TRELAY_T *pR=&g_tRelay[sw]; GOC_SET *pSet = &pRunSet->tSwSet[sw].tGocSet; TGOC_T*poc = &pR->tgoc; bool bWY1, bWY2,bEnble; bool bfztz; /***********启动 **********************************/ bWY1 = LowRelay(g_sw_pub.m2_max[2], pRunSet->tSwSet[sw].dU_fa_WY,pRunSet->tSwSet[sw].dU_fa_WY_fh, poc->sta.bFlag.berrQD); //无压 bWY2 = LowRelay(g_sw_pub.m2_max[3], pRunSet->tSwSet[sw].dU_fa_WY,pRunSet->tSwSet[sw].dU_fa_WY_fh, poc->sta.bFlag.berrQD); bEnble=(tFAg.commerr>0) ; //通信异常,失压跳闸 bfztz=(!pSet->bsw_fz)||pSet->bTT_mxTfz; //非分支或分支线且母线故障跳分支未投入 poc->sta.bFlag.berrQD = bEnble &&bfztz && (BH_GOOSE_EN(sw)) && pR->tgoc.psta.bFlag.bCYY // 曾有压 && pR->tSWST.uSWST.bFlag.bHZWZ //在合闸位置 && pR->tSWST.uSWST.bFlag.bSXWL //三相无流; && bWY1 && bWY2; /***********失压分闸*********************************/ RunTR(&poc->terrlostTime, poc->sta.bFlag.berrQD, dStep); poc->sta.bFlag.berrTz = poc->terrlostTime.boolTrip; if(poc->sta.bFlag.berrTz) //启动信息 { if(soe_check(EV_GOOSE_ERRLOST_TZ+sw*EV_SW_NUM)==false) //失压跳闸 { soe_record_ev( EV_GOOSE_ERRLOST_TZ+sw*EV_SW_NUM,1, 0,0,0 ); } if(soe_check(EV_GOOSE_GL_QD+sw*EV_SW_NUM)==false) // 故障隔离启动 { soe_record_ev( EV_GOOSE_GL_QD+sw*EV_SW_NUM,1, 0,0,0 ); } poc->berrTzLed=true; poc->sta.bFlag.berrTzH=true; pR->tgoc.psta.bFlag.bCYY =false; poc->bgooseGz=true; ResetTR(&pR->tgoc.tCYY3sdelayms); } else { if(soe_check(EV_GOOSE_ERRLOST_TZ+sw*EV_SW_NUM)==true) //失压跳闸 { soe_record_ev( EV_GOOSE_ERRLOST_TZ+sw*EV_SW_NUM,0, 0,0,0 ); } } } void fag_exttz(int sw,DWORD dStep) // 下级开关跳闸失败,本级开关跳闸 { TGOC_T *poc=&g_tRelay[ sw].tgoc; GOC_SET *pSet = &pRunSet->tSwSet[sw].tGocSet; UGOOSE_STU *pg; bool btzsb=false; bool bfztz; int i; bool bgzgl; for(i=0;ibFlag.btzsb); // 相邻开关有跳闸失败 } bgzgl=fag_goosecheck_gzgl(sw)&&(!pSet->bsw_sd)&&(!pSet->bsw_fz); bfztz=(!pSet->bsw_fz)||pSet->bTT_mxTfz; //非分支或分支线且母线故障跳分支未投入 RunTR(&poc->textbsTime,btzsb&&bgzgl, dStep); // 缓动型,跳闸信息自动延长 poc->sta.bFlag.bextQD=btzsb //相邻线路有开关跳闸失败 &&!poc->textbsTime.boolTrip &&(tFAg.commerr==0) //通信正常 &&bfztz &&(BH_GOOSE_EN(sw)) &&g_tRelay[ sw].tSWST.uSWST.bFlag.bHZWZ &&poc->bslowEn //缓动 无压无流 速动,自动满足 &&!poc->psta.bFlag.btzsb; poc->sta.bFlag.bextTz=poc->sta.bFlag.bextQD; if(poc->sta.bFlag.bextTz) { if(soe_check(EV_GOOSE_EXT_TZ+sw*EV_SW_NUM)==false) //保护总 { soe_record_ev( EV_GOOSE_EXT_TZ+sw*EV_SW_NUM,1, 0,0,0 ); #ifdef GD_AREA_ZHONGSHAN_2020 g_tRelay[i].run_stu.fgbs=1;//该SOE返回太快,需直接赋值 #endif } poc->sta.bFlag.bextTzH=true; poc->bgooseGz=true; } else { if(soe_check(EV_GOOSE_EXT_TZ+sw*EV_SW_NUM)==true) //保护总 { soe_record_ev( EV_GOOSE_EXT_TZ+sw*EV_SW_NUM,0, 0,0,0 ); } } } // 两侧有压,开关在分位,确认联络开关有效, //单侧失压后,判合闸条件,条件满足,合联络开关,恢复供电,重新确认联络开关位置 void fag_ll(int sw,DWORD dStep) // 联络开关逻辑处理 { TRELAY_T *pR=&g_tRelay[sw]; TSETSW *pSet = &pRunSet->tSwSet[sw]; TGOC_T*poc = &pR->tgoc; bool bY1,bQD; bool bWY1,bWY2; bool bYY1,bYY2,bllYY; bool bLstQD=false; //有压检测 bWY1 = LowRelay(g_sw_pub.m2_max[2], pSet->dU_fa_WY,pSet->dU_fa_WY_fh, poc->psta.bFlag.bllWY1); //无压 bWY2 = LowRelay(g_sw_pub.m2_max[3], pSet->dU_fa_WY,pSet->dU_fa_WY_fh, poc->psta.bFlag.bllWY2); bYY1 = OverRelay(g_sw_pub.m2_max[2], pSet->dU_fa_YY,pSet->dU_fa_YY_fh, poc->psta.bFlag.bYY1); // 有压 bYY2 = OverRelay(g_sw_pub.m2_max[3], pSet->dU_fa_YY,pSet->dU_fa_YY_fh, poc->psta.bFlag.bYY2); RunTR(&poc->tllWY1Time,bWY1, dStep); RunTR(&poc->tllWY2Time,bWY2, dStep); RunTR(&poc->tllYY1Time,bYY1, dStep); RunTR(&poc->tllYY2Time,bYY2, dStep); poc->psta.bFlag.bllWY1 = poc->tllWY1Time.boolTrip; poc->psta.bFlag.bllWY2 = poc->tllWY2Time.boolTrip; #if defined GD_AREA_ZHONGSHAN || defined GD_AREA_ZHONGSHAN_2020 //中山要求联络开关固定,并且单侧失压后报联络合闸失败 bLstQD =pSet->tGocSet.bTT_ll//联络开关投入 &&(BH_GOOSE_EN(sw)) //智能分布式已投入 #ifdef GD_AREA_ZHONGSHAN &&pSet->tGocSet.bsw_ll #endif &&(poc->psta.bFlag.bllWY1^poc->psta.bFlag.bllWY2) //单侧失压 &&pR->tSWST.uSWST.bFlag.bTZWZ; // 开关跳位 #endif bllYY=poc->tllYY1Time.boolTrip&&poc->tllYY2Time.boolTrip; poc->sta.bFlag.bllWY_1=((bLstQD&&bllYY)||poc->sta.bFlag.bllWY_1)&&bLstQD; RunTR(&poc->tllQdTime,poc->sta.bFlag.bllWY_1, dStep); // 双侧有压后,又单侧失压,超过联络合闸时间,报联络合闸不满足 bQD =pSet->tGocSet.bTT_ll//联络开关投入 #ifdef GD_AREA_ZHONGSHAN_2020 //中山要求联络开关固定 &&(poc->tllcd.sta.bFlag.bCD||poc->sta.bFlag.bllQD) //联络开关充电完成 //&&pSet->tGocSet.bsw_ll &&(BH_GOOSE_EN_YB(sw)) //智能分布式已投入 &&(tFAg.bComErr==0||poc->sta.bFlag.bllQD) // 联络启动后,自保持,通信异常不退出动作逻辑 #else &&poc->tllcd.sta.bFlag.bCD //联络开关充电完成 &&(BH_GOOSE_EN(sw)) //智能分布式已投入 #endif &&(poc->psta.bFlag.bllWY1^poc->psta.bFlag.bllWY2) //单侧失压 &&pR->tSWST.uSWST.bFlag.bTZWZ; // 开关跳位 RunTR(&poc->tgoosedelayms_ll, bQD, dStep); // 联络失压后启动 bY1= bQD // 单侧失压,联络启动条件满足 &&(!poc->tgoosedelayms_ll.boolTrip) //在失压后300ms内 &&!poc->b_side_gz //领域无故障 &&fag_goosecheck_ll(sw) ; //收到故障隔离信号 poc->sta.bFlag.bllQD=(bY1||poc->sta.bFlag.bllQD)&&bQD && !poc->b_side_tzsb ; // 联络启动后,自保持 RunTR(&poc->tllhzTime,poc->sta.bFlag.bllQD, dStep); // Y确认时间后,失压可合闸 poc->sta.bFlag.bllhz=poc->tllhzTime.boolTrip; if(poc->sta.bFlag.bllhz) //启动信息 { if(soe_check(EV_GOOSE_HZ_QD+sw*EV_SW_NUM)==false) // 联络合闸启动 { soe_record_ev( EV_GOOSE_HZ_QD+sw*EV_SW_NUM,1, 0,0,0 ); } sw_do(sw,SW_DO_HZ,SW_DO_TYPE_ON); sw_do(sw,SW_DO_BHH,SW_DO_TYPE_ON); poc->sta.bFlag.bllhzH=true; ResetTR(&poc->tllQdTime); poc->sta.bFlag.bllWY_1=false; } else { if(soe_check(EV_GOOSE_HZ_QD+sw*EV_SW_NUM)==true) // 联络合闸启动返回 { soe_record_ev( EV_GOOSE_HZ_QD+sw*EV_SW_NUM,0, 0,0,0 ); } } if(poc->tllQdTime.boolTrip) //联络失压后合闸不满足 { if(soe_check(EV_GOOSE_LL_UNOK+sw*EV_SW_NUM)==false) // { soe_record_ev( EV_GOOSE_LL_UNOK+sw*EV_SW_NUM,1, 0,0,0 ); } ResetTR(&poc->tllQdTime); ResetTR(&poc->tllcd.tCDTime); poc->sta.bFlag.bllWY_1=false; poc->tllcd.sta.bFlag.bCD=false; } if(poc->tllcd.sta.bFlag.bCD||pR->tSWST.uSWST.bFlag.bHZWZ) { if(soe_check(EV_GOOSE_LL_UNOK+sw*EV_SW_NUM)==true) // { soe_record_ev( EV_GOOSE_LL_UNOK+sw*EV_SW_NUM,0, 0,0,0 ); } } RunTR(&poc->tHzcheckTime, poc->sta.bFlag.bllhzH, dStep); // if(poc->tHzcheckTime.boolTrip) //跳闸失败时间到,清标志,报soe { if(pR->tSWST.uSWST.bFlag.bTZWZ) //合闸闸失败 { if(soe_check(EV_GOOSE_HZ_FAIL+sw*EV_SW_NUM)==false) // { soe_record_ev( EV_GOOSE_HZ_FAIL+sw*EV_SW_NUM,1, 0,0,0 ); // 联络合闸失败 } } else //跳闸成功 { if(soe_check(EV_GOOSE_HZ_OK+sw*EV_SW_NUM)==false) //联络合闸成功 { soe_record_ev( EV_GOOSE_HZ_OK+sw*EV_SW_NUM,1, 0,0,0 ); } } poc->sta.bFlag.bllhzH=false; } } #ifdef GD_AREA_ZHONGSHAN_2020 void fag_oc_acc(int sw,u32 dStep) // 分布式合闸加速跳闸 { bool bQDD; bool bJS3,bJS4,bJS5; bool bY1,bY2; int ui_begin; int oc; ui_begin = UI_SW_INDEX_BEGIN(sw); for(oc=FAG_GL1;octSwSet[sw].tGocSet.tOc[oc]; u16 soeno=EV_GOOSE_HZ_GL1+oc+sw*EV_SW_NUM; bool bgloc=(oc==FAG_LX)?false:true; bool bxbbs=false; // 电流启动 if(bgloc) { bool bxb; DWORD xbcoe; // 谐波系数 bxb=pRunSet->tSwSet[sw].bTT_goose_xbbs; xbcoe=pRunSet->tSwSet[sw].d_goose_xbcoe; poc->sta.bFlag.bIaQD = OverRelay(g_ui[ui_begin+SW_AC_IA].m2[0], pSet->dI, pSet->dI_fh, poc->sta.bFlag.bIaQD); poc->sta.bFlag.bIbQD = OverRelay(g_ui[ui_begin+SW_AC_IB].m2[0], pSet->dI, pSet->dI_fh, poc->sta.bFlag.bIbQD); poc->sta.bFlag.bIcQD = OverRelay(g_ui[ui_begin+SW_AC_IC].m2[0], pSet->dI, pSet->dI_fh, poc->sta.bFlag.bIcQD); poc->sta.bFlag.bIaxb =bxb&&XBCalc(sw,SW_AC_IA,xbcoe,poc->sta.bFlag.bIaQD); poc->sta.bFlag.bIbxb=bxb&&XBCalc(sw,SW_AC_IB,xbcoe,poc->sta.bFlag.bIbQD); poc->sta.bFlag.bIcxb=bxb&&XBCalc(sw,SW_AC_IC,xbcoe,poc->sta.bFlag.bIcQD); bQDD=poc->sta.bFlag.bIaQD||poc->sta.bFlag.bIbQD||poc->sta.bFlag.bIcQD; bxbbs=poc->sta.bFlag.bIaxb||poc->sta.bFlag.bIbxb||poc->sta.bFlag.bIcxb; //谐波闭锁 } else //零序加速 { // 零序电流过量继电器 bY1 = OverRelay(g_ui[UI_SW_INDEX(sw,SW_AC_I0)].m2[0], pSet->dI, pSet->dI_fh, poc->sta.bFlag.bQD); bY2=true; bQDD=bY1&& ((bY2&&pRunSet->bTT_U0BS)||(!pRunSet->bTT_U0BS)); bxbbs=false; } // 检查合闸加速标 bJS3 = g_tRelay[sw].tSWST.uSWST.bFlag.bSHJS; // 手合加速标 poc->sta.bFlag.bQD = (BH_GOOSE_EN_YB(sw)) &&(!pRunSet->tSwSet[sw].tGocSet.bsw_fz) && bQDD && (!bxbbs);//谐波闭锁 // 加速标保持 bJS4 = bJS3 || poc->sta.bFlag.bJSBC; // 后加速启动条件满足 bJS5 = poc->sta.bFlag.bQD&& bJS4; // 合闸加速标保持 poc->sta.bFlag.bJSBC = bJS5 && bJS4; if(bJS5) //幅值启动 { if(!poc->sta.bFlag.bQDWave) { if(bgloc) { rcd_start(sw,RECORD_TYPE_GLGZ, RECORD_LEN_TZQD); //录波类型:跳闸类 } else { rcd_start(sw,RECORD_TYPE_LXGL, RECORD_LEN_TZQD); //录波类型:跳闸类 } poc->sta.bFlag.bQDWave=true; } } else { poc->sta.bFlag.bQDWave=true; } RunTR(&poc->tQDTime, bJS5, dStep); RunTR(&poc->tQD25ms, bJS5, dStep); // 如果加速时间到,启动时间未到,调用幅值启动加速模块 if(poc->sta.bFlag.bQD && poc->tQDTime.boolTrip && !poc->tQD25ms.boolTrip) { if(bgloc) { if(protect_amp_qd_js(sw)) { // 预置25ms,让下个循环再出口 PreSetTime(&poc->tQD25ms, T_25ms); } } else { if(protect_amp_lx_js(sw)) { // 预置25ms,让下个循环再出口 PreSetTime(&poc->tQD25ms, T_25ms); } } } poc->sta.bFlag.bTz=poc->tQDTime.boolTrip && poc->tQD25ms.boolTrip; // 出口记录及出口 if(poc->sta.bFlag.bTz) { if(bgloc) { int ui_begin; DWORD Ia,Ib,Ic; ui_begin = UI_SW_INDEX_BEGIN(sw); Ia = _Mul_Div_U(sqrt_32fix(g_ui[ui_begin + SW_AC_IA].m2[0]), 256, g_ui[ui_begin + SW_AC_IA].m2_factor_k); Ib = _Mul_Div_U(sqrt_32fix(g_ui[ui_begin + SW_AC_IB].m2[0]), 256, g_ui[ui_begin + SW_AC_IB].m2_factor_k); Ic = _Mul_Div_U(sqrt_32fix(g_ui[ui_begin + SW_AC_IC].m2[0]), 256, g_ui[ui_begin + SW_AC_IC].m2_factor_k); if(soe_check(soeno)==false) //过流跳闸 { soe_record_ev( soeno,1, Ia,Ib,Ic ); poc->sta.bFlag.bDzLed = true; g_tRelay[sw].tgoc.bgooseGz=true; } } else // 零序加速 { // 出口记录及出口 if(poc->sta.bFlag.bTz) { int ui_begin; DWORD I0; ui_begin = UI_SW_INDEX_BEGIN(sw); I0= _Mul_Div_U(sqrt_32fix(g_ui[ui_begin + SW_AC_I0].m2[0]), 256, g_ui[ui_begin + SW_AC_I0].m2_factor_k); if(soe_check(soeno)==false) //零序跳闸 { soe_record_ev( soeno,1, I0,0,0 ); poc->sta.bFlag.bDzLed = true; g_tRelay[sw].tgoc.bgooseGz=true; } if(soe_check(soeno)==false) // 故障切除启动 { soe_record_ev( soeno,1, 0,0,0 ); } } } } else { if(soe_check(soeno)==true) // 过流跳闸 { soe_record_ev( soeno,0, 0,0,0 ); } } } } #endif void fag_kc(int sw,DWORD dStep) //goose开出 { TRELAY_T *pR=&g_tRelay[sw]; TGOC_T *poc=&g_tRelay[ sw].tgoc; bool bTz; bool bCur; bool bgzglok=false; bool btzsb=false; bTz=poc->sta.bFlag.bglTzH ||poc->sta.bFlag.blxTzH ||poc->sta.bFlag.bgzglTzH ||poc->sta.bFlag.bsdTzH ||poc->sta.bFlag.bextTzH ||poc->sta.bFlag.berrTzH; // 有跳闸信号时,可由大电流闭锁不动作, // 无闭锁时,需保证一次动作信号仅一次出口 if(bTz&&!pR->bBSTZ&&!poc->bTzout) { sw_do(sw,SW_DO_HZ,SW_DO_TYPE_OFF); sw_do(sw,SW_DO_BHH,SW_DO_TYPE_OFF); sw_do(sw,SW_DO_BHDZ,SW_DO_TYPE_ON); sw_do(sw,SW_DO_FZ,SW_DO_TYPE_ON); sw_do(sw,SW_DO_BHT,SW_DO_TYPE_ON); poc->bTzout=true; } // 跳闸失败检查: 跳闸后持续有流或合位 bCur = ((!pR->tSWST.uSWST.bFlag.bSXWL) || pR->tSWST.uSWST.bFlag.bHZWZ); RunTR(&poc->tTzcheckTime, bTz, dStep); // if(poc->tTzcheckTime.boolTrip) //跳闸失败时间到,清标志,报soe { if(bCur) //跳闸失败 { bTz=poc->sta.bFlag.bglTzH ||poc->sta.bFlag.blxTzH ||poc->sta.bFlag.bgzglTzH ||poc->sta.bFlag.bsdTzH ||poc->sta.bFlag.berrTzH; if(poc->sta.bFlag.bglTzH||poc->sta.bFlag.blxTzH||poc->psta.bFlag.bGZ) //故障切除 { if(soe_check(EV_GOOSE_QC_FAIL+sw*EV_SW_NUM)==false) { soe_record_ev( EV_GOOSE_QC_FAIL+sw*EV_SW_NUM,1, 0,0,0 ); // 故障切除失败 } } else { if(soe_check(EV_GOOSE_GL_FAIL+sw*EV_SW_NUM)==false) // { soe_record_ev( EV_GOOSE_GL_FAIL+sw*EV_SW_NUM,1, 0,0,0 ); //故障隔离失败 } } if(bTz) btzsb=true; //开关失灵引起的跳闸失败,不再发送 } else //跳闸成功 { if(poc->sta.bFlag.bglTzH||poc->sta.bFlag.blxTzH||poc->psta.bFlag.bGZ) { if(soe_check(EV_GOOSE_QC_OK+sw*EV_SW_NUM)==false) // 故障切除 { soe_record_ev( EV_GOOSE_QC_OK+sw*EV_SW_NUM,1, 0,0,0 ); } } else { if(soe_check(EV_GOOSE_GL_OK+sw*EV_SW_NUM)==false) // 故障隔离成功 { soe_record_ev( EV_GOOSE_GL_OK+sw*EV_SW_NUM,1, 0,0,0 ); } bgzglok=true&&(!pRunSet->tSwSet[sw].tGocSet.bsw_fz); //分支开关不发送故障隔离成功信号 } } poc->bTzout=false; poc->sta.bFlag.bglTzH=false; poc->sta.bFlag.blxTzH=false; poc->sta.bFlag.bgzglTzH=false; poc->sta.bFlag.bsdTzH=false; poc->sta.bFlag.bextTzH=false; poc->sta.bFlag.berrTzH=false; ResetTR(&poc->tTzcheckTime); } #if defined GD_AREA_ZHONGSHAN || defined GD_AREA_ZHONGSHAN_2020 //中山要求联络开关固定 btzsb|=(pR->uBHDZ.bFlag.bTZSB&&pRunSet->tSwSet[sw].tGocSet.bsw_fz); //分支开关动作逻辑在常规保护中处理 #endif RunTR(&poc->tgzglokextTime, bgzglok, dStep); //故障隔离成功发送 poc->psta.bFlag.bgzglok=poc->tgzglokextTime.boolTrip; RunTR(&poc->ttzsbextTime, btzsb, dStep); //跳闸失败发送展宽时间 poc->psta.bFlag.btzsb=poc->ttzsbextTime.boolTrip; RunTR(&poc->tgzglokForbitTime, poc->psta.bFlag.bgzglok, dStep); //故障隔离发送闭锁 } void fag_bh(int sw,DWORD dStep) { tFAg.bComErr=(tFAg.commerr>0||tFAg.syscomerr>0)?true:false; // goose 通信异常 本机和系统通信异常 GOC_dir_check(sw,dStep); fag_cd(sw,dStep); // fag_gzgl(sw,dStep); // fag_lostvol_sd(sw,dStep); // #if defined GD_AREA_ZHONGSHAN || defined GD_AREA_ZHONGSHAN_2020 //中山地区,不需要通信失压分闸 #else fag_lostvol_commer(sw,dStep); // #endif fag_exttz(sw,dStep); // fag_ll(sw,dStep); // fag_kc(sw,dStep); // fa_g_commcheck(dStep); // goose信息延时复归 } bool _XB2_Logic_Relay(int sw, DWORD I, DWORD Ixb2, DWORD XBcoe,DWORD Iset) { if(( I > Iset) && ( Ixb2 > pRunSet->dIWL_SQR[sw] )) // I 与 Ixb2 均应大于无流定值 { if( Ixb2 > _MulFac_U(I, XBcoe )) { return(true); } else { return(false); } } else { return(false); } return 0; } /****************************************************************************** 函数名称: XBCalc 函数版本: 01.01 创建作者: xxxxxx 创建日期: 2014-12-16 函数说明: 谐波计算 参数说明: 返回值: 无 修改记录: */ void XBCalc_goc(int sw) { bool bH1,bH2,bH3; bool bxbbs=false; bool bxbbs2=false; if(!BH_GOOSE_EN(sw))return; if(pRunSet->tSwSet[sw].bTT_goose_xbbs) { bH1 = _XB2_Logic_Relay(sw, g_ui[UI_SW_INDEX(sw,SW_AC_IA)].m2[0], g_ui[UI_SW_INDEX(sw,SW_AC_IA)].m2[1], pRunSet->tSwSet[sw].d_goose_xbcoe,pRunSet->tSwSet[sw].tGocSet.dIgl);//A相谐波闭锁 bH2 = _XB2_Logic_Relay(sw, g_ui[UI_SW_INDEX(sw,SW_AC_IB)].m2[0], g_ui[UI_SW_INDEX(sw,SW_AC_IB)].m2[1], pRunSet->tSwSet[sw].d_goose_xbcoe,pRunSet->tSwSet[sw].tGocSet.dIgl);//B相谐波闭锁 bH3 = _XB2_Logic_Relay(sw, g_ui[UI_SW_INDEX(sw,SW_AC_IC)].m2[0], g_ui[UI_SW_INDEX(sw,SW_AC_IC)].m2[1], pRunSet->tSwSet[sw].d_goose_xbcoe,pRunSet->tSwSet[sw].tGocSet.dIgl);//C相谐波闭锁 bxbbs=(bH1 || bH2 || bH3); #if defined GD_AREA_ZHONGSHAN || defined GD_AREA_ZHONGSHAN_2020 bH1 = _XB2_Logic_Relay(sw, g_ui[UI_SW_INDEX(sw,SW_AC_IA)].m2[0], g_ui[UI_SW_INDEX(sw,SW_AC_IA)].m2[1], pRunSet->tSwSet[sw].d_goose_xbcoe,pRunSet->tSwSet[sw].tGocSet.dIgl2);//A相谐波闭锁 bH2 = _XB2_Logic_Relay(sw, g_ui[UI_SW_INDEX(sw,SW_AC_IB)].m2[0], g_ui[UI_SW_INDEX(sw,SW_AC_IB)].m2[1], pRunSet->tSwSet[sw].d_goose_xbcoe,pRunSet->tSwSet[sw].tGocSet.dIgl2);//B相谐波闭锁 bH3 = _XB2_Logic_Relay(sw, g_ui[UI_SW_INDEX(sw,SW_AC_IC)].m2[0], g_ui[UI_SW_INDEX(sw,SW_AC_IC)].m2[1], pRunSet->tSwSet[sw].d_goose_xbcoe,pRunSet->tSwSet[sw].tGocSet.dIgl2);//C相谐波闭锁 bxbbs2=(bH1 || bH2 || bH3); #endif } g_tRelay[sw].tgoc.sta.bFlag.bXBbs =bxbbs; g_tRelay[sw].tgoc.sta.bFlag.bXBbs2 =bxbbs2; if(bxbbs||bxbbs2) { if(soe_check(EV_XBBS+sw*EV_SW_NUM)==false) { soe_record_ev(EV_XBBS+sw*EV_SW_NUM,1, 0,0,0 ); } } else { if(soe_check(EV_XBBS+sw*EV_SW_NUM)==true) { soe_record_ev( EV_XBBS+sw*EV_SW_NUM,0, 0,0,0 ); } } } /***************************************endfile**********************************************************/