#include "head.h" enum { JD_STEP_QD = 0, // 启动判断 JD_STEP_CHECK, // 启动确认 JD_STEP_COLLECT, // 数据收集 JD_STEP_CTFAULT, // 暂态故障判定 JD_STEP_SSFAULT, // 稳态故障处理 JD_STEP_RST, // 复归 JD_STEP_NET_RST, // 等待网络复归 }; enum { JD_FAULT_DIR_ZERO = 0, JD_FAULT_DIR_POS_QD, // 大于启动值正方向 JD_FAULT_DIR_NEG_QD, // 大于启动值反方向 JD_FAULT_DIR_POS, // 大于零漂正方向 JD_FAULT_DIR_NEG, // 大于零漂反方向 }; #ifdef FUN_JDXX // #define XDL_PRINT #define UI_JDXX_I0_INDEX UI_SW_INDEX(sw, SW_AC_I0) #define UI_JDXX_I0S_INDEX UI_SW_INDEX(sw, SW_AC_I0s) /////////////////////////////////////////////// JDXX_SET tJDXX_val[SWITCH_NUM_MAX]; bool TT_U0yx; // U0越限判据投退 bool TT_Ulyy; // Ul线电压有压判据 bool TT_Ipwl; // 相电流无流判据投退 bool TT_Ipph; // 相电流相位判据 bool TT_U0jd; // UO就接地 extern unsigned int g_count_156us; //////////////////////////////////////////////////////////////////////////////////////////////// void jdxx_init(void) { // memset(&tJD,0,sizeof(tJD)); _getjdxxdz_inf(); rt_printf("Jdxx_Ver:%02d.%03d \r\n", (FUN_JDXX_VERSION / 1000), (FUN_JDXX_VERSION % 1000)); } void jdxx_relayinit(void) { int i; for (i = 0; i < SWITCH_NUM_MAX; i++) { JDXX_SET *pJdxx = &tJDXX_val[i]; TRELAY_T *pR = &g_tRelay[i]; // U0判出时间 #ifdef FUN_JDXX_JXJD InitTR_Time(&pR->tJD.tJDXXU01Time, T_20ms, 0); // U01 20ms InitTR_Time(&pR->tJD.tJDXXU02Time, T_20ms, 0); // U02 20ms #elif defined FUN_JDXX_TBLQD InitTR_Time(&pR->tJD.tJDXXU01Time, T_25ms, T_10ms); // U01 40ms InitTR_Time(&pR->tJD.tJDXXU02Time, T_25ms, T_10ms); // U02 40ms #else InitTR_Time(&pR->tJD.tJDXXU01Time, T_20ms, T_20ms); // U01 20ms,保持100ms(弧光接地) InitTR_Time(&pR->tJD.tJDXXU02Time, T_20ms, T_20ms); // U02 20ms,保持100ms(弧光接地) #endif InitTR_Time(&pR->tJD.tJDXXU1yyTime, T_20ms * 3, 0); // 有压60ms InitTR_Time(&pR->tJD.tJDXXU2yyTime, T_20ms * 3, 0); // 有压60ms InitTR_Time(&pR->tJD.tJDXXIylTime, T_20ms * 3, 0); // 有流60ms InitTR_Time(&pR->tJD.tJDXXTripTime, pJdxx->jd_trip_time, T_20ms); InitTR_Time(&pR->tJD.tJDXXAlarmTime, pJdxx->jd_alarm_time, T_20ms); #ifdef JDXX_YXEV_RST InitTR_Time(&pR->tJD.tJDGjEvRstTime, tRunPara.dTEventRst, 0); InitTR_Time(&pR->tJD.tJDTzEvRstTime, tRunPara.dTEventRst, 0); #endif #ifdef HJS_XDLJD InitTR(&pR->tJD.jdxx_jskf_time, pJdxx->jd_js_time, 0); // 开放时间 #endif } } void jdxx_u0_rst(int sw) { TRELAY_T *pR = &g_tRelay[sw]; ResetTR(&pR->tJD.tJDXXU01Time); // U02 20ms ResetTR(&pR->tJD.tJDXXU02Time); // U02 20ms ResetTR(&pR->tJD.tJDXXU1yyTime); // ResetTR(&pR->tJD.tJDXXU2yyTime); // ResetTR(&pR->tJD.tJDXXIylTime); // } void jdxx_qd_rst(int sw) // 启动返回 { int i; TRELAY_T *pR = &g_tRelay[sw]; pR->tJD.jd_step = JD_STEP_QD; pR->tJD.sta.bFlag.bTz = false; pR->tJD.sta.bFlag.bGj = false; pR->tJD.qdPoints = 0; pR->tJD.adPoints = 0; pR->tJD.con_angle = 0; #ifdef FUN_JDXX_SS_ANGLE pR->tJD.dir_cnt = 0; #endif #ifdef HJS_XDLJD pR->tJD.sta.bFlag.bJd_qn = 0; // 区外故障 #endif for (i = 0; i < NUM_ANGLE; i++) { pR->tJD.ui_angle[i] = 0; } ResetTR(&pR->tJD.tJDXXTripTime); ResetTR(&pR->tJD.tJDXXAlarmTime); // soe pro_rst_event(sw, EV_LX_XDL_QD); pro_rst_event(sw, EV_JDXX_JWGZ); #ifdef FUN_JDXX_JXJD pro_rst_event(sw, EV_JDXX_SWIN_GJ); pro_rst_event(sw, EV_JDXX_LWIN_GJ); #endif } void jdxx_fg(int sw) // 接地选线复归 { #ifdef XDL_PRINT rt_printf("\r\njdxx_fg:sw=%d JD_STEP_FG", sw); #endif jdxx_qd_rst(sw); } // soe fugui void jdxx_soe_fg(int sw, DWORD dStep) { #ifdef JDXX_YXEV_RST { TRELAY_T *pR = &g_tRelay[sw]; RunTR(&pR->tJD.tJDGjEvRstTime, true, dStep); RunTR(&pR->tJD.tJDTzEvRstTime, true, dStep); if (pR->tJD.tJDGjEvRstTime.boolTrip) { pro_rst_event(sw, EV_JDXX_GJ); // 事故总 主程序复归 // if(pJdxx->bTT_jdxx_fault_all) //{ // pro_rst_event(sw,EV_ALL_FAULT); // } } if (pR->tJD.tJDTzEvRstTime.boolTrip) { pro_rst_event(sw, EV_JDXX_TZ); // 事故总 主程序复归 // if(pJdxx->bTT_jdxx_fault_all) //{ // pro_rst_event(sw,EV_ALL_FAULT); // } #ifdef FUN_JDXX_JXJD pro_rst_event(sw, EV_JDXX_SWIN_TZ); pro_rst_event(sw, EV_JDXX_LWIN_TZ); pro_rst_event(sw, EV_JDXX_YJ_TZ); #endif } } #else { pro_rst_event(sw, EV_JDXX_GJ); pro_rst_event(sw, EV_JDXX_TZ); // 事故总 主程序复归 // if(pJdxx->bTT_jdxx_fault_all) //{ // pro_rst_event(sw,EV_ALL_FAULT); // } #ifdef FUN_JDXX_JXJD pro_rst_event(sw, EV_JDXX_SWIN_TZ); pro_rst_event(sw, EV_JDXX_LWIN_TZ); pro_rst_event(sw, EV_JDXX_YJ_TZ); #endif } #endif } void jdxx_yxev_rst(int sw) { #ifdef JDXX_YXEV_RST TRELAY_T *pR = &g_tRelay[sw]; ResetTR(&pR->tJD.tJDGjEvRstTime); ResetTR(&pR->tJD.tJDTzEvRstTime); #endif pro_rst_event(sw, EV_JDXX_GJ); pro_rst_event(sw, EV_JDXX_TZ); #ifdef FUN_JDXX_JXJD pro_rst_event(sw, EV_JDXX_SWIN_TZ); pro_rst_event(sw, EV_JDXX_LWIN_TZ); pro_rst_event(sw, EV_JDXX_YJ_TZ); #endif } /********************************** //启动前零序通道零漂模值 **********************************/ void jdxx_getzeroval(int sw) { JDXX_SET *pJdxx = &tJDXX_val[sw]; TRELAY_T *pR = &g_tRelay[sw]; if (pR->tJD.jd_step == JD_STEP_QD) // 复归判断 { pR->tJD.zeroval = g_ui[pJdxx->i0_chan].m2[0] + pJdxx->jd_qdval2; } } /********************************** //突变量 //index:电流通道 //cur:通道采样索要 **********************************/ s32 jdxx_get_qdval(u32 cur, int index) // 突变量 { s32 v, v1, v2, val; v = g_adc_dots_rec[cur][index]; v1 = g_adc_dots_rec[(cur - ADC_REC_SAMPLE) & ADC_REC_DOTS_MASK][index]; v2 = g_adc_dots_rec[(cur - ADC_REC_SAMPLE * 2) & ADC_REC_DOTS_MASK][index]; val = (v - 2 * v1 + v2); return val; } s32 jdxx_getI0_qdval(u32 cur, int index1, int index2, int index3) // 突变量 { s32 val = 0; val = jdxx_get_qdval(cur, index1) + jdxx_get_qdval(cur, index2) + jdxx_get_qdval(cur, index3); return val; } //////////////////////////////////////////////// // 复归信号保持 bool jdxx_soe_check(int sw) { if (soe_check(EV_JDXX_GJ + sw * EV_SW_NUM)) return true; if (soe_check(EV_JDXX_TZ + sw * EV_SW_NUM)) return true; // if(soe_check(EV_JDXX_JWGZ+sw*EV_SW_NUM)) return true; #ifdef FUN_JDXX_JXJD if (soe_check(EV_JDXX_SWIN_TZ + sw * EV_SW_NUM)) return true; if (soe_check(EV_JDXX_LWIN_TZ + sw * EV_SW_NUM)) return true; if (soe_check(EV_JDXX_YJ_TZ + sw * EV_SW_NUM)) return true; #endif return false; } #ifdef FUN_JDXX_JXJD // 瞬时故障延时跳闸逻辑 bool jdxx_ssjd_pro(int sw) { int i, num; bool bQDD; JDXX_SET *pJdxx = &tJDXX_val[sw]; TRELAY_T *pR = &g_tRelay[sw]; // 短延时接地故障 if (pJdxx->bTT_jxjd_stz) { // I瞬时接地计次 pR->tJD.cnt_sdelay++; if (pR->tJD.cnt_sdelay > pJdxx->jd_sdelay_cnt) { pR->tJD.cnt_sdelay = pJdxx->jd_sdelay_cnt; } #ifdef XDL_PRINT rt_printf("\r\nSW%d:间歇性接地保护I段计次!sdn=%d!", sw, pR->tJD.cnt_sdelay); #endif // jxjd_logic bQDD = (pR->tJD.cnt_sdelay >= pJdxx->jd_sdelay_cnt) && (ustimer_get_duration(pR->tJD.jdxx_sdelay_us0[pR->tJD.cnt_sdelay - 2]) < (pJdxx->jd_sdelay_time * (USTIMER_SEC / SAM_FREQUENCY))); // 短延时故障 if (bQDD) { // led pR->tJD.sta.bFlag.bTz = true; pR->tJD.sta.bFlag.bTZLed = true; // soe if (soe_check(EV_JDXX_SWIN_TZ + sw * EV_SW_NUM) == false) { soe_record_ev(EV_JDXX_SWIN_TZ + sw * EV_SW_NUM, 1, 0, 0, 0); if (soe_check(EV_JDXX_TZ + sw * EV_SW_NUM) == false) // 区内故障 { soe_record_ev(EV_JDXX_TZ + sw * EV_SW_NUM, 1, 0, 0, 0); } // 事故总 if (pJdxx->bTT_jdxx_fault_all) { if (!soe_check(EV_ALL_FAULT + sw * EV_SW_NUM)) // 保护总 { soe_record_ev(EV_ALL_FAULT + sw * EV_SW_NUM, 1, 0, 0, 0); } } #ifdef XDL_PRINT rt_printf("\r\n间歇性接地保护I段动作"); #endif // 故障处理完毕,进入复归处理流程 pR->tJD.jd_step = JD_STEP_RST; pR->tJD.cnt_sdelay = 0; pR->tJD.cnt_ldelay = 0; //??? #ifdef XDL_PRINT rt_printf("\r\njdxx_s_fault:T[0]=%d!", pR->tJD.time_qd / USTIMER_SEC); rt_printf("\r\njdxx_s_fault:sw=%d step_rst", sw); #endif } return true; } else // 存储故障时刻 { // SOE if (soe_check(EV_JDXX_SWIN_GJ + sw * EV_SW_NUM) == false) { soe_record_ev(EV_JDXX_SWIN_GJ + sw * EV_SW_NUM, 1, 0, 0, 0); } // us0 fifo num = pJdxx->jd_sdelay_cnt - 1; for (i = 0; i < num; i++) { pR->tJD.jdxx_sdelay_us0[num - i] = pR->tJD.jdxx_sdelay_us0[num - 1 - i]; } pR->tJD.jdxx_sdelay_us0[0] = pR->tJD.time_qd; // ustimer_get_origin(); #ifdef XDL_PRINT rt_printf("\r\njdxx_s_fault:T[0]=%d!", pR->tJD.jdxx_sdelay_us0[0] / USTIMER_SEC); #endif } } // 长延时接地故障 if (pJdxx->bTT_jxjd_ltz) { // II瞬时接地计次 pR->tJD.cnt_ldelay++; if (pR->tJD.cnt_ldelay > pJdxx->jd_ldelay_cnt) { pR->tJD.cnt_ldelay = pJdxx->jd_ldelay_cnt; } #ifdef XDL_PRINT rt_printf("\r\nSW%d间歇性接地保护II段计次!ldn=%d!", sw, pR->tJD.cnt_ldelay); #endif // jxjd_logic bQDD = (pR->tJD.cnt_ldelay >= pJdxx->jd_ldelay_cnt) && (ustimer_get_duration(pR->tJD.jdxx_ldelay_us0[pR->tJD.cnt_ldelay - 2]) < (pJdxx->jd_ldelay_time * (USTIMER_SEC / SAM_FREQUENCY))); // 长延时故障 if (bQDD) { // led pR->tJD.sta.bFlag.bTz = true; pR->tJD.sta.bFlag.bTZLed = true; // soe if (soe_check(EV_JDXX_LWIN_TZ + sw * EV_SW_NUM) == false) { soe_record_ev(EV_JDXX_LWIN_TZ + sw * EV_SW_NUM, 1, 0, 0, 0); if (soe_check(EV_JDXX_TZ + sw * EV_SW_NUM) == false) // 区内故障 { soe_record_ev(EV_JDXX_TZ + sw * EV_SW_NUM, 1, 0, 0, 0); } // 事故总 if (pJdxx->bTT_jdxx_fault_all) { if (!soe_check(EV_ALL_FAULT + sw * EV_SW_NUM)) // 保护总 { soe_record_ev(EV_ALL_FAULT + sw * EV_SW_NUM, 1, 0, 0, 0); } } #ifdef XDL_PRINT rt_printf("\r\n间歇性接地保护II段动作"); #endif // 故障处理完毕,进入复归处理流程 pR->tJD.jd_step = JD_STEP_RST; pR->tJD.cnt_sdelay = 0; //??? pR->tJD.cnt_ldelay = 0; #ifdef XDL_PRINT rt_printf("\r\njdxx_l_fault:T[0]=%d!", pR->tJD.time_qd / USTIMER_SEC); rt_printf("\r\njdxx_l_fault:sw=%d step_rst", sw); #endif } return true; } else // 存储故障时刻 { // SOE if (soe_check(EV_JDXX_LWIN_GJ + sw * EV_SW_NUM) == false) { soe_record_ev(EV_JDXX_LWIN_GJ + sw * EV_SW_NUM, 1, 0, 0, 0); } // us0 fifo num = pJdxx->jd_ldelay_cnt - 1; for (i = 0; i < num; i++) { pR->tJD.jdxx_ldelay_us0[num - i] = pR->tJD.jdxx_ldelay_us0[num - 1 - i]; } pR->tJD.jdxx_ldelay_us0[0] = pR->tJD.time_qd; // ustimer_get_origin(); #ifdef XDL_PRINT rt_printf("\r\njdxx_l_fault:T[0]=%d!", pR->tJD.jdxx_ldelay_us0[0] / USTIMER_SEC); #endif } } return false; } #endif // 复归 void jdxx_rst(int sw, DWORD dStep) { TRELAY_T *pR = &g_tRelay[sw]; // 状态 if (pR->tJD.jd_step == JD_STEP_QD) { jdxx_soe_fg(sw, dStep); return; } // 复归 if (pR->tJD.jd_step == JD_STEP_RST) { jdxx_fg(sw); } else // pR->tJD.jd_step==JD_STEP_RST { #ifdef FUN_JDXX_JXJD bool ret; ret = jdxx_ssjd_pro(sw); // 多次瞬时故障跳闸 if (!ret) #endif { jdxx_fg(sw); } } } s16 jdxx_get_adval(u32 dots, int index) { u32 cur = dots & ADC_REC_DOTS_MASK; s16 v; v = g_adc_dots_rec[cur][index]; return v; } s16 jdxx_getI0_adval(u32 dots, int index1, int index2, int index3) { u32 cur = dots & ADC_REC_DOTS_MASK; s16 v; v = g_adc_dots_rec[cur][index1] + g_adc_dots_rec[cur][index2] + g_adc_dots_rec[cur][index3]; return v; } /*bool jdxx_I0_ov(int sw) //判断零序是否失真 { int i; JDXX_SET *pJdxx=&pRunSet->tSwSet[sw].tJDXX; for(i=0;ijd_faultPoints;i++) // 统计接地时刻的波形,是否满偏失真 ,大于8A,即使用大量程零序波形判断 { s16 v; v=jdxx_get_adval(tJD[sw].dot_qd+i,g_ui[UI_SW_INDEX(sw,SW_AC_I0)].chn_index);//jdxx_get_adval(tJD.dot_qd+i,g_ui[UI_JDXX_I0G_INDEX].chn_index); if(_AbsL(v)>=pJdxx->jd_ov_val) { return true; } } return false; }*/ #define U0_FULL_DOTNUM 10 bool jdxx_U0_ov(int sw) // 判断一周波零序电压是否失真 { int i, j, mod, index; u32 dotcur; TRELAY_T *pR = &g_tRelay[sw]; if (pR->tJD.jd_u0_12 == 1) index = PUB_AC_U01; else index = PUB_AC_U02; mod = (int)(g_count_156us & 0x03); dotcur = (g_adc_dots_count)*ADC_REC_SAMPLE_RATE + mod - ADC_REC_SAMPLE; for (i = 0, j = 0; i < ADC_REC_SAMPLE; i++) // ADC_REC_SAMPLE 统计接地时刻的波形,是否满偏失真 ,大于8A,即使用大量程零序波形判断 { s16 v; v = jdxx_get_adval(dotcur + i, g_ui[index].chn_index); pR->tJD.jd_U0ov_val = (short)(7.2 * g_ui[index].m2_factor_k / 256.0 + 0.5); // EVT零序 7.8125V满偏,7.2V作为满偏定值 if (_AbsL(v) >= pR->tJD.jd_U0ov_val) { if (++j > U0_FULL_DOTNUM) { return true; } } } return false; } bool jdxx_I0_ov(int sw) // 判断零序是否失真 { int i; JDXX_SET *pJdxx = &tJDXX_val[sw]; TRELAY_T *pR = &g_tRelay[sw]; if (g_ui[UI_JDXX_I0S_INDEX].chn_index == CFG_ADC_CHANNEL_ZERO) { return false; } for (i = 0; i < pJdxx->jd_faultPoints; i++) // 统计接地时刻的波形,是否满偏失真 ,大于0.5A,即使用大量程零序波形判断 { s16 v; v = jdxx_get_adval(pR->tJD.dot_qd + i, g_ui[UI_JDXX_I0_INDEX].chn_index); if (_AbsL(v) >= pJdxx->jd_ov_val) { rt_printf("jdxx:sw=%d 零序小通道电流满偏失真!\r\n", sw); return true; } } return false; } int jdxx_I0Range(int sw) // { int i; int bv0 = 0, bv1 = 0; int dots = 0; JDXX_SET *pJdxx = &tJDXX_val[sw]; TRELAY_T *pR = &g_tRelay[sw]; for (i = 0; i < pJdxx->jd_faultPoints - 1; i++) // 取方向 { if (pJdxx->bTT_jdxx_cph) //(g_ui[UI_SW_INDEX(sw,SW_AC_I0)].chn_index==CFG_ADC_CHANNEL_ZERO) { if (jdxx_getI0_qdval(pR->tJD.dot_qd + i, g_ui[UI_SW_INDEX(sw, SW_AC_IA)].chn_index, g_ui[UI_SW_INDEX(sw, SW_AC_IB)].chn_index, g_ui[UI_SW_INDEX(sw, SW_AC_IC)].chn_index) > 0) // pJdxx->jd_zero) { bv0 = 1; break; } else if (jdxx_getI0_qdval(pR->tJD.dot_qd + i, g_ui[UI_SW_INDEX(sw, SW_AC_IA)].chn_index, g_ui[UI_SW_INDEX(sw, SW_AC_IB)].chn_index, g_ui[UI_SW_INDEX(sw, SW_AC_IC)].chn_index) < 0) //-pJdxx->jd_zero) { bv0 = -1; break; } } else { if (g_ui[pJdxx->i0_chan].chn_index == CFG_ADC_CHANNEL_ZERO) { if (jdxx_getI0_qdval(pR->tJD.dot_qd + i, g_ui[UI_SW_INDEX(sw, SW_AC_IA)].chn_index, g_ui[UI_SW_INDEX(sw, SW_AC_IB)].chn_index, g_ui[UI_SW_INDEX(sw, SW_AC_IC)].chn_index) > 0) // pJdxx->jd_zero) { bv0 = 1; break; } else if (jdxx_getI0_qdval(pR->tJD.dot_qd + i, g_ui[UI_SW_INDEX(sw, SW_AC_IA)].chn_index, g_ui[UI_SW_INDEX(sw, SW_AC_IB)].chn_index, g_ui[UI_SW_INDEX(sw, SW_AC_IC)].chn_index) < 0) //-pJdxx->jd_zero) { bv0 = -1; break; } } else { if (jdxx_get_qdval(pR->tJD.dot_qd + i, g_ui[pJdxx->i0_chan].chn_index) > 0) // pJdxx->jd_zero) { bv0 = 1; break; } else if (jdxx_get_qdval(pR->tJD.dot_qd + i, g_ui[pJdxx->i0_chan].chn_index) < 0) //-pJdxx->jd_zero) { bv0 = -1; break; } } } } for (i++; i < pJdxx->jd_faultPoints; i++) // 取方向 { if (pJdxx->bTT_jdxx_cph) //(g_ui[UI_SW_INDEX(sw,SW_AC_I0)].chn_index==CFG_ADC_CHANNEL_ZERO) { if (jdxx_getI0_qdval(pR->tJD.dot_qd + i, g_ui[UI_SW_INDEX(sw, SW_AC_IA)].chn_index, g_ui[UI_SW_INDEX(sw, SW_AC_IB)].chn_index, g_ui[UI_SW_INDEX(sw, SW_AC_IC)].chn_index) > 0) // pJdxx->jd_zero) { bv1 = 1; } else if (jdxx_getI0_qdval(pR->tJD.dot_qd + i, g_ui[UI_SW_INDEX(sw, SW_AC_IA)].chn_index, g_ui[UI_SW_INDEX(sw, SW_AC_IB)].chn_index, g_ui[UI_SW_INDEX(sw, SW_AC_IC)].chn_index) < 0) //-pJdxx->jd_zero) { bv1 = -1; } } else { if (g_ui[pJdxx->i0_chan].chn_index == CFG_ADC_CHANNEL_ZERO) { if (jdxx_getI0_qdval(pR->tJD.dot_qd + i, g_ui[UI_SW_INDEX(sw, SW_AC_IA)].chn_index, g_ui[UI_SW_INDEX(sw, SW_AC_IB)].chn_index, g_ui[UI_SW_INDEX(sw, SW_AC_IC)].chn_index) > 0) // pJdxx->jd_zero) { bv1 = 1; } else if (jdxx_getI0_qdval(pR->tJD.dot_qd + i, g_ui[UI_SW_INDEX(sw, SW_AC_IA)].chn_index, g_ui[UI_SW_INDEX(sw, SW_AC_IB)].chn_index, g_ui[UI_SW_INDEX(sw, SW_AC_IC)].chn_index) < 0) //-pJdxx->jd_zero) { bv1 = -1; } } else { if (jdxx_get_qdval(pR->tJD.dot_qd + i, g_ui[pJdxx->i0_chan].chn_index) > 0) // pJdxx->jd_zero) { bv1 = 1; } else if (jdxx_get_qdval(pR->tJD.dot_qd + i, g_ui[pJdxx->i0_chan].chn_index) < 0) //-pJdxx->jd_zero) { bv1 = -1; } } } dots = i + 1; if (bv0 != bv1) break; } #ifdef XDL_PRINT rt_printf("\r\n sw=%d 启动后同方向点数%d", sw, dots); #endif return dots; } int jdxx_Iabc_check_dir(int sw) // Ia Ib Ic 接地相判断,以零序启动时刻为主,查找零序启动后32点内的最大值,做积分,看三相的方向 { int dots; long va, vb, vc, v1, v2, v3; int i; TRELAY_T *pR = &g_tRelay[sw]; dots = jdxx_I0Range(sw); va = 0; vb = 0; vc = 0; for (i = 0; i < dots; i++) // { va += jdxx_get_qdval(pR->tJD.dot_qd + i, g_ui[UI_SW_INDEX(sw, SW_AC_IA)].chn_index); vb += jdxx_get_qdval(pR->tJD.dot_qd + i, g_ui[UI_SW_INDEX(sw, SW_AC_IB)].chn_index); vc += jdxx_get_qdval(pR->tJD.dot_qd + i, g_ui[UI_SW_INDEX(sw, SW_AC_IC)].chn_index); } #ifdef XDL_PRINT rt_printf("\r\n三相积分值Ia=%d Ib=%d Ic=%d", va, vb, vc); #endif // 一相和另外两相反相 if ((va > 0 && vb <= 0 && vc <= 0) || (va < 0 && vb >= 0 && vc >= 0)) // 不同相 { return SW_AC_IA; // A相接地 } else if ((vb > 0 && va <= 0 && vc <= 0) || (vb < 0 && va >= 0 && vc >= 0)) { return SW_AC_IB; // B相接地 } else if ((vc > 0 && va <= 0 && vb <= 0) || (vc < 0 && va >= 0 && vb >= 0)) { return SW_AC_IC; // C相接地 } // 突变:4倍 v1 = _AbsL(va); v2 = _AbsL(vb); v3 = _AbsL(vc); if ((v1 >> 2) > v2 && (v1 >> 2) > v3) { return SW_AC_IA; // A相接地 } else if ((v2 >> 2) > v1 && (v2 >> 2) > v3) { return SW_AC_IB; // A相接地 } else if ((v3 >> 2) > v1 && (v3 >> 2) > v2) { return SW_AC_IC; // A相接地 } // 无法判相 return -1; } // 电压波形起始点 int jdxx_get_dotsoff(int sw, int pha) { int vdots = 0, dotsoff = 0; JDXX_SET *pJdxx = &tJDXX_val[sw]; TRELAY_T *pR = &g_tRelay[sw]; if ((pJdxx->jd_voltype == PUB_AC_U01) || (pJdxx->jd_voltype == PUB_AC_U02)) { vdots = pR->tJD.dot_qd; } else if (pJdxx->jd_voltype == PUB_AC_UA1) { if (pha == SW_AC_IA) // A相接地,与UA1比较,波形不需偏移 { dotsoff = 0; } else if (pha == SW_AC_IB) // B相接地,与UA1比较,参考电压波形需后移120度,即128/3=42.66 { dotsoff = -43; } else { dotsoff = 43; // C相接地,参考电压UA1波形需前移120度 } vdots = pR->tJD.dot_qd + dotsoff - ADC_REC_SAMPLE * 2; // 电压波形起始点 } else if (pJdxx->jd_voltype == PUB_AC_UAB1) { if (pha == SW_AC_IA) // A相接地,与UAB1比较,UAB1波形超前Ia30度,30/360*128=10.666(11点) { dotsoff = 11; } else if (pha == SW_AC_IB) // B相接地,与UAB1比较,参考电压波形需后移120度,即128/3=42.66+10.66 { dotsoff = -53; } else { dotsoff = 53; // C相接地,参考电压UA1波形需前移120度 } vdots = pR->tJD.dot_qd + dotsoff - ADC_REC_SAMPLE * 2; // 电压波形起始点 } return vdots; } int jdxx_VI0_dir(int sw, int pha) { int i, dotsnum, vdots; s32 v0, I0; JDXX_SET *pJdxx = &tJDXX_val[sw]; TRELAY_T *pR = &g_tRelay[sw]; if (pha < 0) return 0; vdots = jdxx_get_dotsoff(sw, pha); dotsnum = jdxx_I0Range(sw); // 零序电流统计点数 if (dotsnum == 0) return 0; // 积分 v0 = 0; I0 = 0; for (i = 0; i < dotsnum; i++) // { if (pRunSet->bTT_U0ZC) // U0 { if (pR->tJD.jd_u0_12 == 1) { v0 += jdxx_getI0_qdval(pR->tJD.dot_qd + i, g_ui[PUB_AC_UA1].chn_index, g_ui[PUB_AC_UB1].chn_index, g_ui[PUB_AC_UC1].chn_index); } else { v0 += jdxx_getI0_qdval(pR->tJD.dot_qd + i, g_ui[PUB_AC_UA2].chn_index, g_ui[PUB_AC_UB2].chn_index, g_ui[PUB_AC_UC2].chn_index); } } else { if (pR->tJD.jd_u0_12 == 1) { v0 += jdxx_get_qdval(vdots + i, g_ui[PUB_AC_U01].chn_index); } else { v0 += jdxx_get_qdval(vdots + i, g_ui[PUB_AC_U02].chn_index); } } if (g_ui[pJdxx->i0_chan].chn_index == CFG_ADC_CHANNEL_ZERO) // I0 { I0 += jdxx_getI0_qdval(pR->tJD.dot_qd + i, g_ui[UI_SW_INDEX(sw, SW_AC_IA)].chn_index, g_ui[UI_SW_INDEX(sw, SW_AC_IB)].chn_index, g_ui[UI_SW_INDEX(sw, SW_AC_IC)].chn_index); } else { I0 += jdxx_get_qdval(pR->tJD.dot_qd + i, g_ui[pJdxx->i0_chan].chn_index); } } #ifdef XDL_PRINT rt_printf("\r\nV_I0积分:V=%d I0=%d", v0, I0); #endif // V0是否突变 // if(_AbsL(v0)<=(DWORD)pJdxx->jd_volzero*dotsnum) return 0; //电压突变太小 // 区内区外判断 if ((v0 > 0 && I0 > 0) || (v0 < 0 && I0 < 0)) return 1; else return -1; } // 判界内界外,零序电流和参考电压比波形的相似度 chnl 为相别 // 返回:ret=-1 无法判出相、区内区外 // ret=0 正确判出 int jdxx_checkjd(int sw) { int pha0, ret0; JDXX_SET *pJdxx = &tJDXX_val[sw]; TRELAY_T *pR = &g_tRelay[sw]; if (pJdxx->bTT_jdxx_cph) { pha0 = jdxx_Iabc_check_dir(sw); // 通过三相电流方向判断接地相 ret0 = jdxx_VI0_dir(sw, pha0); // U 和I0的积分:同向为1,已向为 1 if (ret0 == 0) { #ifdef XDL_PRINT if (pha0 < 0) { rt_printf("\r\n判相失败!pha=%d", pha0); } else { rt_printf("\r\n区内区外判别失败!电压零流方向=%d(1:界内,-1:界外)", ret0); } #endif return -1; } #ifdef XDL_PRINT rt_printf("\r\n暂态接地判据:sw=%d 电压零流方向=%d(1:界内,-1:界外) pha=%d", sw, ret0, pha0); #endif // rcd_start(sw,RECORD_TYPE_LXGL, RECORD_LEN_TZQD); //录波类型:跳闸类 // 判断界内 if (((pRunSet->tSwSet[sw].bTT_Current_Inv ^ get_power_on_dir(sw)) && ret0 < 0) || (!(pRunSet->tSwSet[sw].bTT_Current_Inv ^ get_power_on_dir(sw)) && ret0 > 0)) { pR->tJD.tc_result = 1; } else { pR->tJD.tc_result = 0; } } else // U0参与逻辑 { pha0 = 4; // 不判相 ret0 = jdxx_VI0_dir(sw, pha0); // U 和I0的积分,同向为1 ,反向为-1 if (ret0 == 0) { #ifdef XDL_PRINT rt_printf("\r\n区内区外判别失败!电压零流方向=%d(1:界内,-1:界外)", ret0); #endif return -1; } #ifdef XDL_PRINT rt_printf("\r\n暂态接地判据:sw=%d 电压零流方向=%d(1:界内,-1:界外)", sw, -ret0); // U0/I0反相为界内,同向为界外 #endif // rcd_start(sw,RECORD_TYPE_LXGL, RECORD_LEN_TZQD); //录波类型:跳闸类 // 判断界内 #if defined FUN_JDXX_JXJD || defined DTU_HUNAN if (((pRunSet->tSwSet[sw].bTT_Current_Inv ^ get_power_on_dir(sw)) && ret0 > 0) || // 极性 (!(pRunSet->tSwSet[sw].bTT_Current_Inv ^ get_power_on_dir(sw)) && ret0 < 0)) #else if ((((pRunSet->tSwSet[sw].bTT_Current_Inv ^ get_power_on_dir(sw)) && ret0 > 0) || // 极性 (!(pRunSet->tSwSet[sw].bTT_Current_Inv ^ get_power_on_dir(sw)) && ret0 < 0)) && (g_ui[pJdxx->i0_chan].m2[0] >= pJdxx->jd_qdval2)) // I0幅值 #endif { pR->tJD.tc_result = 1; } else { pR->tJD.tc_result = 0; } #ifdef XDL_PRINT rt_printf("\r\n首端算法结论:sw=%d result=%d(1:界内,-1:界外)", sw, pR->tJD.tc_result); #endif } return 0; } /********************************** //接地选线启动逻辑 **********************************/ // 有功分量判据 void jdxx_yg_qd(int sw) { int ret0; float pea, th_pea; TRELAY_T *pR = &g_tRelay[sw]; JDXX_SET *pJdxx = &tJDXX_val[sw]; // 判区内区外 if (pR->tJD.jd_step == JD_STEP_QD) { // 有功分量选择 if (g_ui[UI_JDXX_I0S_INDEX].chn_index != CFG_ADC_CHANNEL_ZERO) pea = g_ui_p0[sw].Peas; else pea = g_ui_p0[sw].Pea; // 有功门槛值,约15K if (g_equ_config_ac[g_sw_pub.ac_cfg_index[pJdxx->i0_chan]].scale == EQU_SCALE_EVT_6V50_100V) th_pea = 0.02; //_sw_ui_e_k(int ui_index) else th_pea = 0.30; // 100/6.5*0.02=0.30 // 有功分量判区内区外 if (pRunSet->tSwSet[sw].bTT_Current_Inv ^ get_power_on_dir(sw)) { if ((pea - th_pea) > 0) ret0 = -1; // 0.30--100V;0.02--6.5V else ret0 = 1; } else { if ((pea + th_pea) < 0) ret0 = -1; else ret0 = 1; } #ifdef XDL_PRINT rt_printf("\r\n暂态接地判据:sw=%d 电压零流方向=%d(1:界内,-1:界外)", sw, -ret0); // U0/I0反相为界内,同向为界外 #endif // rcd_start(sw,RECORD_TYPE_LXGL, RECORD_LEN_TZQD); //录波类型:跳闸类 // 判断界内 if (ret0 < 0) { pR->tJD.tc_result = 1; } else { pR->tJD.tc_result = 0; } pR->tJD.jd_step = JD_STEP_SSFAULT; } } // 首半波判据 #define NUM_QDFX (ADC_REC_SAMPLE << 2) // 四个周波 void jdxx_qd(int sw) { s32 qdval; int mod, dir; u32 dotcnt, dotend, dotcur; //,dotnum; JDXX_SET *pJdxx = &tJDXX_val[sw]; TRELAY_T *pR = &g_tRelay[sw]; mod = (int)(g_count_156us & 0x03); dotend = (g_adc_dots_count)*ADC_REC_SAMPLE_RATE + mod; if (pR->tJD.jd_step == JD_STEP_RST || pR->tJD.jd_step == JD_STEP_SSFAULT) return; // tbl dotcur = dotend - NUM_QDFX; dir = 0; for (dotcnt = 0; dotcnt < NUM_QDFX; dotcnt++) // U0已持续四个周波 ADC_REC_SAMPLE*3 { u32 cur; cur = dotcur & ADC_REC_DOTS_MASK; // 当前采样点 dotcur++; // 启动判断 if (pR->tJD.jd_step == JD_STEP_QD) { if (g_ui[pJdxx->i0_chan].chn_index == CFG_ADC_CHANNEL_ZERO) { qdval = jdxx_getI0_qdval(cur, g_ui[UI_SW_INDEX(sw, SW_AC_IA)].chn_index, g_ui[UI_SW_INDEX(sw, SW_AC_IB)].chn_index, g_ui[UI_SW_INDEX(sw, SW_AC_IC)].chn_index); } else { qdval = jdxx_get_qdval(cur, g_ui[pJdxx->i0_chan].chn_index); } if (_AbsL(qdval) > pR->tJD.jd_qdval) // 大于启动值 { pR->tJD.jd_step = JD_STEP_CHECK; pR->tJD.qdPoints = 0; pR->tJD.dot_qd = cur; // 保存当前启动点的采样序号 if (qdval > 0) { dir = 1; } else if (qdval < 0) { dir = -1; } #ifdef XDL_PRINT rt_printf_time("jdxx:JD_STEP_CHECK sw=%d dot=%d qdval=%d set=%d\r\n", sw, cur, qdval, pR->tJD.jd_qdval); #endif } } else if (pR->tJD.jd_step == JD_STEP_CHECK) // 收集数据 { if (g_ui[pJdxx->i0_chan].chn_index == CFG_ADC_CHANNEL_ZERO) { qdval = jdxx_getI0_qdval(cur, g_ui[UI_SW_INDEX(sw, SW_AC_IA)].chn_index, g_ui[UI_SW_INDEX(sw, SW_AC_IB)].chn_index, g_ui[UI_SW_INDEX(sw, SW_AC_IC)].chn_index); } else { qdval = jdxx_get_qdval(cur, g_ui[pJdxx->i0_chan].chn_index); } if ((qdval * dir < 0) // 反相 || (_AbsL(qdval) < pR->tJD.jd_qdval)) // 小于启动值 { #ifdef XDL_PRINT if (qdval * dir < 0) { rt_printf("jdxx:sw=%d dot=%d;启动后干扰\r\n", sw, cur); } else { rt_printf("jdxx:sw=%d dot=%d;启动后有值小于启动值\r\n", sw, cur); } #endif pR->tJD.jd_step = JD_STEP_QD; continue; } pR->tJD.qdPoints++; if (pR->tJD.qdPoints >= pJdxx->jd_qdPoints) // 大于启动个数,进入数据收集阶段,可启动录波 { pR->tJD.jd_step = JD_STEP_COLLECT; pR->tJD.adPoints = 0; #ifdef XDL_PRINT rt_printf("jdxx:sw=%d dot=%d;JD_STEP_COLLECT\r\n", sw, cur); #endif } } else if (pR->tJD.jd_step == JD_STEP_COLLECT) // 收集数据 { pR->tJD.adPoints++; if (pR->tJD.adPoints >= pJdxx->jd_faultPoints) { pR->tJD.jd_step = JD_STEP_CTFAULT; #ifdef XDL_PRINT rt_printf("jdxx:sw=%d JD_STEP_CTFAULT! dcnt=%d\r\n", sw, dotcnt); #endif } } else if (pR->tJD.jd_step == JD_STEP_CTFAULT) // 暂态特征判断 { int i, ret; bool bFault = false; s32 val = 0; int ovQDpoints = 0; if (!bFault) // 故障未确认 { for (i = pJdxx->jd_qdPoints; i < pJdxx->jd_faultPoints + pJdxx->jd_qdPoints; i++) { u32 cur = (pR->tJD.dot_qd + i) & ADC_REC_DOTS_MASK; if (g_ui[pJdxx->i0_chan].chn_index == CFG_ADC_CHANNEL_ZERO) { val = _AbsL(jdxx_getI0_qdval(cur, g_ui[UI_SW_INDEX(sw, SW_AC_IA)].chn_index, g_ui[UI_SW_INDEX(sw, SW_AC_IB)].chn_index, g_ui[UI_SW_INDEX(sw, SW_AC_IC)].chn_index)); } else { val = _AbsL(jdxx_get_qdval(cur, g_ui[pJdxx->i0_chan].chn_index)); } if (val > pR->tJD.jd_qdval) { ovQDpoints++; } if (ovQDpoints > pJdxx->jd_surePoints) { bFault = true; break; } } } // 故障确认,判断暂态接地线路逻辑 if (bFault) { #ifdef FUN_JDXX_TBLQD if (pJdxx->bTT_jdxx_p0dir) { pR->tJD.tc_result = 1; // 启动 pR->tJD.adPoints = 0; pR->tJD.jd_step = JD_STEP_SSFAULT; if (soe_check(EV_LX_XDL_QD + sw * EV_SW_NUM) == false) { soe_record_ev(EV_LX_XDL_QD + sw * EV_SW_NUM, 1, 0, 0, 0); } #ifdef XDL_PRINT rt_printf("jdxx:sw=%d JD_STEP_SSFAULT\r\n", sw); #endif return; } else #endif { ret = jdxx_checkjd(sw); if (ret < 0) { pR->tJD.jd_step = JD_STEP_RST; #ifdef XDL_PRINT rt_printf("\r\njdxx_fg:sw=%d JD_STEP_FG", sw); #endif return; } else { pR->tJD.adPoints = 0; pR->tJD.jd_step = JD_STEP_SSFAULT; if (soe_check(EV_LX_XDL_QD + sw * EV_SW_NUM) == false) { soe_record_ev(EV_LX_XDL_QD + sw * EV_SW_NUM, 1, 0, 0, 0); } #ifdef XDL_PRINT rt_printf("jdxx:sw=%d JD_STEP_SSFAULT\r\n", sw); #endif return; } } } else // 干扰,复归 { #if 0 // def FUN_JDXX_TBLQD //只需要U0期间出现了I0突变,就ok { #ifdef XDL_PRINT rt_printf("jdxx:sw=%d 启动后确认干扰\r\n",sw); #endif pR->tJD.jd_step=JD_STEP_QD; continue; } #else if (dotcnt < (NUM_QDFX - 128)) // 最后1周波前必须确认(512-128) { #ifdef XDL_PRINT rt_printf("jdxx:sw=%d 启动后确认干扰\r\n", sw); #endif pR->tJD.jd_step = JD_STEP_QD; continue; } else { pR->tJD.adPoints = 0; pR->tJD.jd_step = JD_STEP_RST; #ifdef XDL_PRINT rt_printf("\r\njdxx_fg:sw=%d JD_STEP_FG!(not sure)", sw); #endif return; } #endif } } } } // 稳态判据 #define ANGF150 (150 * 65536) // 150度 #define ANGN150 ((-150) * 65536) //-150度 #define ANGF30 (30 * 65536) // 30度 #define ANGN30 ((-30) * 65536) //-30度 #ifdef FUN_JDXX_12FS // 针对电科院一二次融合测试 #define ANGF96 (110 * 65536) // 110度 #define ANGN96 ((-110) * 65536) //-110度 #define ANGF45 (30 * 65536) // 30度 #define ANGN45 ((-30) * 65536) //-30度 #else #define ANGF96 (96 * 65536) // 96度 #define ANGN96 ((-96) * 65536) //-96度 #define ANGF45 (45 * 65536) // 45度 #define ANGN45 ((-45) * 65536) //-45度 #endif #define ANGF360 (360 * 65536) // 360度 #define ANGF90 (90 * 65536) // 90度 #define ANGN90 ((-90) * 65536) //-90度 #define ANGF70 (70 * 65536) // 70度 #define ANGN70 ((-70) * 65536) //-70度 int jdxx_angle_range(int sw) { int i, ret; long deltaA; TRELAY_T *pR = &g_tRelay[sw]; #if 1 long max, min; max = pR->tJD.ui_angle[0]; min = pR->tJD.ui_angle[0]; for (i = 1; i < NUM_ANGLE; i++) { if (pR->tJD.ui_angle[i] > max) { max = pR->tJD.ui_angle[i]; } else if (pR->tJD.ui_angle[i] < min) { min = pR->tJD.ui_angle[i]; } } #ifdef XDL_PRINT rt_printf("jdxx:sw=%d AngleMax=%d , AngleMin=%d!\r\n", sw, (max >> 16), (min >> 16)); #endif if ((max > ANGF90) && (min < ANGN90)) // 在2-3象限 { for (i = 0; i < NUM_ANGLE; i++) { if (pR->tJD.ui_angle[i] < 0) { pR->tJD.ui_angle[i] += ANGF360; // 归一化到0~360 } #ifdef XDL_PRINT rt_printf("jdxx:sw=%d Angle23=%d!\r\n", sw, (pR->tJD.ui_angle[i] >> 16)); #endif } } // 相角 deltaA = 0; for (i = 0; i < NUM_ANGLE; i++) { deltaA += pR->tJD.ui_angle[i]; } deltaA /= NUM_ANGLE; #else int j; ret = 3; deltaA = 0; for (i = 0, j = 0; i < NUM_ANGLE; i++) { if (pR->tJD.ui_angle[i] > 0) continue; else { deltaA += pR->tJD.ui_angle[i]; j++; } } if (j == 0) { ret = 3; // 非界外 } else { deltaA /= j; } #endif // 判区内区外 ret = 3; if (pRunSet->tSwSet[sw].bTT_Current_Inv ^ get_power_on_dir(sw)) { if (deltaA > ANGF45 && deltaA < ANGF96) ret = 2; // 界外 } else { if (deltaA > ANGN96 && deltaA < ANGN45) ret = 2; // 界外 } #ifdef XDL_PRINT if (ret == 2) { rt_printf("jdxx:sw=%d 零序功率方向判区外接地!ret0=%d!Angle=%d!\r\n", sw, ret, (deltaA >> 16)); } #endif return ret; } /************************************************************************** 函数名称:CalcUIzAng 函数版本:1.00 函数功能说明:接地零序角度必须归一到-180-180。(部分项目角度没有归一化到-180-180) 输入参数:long Real1, long Imag1, long Imag2, long Imag2 输出参数: 返回值: long 角差; **************************************************************************/ long CalcUIzAng(long Real1, long Imag1, long Real2, long Imag2) { long lTmp; lTmp = _AngPQ(Real1, Imag1) - _AngPQ(Real2, Imag2); // 规格化在0 ~ 360之间 if (lTmp < 0) { lTmp += ANGLE_P360; } if (lTmp > ANGLE_P180) // 转换为-180 ~180 { lTmp -= ANGLE_P360; } return (lTmp); } void jdxx_fault(int sw, DWORD dStep) { int ret0, ret1, bQNGZ, u0_index; bool b_tz, b_gj; JDXX_SET *pJdxx = &tJDXX_val[sw]; TRELAY_T *pR = &g_tRelay[sw]; #ifdef ITEM_FYF630Z b_gj = pJdxx->bTT_jdxx_gj; b_tz = pJdxx->bTT_jdxx_tz; #ifdef BH_JZ_YB if (!g_tRelay[sw].run_stu.bh_ck) #else if (pRunSet->tSwSet[sw].bSW_JZ) #endif { if (b_tz) { b_tz = false; b_gj = true; } } #elif defined DFTU_LINUX_ZXJC || defined DTU_HUNAN || defined DTU4_GW_TEST || defined FB_SHANDONG || defined FBS_GX b_gj = pJdxx->bTT_jdxx_gj; b_tz = pJdxx->bTT_jdxx_tz; #else b_gj = pJdxx->bTT_jdxx_gj; b_tz = pJdxx->bTT_jdxx_tz; if (JZS_ALL_EN(sw)) // 集中模式或者就地式FA自适应非首开关不跳闸 { if (b_tz) { b_tz = false; b_gj = true; } } #endif if (pR->tJD.jd_step == JD_STEP_SSFAULT) // 稳态逻辑判定 { // 判稳态电流 #if defined FUN_JDXX_JXJD || defined DTU_HUNAN ret1 = 1; #else if (g_ui[pJdxx->i0_chan].m2[0] >= pJdxx->jd_qdval2) { ret1 = 1; } else { ret1 = 0; if (pR->tJD.tc_result) { pR->tJD.tc_result = 0; #ifdef XDL_PRINT rt_printf("jdxx:sw=%d ret1=%d--暂态误判!\r\n", sw, ret1); #endif } } #endif // 判相位 if (pR->tJD.jd_u0_12 == 1) u0_index = PUB_AC_U01; else u0_index = PUB_AC_U02; // 判稳态相位 if (!pJdxx->bTT_jdxx_p0dir) { ret0 = 3; } else { long deltaA; // 计算零序功率角度:-180~180 (固定大通道) if (g_ui[pJdxx->i0_chan].m2[0] >= pJdxx->jd_qdval2) { deltaA = CalcUIzAng(g_ui[u0_index].ri.r, g_ui[u0_index].ri.i, g_ui[pJdxx->i0_chan].ri.r, g_ui[pJdxx->i0_chan].ri.i); if ((g_ui[UI_SW_INDEX(sw, SW_AC_I0s)].chn_index != CFG_ADC_CHANNEL_ZERO) && (g_ui[UI_JDXX_I0_INDEX].m2[0] > pJdxx->jd_ov_val2)) { deltaA = CalcUIzAng(g_ui[u0_index].ri.r, g_ui[u0_index].ri.i, g_ui[UI_JDXX_I0_INDEX].ri.r, g_ui[UI_JDXX_I0_INDEX].ri.i); } } else // 区外处理 { if (pRunSet->tSwSet[sw].bTT_Current_Inv ^ get_power_on_dir(sw)) { deltaA = ANGF90; } else { deltaA = ANGN90; } } #ifdef XDL_PRINT if (pR->tJD.con_angle < NUM_ANGLE) rt_printf("jdxx:sw=%d Z_angle=%d\r\n", sw, (deltaA >> 16)); #endif #ifdef CN_AREA_GW_SHANXI if (deltaA > ANGF30 && deltaA < ANGF150) { if (pRunSet->tSwSet[sw].bTT_Current_Inv ^ get_power_on_dir(sw)) { ret0 = 2; // 界外 } else { ret0 = 1; // 界内 } } else if (deltaA > ANGN150 && deltaA < ANGN30) { if (pRunSet->tSwSet[sw].bTT_Current_Inv ^ get_power_on_dir(sw)) { ret0 = 1; // 界内 } else { ret0 = 2; // 界外 } } else { ret0 = 0; // 干扰 #ifdef XDL_PRINT rt_printf("jdxx:sw=%d 零序功率方向不正确,非接地!\r\n", sw); #endif } #elif defined FUN_JDXX_SS_ANGLE if (deltaA > ANGF90 && deltaA < ANGF180) { if (pRunSet->tSwSet[sw].bTT_Current_Inv ^ get_power_on_dir(sw)) { if (pR->tJD.dir_cnt) { pR->tJD.dir_cnt--; ret0 = 1; // 界内 } if (pR->tJD.dir_cnt == 0) { ret0 = 2; // 界外 #ifdef XDL_PRINT rt_printf("jdxx:sw=%d 零序功率方向抖动,非接地!\r\n", sw); #endif } } else { // pR->tJD.dir_cnt=(pR->tJD.dir_cnt+1)%20; if (pR->tJD.dir_cnt < 20) { pR->tJD.dir_cnt++; } if (pR->tJD.dir_cnt) { ret0 = 1; // 界内 } } } else if (deltaA > ANGN180 && deltaA < ANGN90) { if (pRunSet->tSwSet[sw].bTT_Current_Inv ^ get_power_on_dir(sw)) { // pR->tJD.dir_cnt=(pR->tJD.dir_cnt+1)%20; if (pR->tJD.dir_cnt < 20) { pR->tJD.dir_cnt++; } if (pR->tJD.dir_cnt) { ret0 = 1; // 界内 } } else { if (pR->tJD.dir_cnt) { pR->tJD.dir_cnt--; ret0 = 1; // 界内 } if (pR->tJD.dir_cnt == 0) { ret0 = 2; // 界外 #ifdef XDL_PRINT rt_printf("jdxx:sw=%d 零序功率方向抖动,非接地!\r\n", sw); #endif } } } else { if (pR->tJD.dir_cnt) { pR->tJD.dir_cnt--; ret0 = 1; // 界内 } if (pR->tJD.dir_cnt == 0) { ret0 = 0; // 干扰 #ifdef XDL_PRINT rt_printf("jdxx:sw=%d 零序功率方向不正确,非接地!\r\n", sw); #endif } } #else // 计算角度,判相位 if (pR->tJD.con_angle < NUM_ANGLE) { pR->tJD.ui_angle[pR->tJD.con_angle++] = deltaA; return; } else { ret0 = jdxx_angle_range(sw); } #endif } // U0强制启动 if (TT_U0jd) { if (pRunSet->tSwSet[sw].bTT_Current_Inv ^ get_power_on_dir(sw)) { ret0 = 2; ret1 = 0; } else { ret0 = 3; ret1 = 1; } } // 故障处理 if (pR->tJD.tc_result && (ret0 == 1 || ret0 == 3) && (ret1 == 1)) { bQNGZ = 1; } else if ((pR->tJD.tc_result == 0 && (ret0 == 2 || ret0 == 3)) || (ret1 == 0)) { bQNGZ = 2; } else { bQNGZ = 0; } // 区内 if (bQNGZ == 1) { #ifdef HJS_XDLJD pR->tJD.sta.bFlag.bJd_qn = 1; // 区内故障 #endif // 告警 if (b_gj) { RunTR(&pR->tJD.tJDXXAlarmTime, bQNGZ, dStep); // 故障持续时间 pR->tJD.sta.bFlag.bGj = pR->tJD.tJDXXAlarmTime.boolTrip; if (pR->tJD.sta.bFlag.bGj) { if (soe_check(EV_JDXX_GJ + sw * EV_SW_NUM) == false) { // 断面 DWORD I0, U0; I0 = _Mul_Div_U(sqrt_32fix(g_ui[UI_SW_INDEX(sw, SW_AC_I0)].m2[0]), 256, g_ui[UI_SW_INDEX(sw, SW_AC_I0)].m2_factor_k); U0 = _Mul_Div_U(sqrt_32fix(g_ui[u0_index].m2[0]), 256, g_ui[u0_index].m2_factor_k); pR->tJD.sta.bFlag.bGJLed = true; soe_record_ev(EV_JDXX_GJ + sw * EV_SW_NUM, 1, I0, U0, 0); if (pJdxx->bTT_jdxx_fault_all) { if (!soe_check(EV_ALL_FAULT + sw * EV_SW_NUM)) // 保护总 { soe_record_ev(EV_ALL_FAULT + sw * EV_SW_NUM, 1, 0, 0, 0); } } // 故障处理完毕,进入复归处理流程 if (!b_tz) // 未投出口 { pR->tJD.tc_result = 0; pR->tJD.jd_step = JD_STEP_RST; #ifdef XDL_PRINT rt_printf("\r\njdxx_fault:sw=%d step_rst", sw); #endif } } } } // 出口 if (b_tz) { RunTR(&pR->tJD.tJDXXTripTime, bQNGZ, dStep); // 故障持续时间 pR->tJD.sta.bFlag.bTz = pR->tJD.tJDXXTripTime.boolTrip; #ifdef HJS_XDLJD if (pR->tJD.sta.bFlag.bHjsTz) { pR->tJD.sta.bFlag.bTz_prot = pR->tJD.sta.bFlag.bTz; } else { pR->tJD.sta.bFlag.bTz_prot = 0; } #endif if (pR->tJD.sta.bFlag.bTz) // 出口 { // 断面 DWORD I0, U0; I0 = _Mul_Div_U(sqrt_32fix(g_ui[UI_SW_INDEX(sw, SW_AC_I0)].m2[0]), 256, g_ui[UI_SW_INDEX(sw, SW_AC_I0)].m2_factor_k); U0 = _Mul_Div_U(sqrt_32fix(g_ui[u0_index].m2[0]), 256, g_ui[u0_index].m2_factor_k); pR->tJD.sta.bFlag.bTZLed = true; // soe #ifdef FUN_JDXX_JXJD if (soe_check(EV_JDXX_YJ_TZ + sw * EV_SW_NUM) == false) { soe_record_ev(EV_JDXX_YJ_TZ + sw * EV_SW_NUM, 1, I0, U0, 0); #ifndef HJS_XDLJD if (soe_check(EV_JDXX_TZ + sw * EV_SW_NUM) == false) // 区内跳闸 { soe_record_ev(EV_JDXX_TZ + sw * EV_SW_NUM, 1, I0, U0, 0); } #else if ((soe_check(EV_JDXX_TZ + sw * EV_SW_NUM) == false) && (!pR->tJD.sta.bFlag.bHjsTz)) // 区内跳闸 { soe_record_ev(EV_JDXX_TZ + sw * EV_SW_NUM, 1, I0, U0, 0); } #endif if (pJdxx->bTT_jdxx_fault_all) { if (soe_check(EV_ALL_FAULT + sw * EV_SW_NUM) == false) // 保护总 { soe_record_ev(EV_ALL_FAULT + sw * EV_SW_NUM, 1, 0, 0, 0); } } #ifdef XDL_PRINT rt_printf("\r\n区内永久接地动作"); #endif } #else if (soe_check(EV_JDXX_TZ + sw * EV_SW_NUM) == false) { soe_record_ev(EV_JDXX_TZ + sw * EV_SW_NUM, 1, I0, U0, 0); if (!soe_check(EV_ALL_FAULT + sw * EV_SW_NUM)) // 保护总 { soe_record_ev(EV_ALL_FAULT + sw * EV_SW_NUM, 1, 0, 0, 0); } #ifdef XDL_PRINT rt_printf("\r\n区内接地动作"); #endif } #endif // 故障处理完毕,进入复归处理流程 pR->tJD.tc_result = 0; pR->tJD.jd_step = JD_STEP_RST; #ifdef FUN_JDXX_JXJD pR->tJD.cnt_sdelay = 0; pR->tJD.cnt_ldelay = 0; #endif #ifdef XDL_PRINT rt_printf("\r\njdxx_fault:T[0]=%d!", pR->tJD.time_qd / USTIMER_SEC); rt_printf("\r\njdxx_fault:sw=%d step_rst!", sw); #endif } } } else if (bQNGZ == 2) // 区外 { if (soe_check(EV_JDXX_JWGZ + sw * EV_SW_NUM) == false) // soe返回 { // 断面 DWORD I0, U0; I0 = _Mul_Div_U(sqrt_32fix(g_ui[UI_SW_INDEX(sw, SW_AC_I0)].m2[0]), 256, g_ui[UI_SW_INDEX(sw, SW_AC_I0)].m2_factor_k); U0 = _Mul_Div_U(sqrt_32fix(g_ui[u0_index].m2[0]), 256, g_ui[u0_index].m2_factor_k); soe_record_ev(EV_JDXX_JWGZ + sw * EV_SW_NUM, 1, I0, U0, 0); rt_printf("\r\n区外接地"); } // 故障处理完毕,进入复归处理流程 #ifdef HJS_XDLJD pR->tJD.sta.bFlag.bJd_qn = 0; // 区外故障 #endif pR->tJD.tc_result = 0; pR->tJD.jd_step = JD_STEP_RST; #ifdef XDL_PRINT rt_printf("\r\njdxx_fault:sw=%d step_rst", sw); #endif } else // if((tJD[sw].tc_result && ret0==2)||(tJD[sw].tc_result==0 && ret0==1)) { // 故障处理完毕,进入复归处理流程 #ifdef HJS_XDLJD pR->tJD.sta.bFlag.bJd_qn = 0; // 区外故障 #endif pR->tJD.tc_result = 0; pR->tJD.jd_step = JD_STEP_RST; #ifdef XDL_PRINT rt_printf("\r\njdxx:sw=%d 暂态与稳态矛盾,非接地!", sw); rt_printf("\r\njdxx_fault:sw=%d step_rst", sw); #endif } } } #define ANGF145 (145 * 65536) // 145度 #define ANGF95 (95 * 65536) // 95度 #define ANGN145 ((-145) * 65536) //-145度 #define ANGN95 ((-95) * 65536) //-95度 #ifdef PT_DX_LOCK_XDL static bool check_pt_ok(u32 sw) { TSETSW *pSet = &pRunSet->tSwSet[sw]; if (((FA_ALL_EN(sw) && (pSet->bTT_fa_ptdx)) || (BH_ALL_EN(sw) && (pSet->bTT_bh_ptdx))) && (soe_check(EV_PT1ERR + sw * EV_SW_NUM) || soe_check(EV_PT2ERR + sw * EV_SW_NUM))) { return false; } return true; } #endif void jdxx_pro(int sw, DWORD dStep) // 接地故障判断 5ms中断中处理 { bool bQD1, bQD2, bQD3, bQD4, bQD5; int soeno; TRELAY_T *pR = &g_tRelay[sw]; JDXX_SET *pJdxx = &tJDXX_val[sw]; // if(!pJdxx->bTT_jdxx) return; #ifdef DFTU_LINUX_ZXJC if (!(pRunSet->tSwSet[sw].bTT_BH && pJdxx->bTT_jdxx)) return; // g_run_stu.bhall && #else if (!(FUN_ALL_EN(sw) && pJdxx->bTT_jdxx)) return; // g_run_stu.bhall && #endif #ifdef PT_DX_LOCK_XDL if (!check_pt_ok(sw)) { return; } #endif #ifdef FUN_JDXX_JXJD // 分位清计次 if (pR->tSWST.uSWST.bFlag.bTZWZ) // 跳位无流 { pR->tJD.cnt_sdelay = 0; pR->tJD.cnt_ldelay = 0; } #endif // 定义通道 if (pRunSet->bTT_U0ZC) { if (((g_sw_pub.ui_flags & UI_FLAGS_MAKE_U01) == 0) && ((g_sw_pub.ui_flags & UI_FLAGS_MAKE_U02) == 0)) return; } else { if (g_ui[PUB_AC_U01].chn_index == CFG_ADC_CHANNEL_ZERO && g_ui[PUB_AC_U02].chn_index == CFG_ADC_CHANNEL_ZERO) return; } // 选相 if (pJdxx->bTT_jdxx_cph) { if ((g_ui[UI_SW_INDEX(sw, SW_AC_IA)].chn_index == CFG_ADC_CHANNEL_ZERO) || (g_ui[UI_SW_INDEX(sw, SW_AC_IB)].chn_index == CFG_ADC_CHANNEL_ZERO) || (g_ui[UI_SW_INDEX(sw, SW_AC_IC)].chn_index == CFG_ADC_CHANNEL_ZERO)) return; } // U0启动录波 bQD1 = (g_ui[PUB_AC_U01].m2[0] > pJdxx->jd_U0gl); bQD2 = (g_ui[PUB_AC_U02].m2[0] > pJdxx->jd_U0gl); RunTR(&pR->tJD.tJDXXU01Time, bQD1, dStep); // U0计算时间:20ms RunTR(&pR->tJD.tJDXXU02Time, bQD2, dStep); // U0计算时间:20ms // 相有压有流 #ifdef CN_AREA_FUJIAN_TEST // 福建电压为小信号 bQD3 = (g_sw_pub.m2_max[3] > pRunSet->dVOL70V_SQR_U2); //(g_ui[PUB_AC_UAB1].chn_index!=CFG_ADC_CHANNEL_ZERO || g_ui[PUB_AC_UBC1].chn_index!=CFG_ADC_CHANNEL_ZERO) #else bQD3 = (g_sw_pub.m2_max[2] > pRunSet->dVOL70V_SQR); //(g_ui[PUB_AC_UAB1].chn_index!=CFG_ADC_CHANNEL_ZERO || g_ui[PUB_AC_UBC1].chn_index!=CFG_ADC_CHANNEL_ZERO) #endif bQD4 = (g_sw_pub.m2_max[3] > pRunSet->dVOL70V_SQR); //(g_ui[PUB_AC_UAB2].chn_index!=CFG_ADC_CHANNEL_ZERO || g_ui[PUB_AC_UBC2].chn_index!=CFG_ADC_CHANNEL_ZERO) bQD5 = (g_sw[sw].m2_min > pRunSet->dIWL_SQR[sw]); RunTR(&pR->tJD.tJDXXU1yyTime, bQD3, dStep); // Ul有压时间时间:60ms RunTR(&pR->tJD.tJDXXU2yyTime, bQD4, dStep); // Ul有压时间时间:60ms RunTR(&pR->tJD.tJDXXIylTime, bQD5, dStep); // Iph有流时间时间:60ms // 取通道启动前的采样值,作为零漂值,在故障复归时使用 // if(!bQD1 && !bQD2) //{ // tJD[sw].dot_save=(g_adc_dots_count)*ADC_REC_SAMPLE_RATE+mod; // jdxx_getzeroval(sw); //} // U01故障处理 soeno = EV_XDL_U0GJ1 + sw * EV_SW_NUM; if (pR->tJD.tJDXXU01Time.boolTrip) { if (soe_check(soeno) == false) { DWORD u0; pR->tJD.jd_u0_12 = 1; u0 = _Mul_Div_U(sqrt_32fix(g_ui[PUB_AC_U01].m2[0]), 256, g_ui[PUB_AC_U01].m2_factor_k); soe_record_ev(soeno, 1, u0, 0, 0); // 置启动标志,记录启动不能放在录波启动成功的条件里,避免启动失败后频繁打印!记录启动时刻. if (pRunSet->tSwSet[sw].bTT_Power_v2 == 0) { jdxx_fg(sw); // 零压启动强制复归 #ifdef JDXX_YXEV_RST jdxx_yxev_rst(sw); #endif pR->tJD.time_qd = ustimer_get_origin(); rcd_start(sw, RECORD_TYPE_XDLJD, RECORD_LEN_TZQD); #ifdef XDL_PRINT rt_printf("\r\njdxx_u01_time:T[0]=%d!", pR->tJD.time_qd / USTIMER_SEC); #endif } } } else { // 计算零序功率:扩大10倍,提高计算分辨率 if (pRunSet->tSwSet[sw].bTT_Power_v2 == 0) { if (bQD1) { g_ui_p0[sw].Pea += g_ui_p0[sw].p * 10; g_ui_p0[sw].Per += g_ui_p0[sw].q * 10; g_ui_p0[sw].Peas += g_ui_p0[sw].ps * 10; g_ui_p0[sw].Pers += g_ui_p0[sw].qs * 10; } else { g_ui_p0[sw].Pea = 0; g_ui_p0[sw].Per = 0; g_ui_p0[sw].Peas = 0; g_ui_p0[sw].Pers = 0; } } // soe复归 if (soe_check(soeno) == true) { pR->tJD.jd_u0_12 = 0; soe_record_ev(soeno, 0, 0, 0, 0); jdxx_u0_rst(sw); } } // U02 soeno = EV_XDL_U0GJ2 + sw * EV_SW_NUM; if (pR->tJD.tJDXXU02Time.boolTrip) { if (soe_check(soeno) == false) { DWORD u0; pR->tJD.jd_u0_12 = 2; u0 = _Mul_Div_U(sqrt_32fix(g_ui[PUB_AC_U02].m2[0]), 256, g_ui[PUB_AC_U02].m2_factor_k); soe_record_ev(soeno, 1, u0, 0, 0); // 置启动标志,不能放在录波启动成功的条件里,避免启动失败后频繁打印!记录启动时刻. if (pRunSet->tSwSet[sw].bTT_Power_v2) { jdxx_fg(sw); // 零压启动强制复归 #ifdef JDXX_YXEV_RST jdxx_yxev_rst(sw); #endif pR->tJD.time_qd = ustimer_get_origin(); rcd_start(sw, RECORD_TYPE_XDLJD, RECORD_LEN_TZQD); #ifdef XDL_PRINT rt_printf("\r\njdxx_u02_time:T[0]=%d!", pR->tJD.time_qd / USTIMER_SEC); #endif } } } else { // 计算零序功率:扩大10倍,提高计算分辨率 if (pRunSet->tSwSet[sw].bTT_Power_v2) { if (bQD2) { g_ui_p0[sw].Pea += g_ui_p0[sw].p * 10; g_ui_p0[sw].Per += g_ui_p0[sw].q * 10; g_ui_p0[sw].Peas += g_ui_p0[sw].ps * 10; g_ui_p0[sw].Pers += g_ui_p0[sw].qs * 10; } else { g_ui_p0[sw].Pea = 0; g_ui_p0[sw].Per = 0; g_ui_p0[sw].Peas = 0; g_ui_p0[sw].Pers = 0; } } // soe复归 if (soe_check(soeno) == true) { pR->tJD.jd_u0_12 = 0; soe_record_ev(soeno, 0, 0, 0, 0); jdxx_u0_rst(sw); } } // U0达到定值,启动 if (pR->tJD.tJDXXU01Time.boolTrip || pR->tJD.tJDXXU02Time.boolTrip) { // 正常波形 if (pR->tJD.jd_step != JD_STEP_RST) { // 判电压满幅度 if (TT_U0yx && jdxx_U0_ov(sw)) { pR->tJD.jd_step = JD_STEP_RST; #ifdef XDL_PRINT rt_printf("jdxx:sw=%d 零序电压失真!\r\n", sw); #endif return; } // 判断线电压无压 if (TT_Ulyy && ((pR->tJD.tJDXXU1yyTime.boolTrip == false && pR->tJD.tJDXXU01Time.boolTrip) || (pR->tJD.tJDXXU2yyTime.boolTrip == false && pR->tJD.tJDXXU02Time.boolTrip))) { pR->tJD.jd_step = JD_STEP_RST; #ifdef XDL_PRINT rt_printf("jdxx:sw=%d 线路无压!\r\n", sw); #endif return; } // 判断相电流无流 if (TT_Ipwl && !pR->tJD.tJDXXIylTime.boolTrip) { pR->tJD.jd_step = JD_STEP_RST; #ifdef XDL_PRINT rt_printf("jdxx:sw=%d 断线无流!\r\n", sw); #endif return; } // 判断相电流相序 if (TT_Ipph && pR->tJD.tJDXXIylTime.boolTrip) // 有流 { long deltaIAB, deltaIAC; deltaIAB = CalcAngSub(g_ui[UI_SW_INDEX(sw, SW_AC_IA)].ri.r, g_ui[UI_SW_INDEX(sw, SW_AC_IA)].ri.i, g_ui[UI_SW_INDEX(sw, SW_AC_IB)].ri.r, g_ui[UI_SW_INDEX(sw, SW_AC_IB)].ri.i); deltaIAC = CalcAngSub(g_ui[UI_SW_INDEX(sw, SW_AC_IA)].ri.r, g_ui[UI_SW_INDEX(sw, SW_AC_IA)].ri.i, g_ui[UI_SW_INDEX(sw, SW_AC_IC)].ri.r, g_ui[UI_SW_INDEX(sw, SW_AC_IC)].ri.i); if (deltaIAB < ANGF95 || deltaIAB > ANGF145 || deltaIAC > ANGN95 || deltaIAC < ANGN145) { pR->tJD.jd_step = JD_STEP_RST; #ifdef XDL_PRINT rt_printf("jdxx:sw=%d : PIab=%d,PIac=%d. 三相乱序! \r\n", sw, deltaIAB >> 16, deltaIAC >> 16); #endif return; } } // 获得电流启动值 if (pR->tJD.jd_step != JD_STEP_SSFAULT) { g_ui[pJdxx->i0_chan].fz = _AmXY(g_ui[pJdxx->i0_chan].ri.r, g_ui[pJdxx->i0_chan].ri.i); pR->tJD.jd_qdval = (g_ui[pJdxx->i0_chan].fz >> 2); // 1/4 if (pR->tJD.jd_qdval < pJdxx->jd_qdval) { pR->tJD.jd_qdval = pJdxx->jd_qdval; } #ifdef XDL_PRINT rt_printf("jdxx:sw=%d 零流启动值=%d ,定值=%d!\r\n", sw, pR->tJD.jd_qdval, pJdxx->jd_qdval); // rt_printf("jdxx:sw=%d 零序有功=%f ,零序无功=%f;零序s有功=%f ,零序s无功=%f!\r\n",sw,g_ui_p0[sw].Pea,g_ui_p0[sw].Per,g_ui_p0[sw].Peas,g_ui_p0[sw].Pers); #endif } // fault #ifdef CN_AREA_GW_SHANXI if (pJdxx->bTT_jdxx_p0dir) { if (pR->tJD.jd_step == JD_STEP_QD) { if (g_ui[UI_JDXX_I0_INDEX].m2[0] >= pJdxx->jd_zero_N) { pR->tJD.tc_result = 1; pR->tJD.jd_step = JD_STEP_SSFAULT; #ifdef XDL_PRINT rt_printf("jdxx:sw=%d 功率方向投,进入稳态判据!\r\n", sw); #endif } } } else #endif { #if 0 if(pJdxx->jd_type==1)//有功分量法 { jdxx_yg_qd(sw); } else//首半波 #endif if (TT_U0jd) { if (pR->tJD.jd_step == JD_STEP_QD) { pR->tJD.tc_result = 1; pR->tJD.jd_step = JD_STEP_SSFAULT; #ifdef XDL_PRINT rt_printf("jdxx:sw=%d 零压启动,进入稳态判据!\r\n", sw); #endif } } else { jdxx_qd(sw); } } jdxx_fault(sw, dStep); } } else // rst { jdxx_rst(sw, dStep); } } ///////////////////////////////////////////////////////////////////////// void _getjdxxdz_inf(void) { int i, file_length; struct file *pfile; u8 *filebuf; loff_t pos; // 打开文件 pfile = rt_file_open("/app/data/pcolcfg.ini", O_RDONLY, 0); if (IS_ERR(pfile)) { dp_err_n_c_rt("error! 无法打开 pcolcfg.ini"); goto jdxx_err; } // 得到文件长度 file_length = rt_file_getfile_size(pfile); // file_length = rt_file_getfile_size(pfile); if (file_length <= 0) { rt_file_close(pfile, 0); goto jdxx_err; } // 分配内存 filebuf = rt_malloc(file_length); if ((filebuf) == NULL) { rt_file_close(pfile, 0); goto jdxx_err; } pos = 0; if (rt_file_read(pfile, filebuf, file_length, &pos) != file_length) { rt_file_close(pfile, 0); rt_free(filebuf); goto jdxx_err; } // 找到\r\n位置,得到一行长度 for (i = 0; i < file_length; i++) { if (strncmp(&filebuf[i], "TT_U0yx", 7) == 0) { TT_U0yx = getstrval(&filebuf[i]); } else if (strncmp(&filebuf[i], "TT_Ipwl", 7) == 0) { TT_Ipwl = getstrval(&filebuf[i]); } else if (strncmp(&filebuf[i], "TT_Ipph", 7) == 0) { TT_Ipph = getstrval(&filebuf[i]); } else if (strncmp(&filebuf[i], "TT_Ulyy", 7) == 0) { TT_Ulyy = getstrval(&filebuf[i]); } else if (strncmp(&filebuf[i], "TT_U0jd", 7) == 0) { TT_U0jd = getstrval(&filebuf[i]); break; } } if (i >= file_length) { TT_U0yx = 0; TT_Ipwl = 0; TT_Ipph = 0; TT_Ulyy = 0; TT_U0jd = 0; } #ifdef XDL_PRINT rt_printf("TT_U0yx = %d\r\n", TT_U0yx); rt_printf("TT_Ipwl = %d\r\n", TT_Ipwl); rt_printf("TT_Ipph = %d\r\n", TT_Ipph); rt_printf("TT_Ulyy = %d\r\n", TT_Ulyy); rt_printf("TT_U0jd = %d\r\n", TT_U0jd); #endif if (TT_U0jd) { log_str_time(LOG_ERR, "U0接地投入", 1, 1); rt_printf("U0接地投入!\r\n"); } rt_file_close(pfile, 0); // 关闭文件 rt_free(filebuf); // 释放内存 return; jdxx_err: TT_U0yx = 0; TT_Ipwl = 0; TT_Ipph = 0; TT_Ulyy = 0; TT_U0jd = 0; #ifdef XDL_PRINT rt_printf("ERR!TT_U0yx = %d\r\n", TT_U0yx); rt_printf("ERR!TT_Ipwl = %d\r\n", TT_Ipwl); rt_printf("ERR!TT_Ipph = %d\r\n", TT_Ipph); rt_printf("ERR!TT_Ulyy = %d\r\n", TT_Ulyy); rt_printf("ERR!TT_U0jd = %d\r\n", TT_U0jd); #endif } ////////////////////////////////////////////////////////////////////////////// #endif // FUN_JDXX /*------------------------------ 文件结束 ------------------------------------- */