/*************************************************** * 文件名: phase1_second_har_brake.c * 文件标识: * 摘 要:二次谐波制动模块 — Phase 1 安全重构 * * 当前版本:2.0 * 作 者:hxf (重构 by Hermes + Codex gpt-5.6-luna-medium) * 创建日期:2025年01月14日 * 重构日期:2026年07月16日 * * Phase 1 重构清单 (零行为变更): * [OK] 提取过流检测公共逻辑 isPhaseOverCurrent() / checkAllPhasesOverCurrent() * [OK] 6 处复制粘贴 → 1 处 + 配置驱动 * [OK] 删除 #if 0 死代码段 * [OK] 0x81 → FA_ENABLE_MASK 宏 * [OK] extern 声明迁移至 .h * [OK] 函数接口保持兼容 ***************************************************/ #include "phase1_second_har_brake.h" #include "FANEW.h" #include "zx8600.h" #include "vsp5.h" /***************************************************************************** * 函数名称:SecondHarBrake_ParamInit * 功能描述: * 初始化二次谐波制动的定值. * * 输入参数: * fd — 馈线号 * * 返回值:无 * * 作 者:hxf * 修改时间:2025-01-14 *****************************************************************************/ void SecondHarBrake_ParamInit(BYTE fd) { // 二次谐波制动系数 if (REGION_SELECT_ZHONGSHAN == getRegionSelect()) { faFdRunPara[fd].wBrakeRatio = faFdPara[fd].wBrakeRatio; // 中山二次谐波单位% } else { faFdRunPara[fd].wBrakeRatio = faFdPara[fd].wBrakeRatio * 100; } // 二次谐波制动有效时间 faFdRunPara[fd].BrakeRatioTime = faFdPara[fd].BrakeRatioTime * FAPARA_TIME_MULTIPLE / FA_CYCLE_TIMER; } /***************************************************************************** * 函数:isPhaseOverCurrent * 目的:单相过流检测 — 提取自原来 6 处重复的过流判断逻辑 * * 输入:fd-馈线号, sect-段号, phase-相号(0=A,1=B,2=C), * threshold-过流定值, returnRatio-返回比 * 输出:TRUE=过流, FALSE=正常 * 说明:内部static, Phase 1 提取公共逻辑用 *****************************************************************************/ static BOOL isPhaseOverCurrent(BYTE fd, int sect, int phase, DWORD threshold, float returnRatio) { DWORD value = gaProtYcBuf[faFdRunPara[fd].ai_start + FA_FD_AI_I + phase]; // SecHarOcStartFlag 暂保留在原位置, Phase 2 迁移到 faFdInfo extern BYTE SecHarOcStartFlag[FA_FD_NUM][SECBRAKENUM][3]; if (value > threshold) { SecHarOcStartFlag[fd][sect][phase] = 1; return TRUE; } else if (value > (DWORD)(threshold * returnRatio)) { return (SecHarOcStartFlag[fd][sect][phase] != 0) ? TRUE : FALSE; } else { SecHarOcStartFlag[fd][sect][phase] = 0; return FALSE; } } /***************************************************************************** * 函数:checkAllPhasesOverCurrent * 目的:遍历三相执行过流检测 * * 输入:fd-馈线号, sect-段号, threshold-过流定值, returnRatio-返回比 * 输出:TRUE=任一相过流, FALSE=三相均正常 *****************************************************************************/ static BOOL checkAllPhasesOverCurrent(BYTE fd, int sect, DWORD threshold, float returnRatio) { BOOL result = FALSE; int phase; for (phase = 0; phase < 3; phase++) { if (isPhaseOverCurrent(fd, sect, phase, threshold, returnRatio)) { result = TRUE; } } return result; } /***************************************************************************** * Procedure: SecondHarBrake_faFdStateIsOC ID:1 * Purpose: 判断当前是否在过流状态--投入二次谐波制动 * Input: fd-馈线号 * Output: * wh 20230905 改动&优化:统一逻辑过流,过流返回=越限告警;逻辑:判断波峰/波谷 * 根据:广州模式(1=第1段,2:第2段,3:两段都有,0:退出) * 集中式 (1:有电流越限段,0退出) * 标准:过流模式制动逻辑 * Errors: *****************************************************************************/ BOOL SecondHarBrake_faFdStateIsOC(BYTE fd) { int sect = 0; BOOL result = FALSE; float returnRatio2 = 0; returnRatio2 = faFdPara[fd].ReturnRatio / 100.0f; /* 过流段循环 */ for (sect = 0; sect < SECBRAKENUM; sect++) { /* ==================== 广州模式 ==================== */ if (REGION_SELECT_GUANGZHOU == getRegionSelect()) { if (FA_ENABLE_MASK == faEnable[fd]) { /* 第1段:单段模式 */ if ((1 == faFdPara[fd].dwFACfg[FA_CFG_SecondHar_Brake]) && (FA_FD_SECT_OC_1 == sect)) { if (faFdRunPara[fd].oc_en[sect] == TRUE) { result |= checkAllPhasesOverCurrent( fd, sect, faFdRunPara[fd].oc_limit[sect], returnRatio2); } } /* 第2段:单段模式 */ else if ((2 == faFdPara[fd].dwFACfg[FA_CFG_SecondHar_Brake]) && (FA_FD_SECT_OC_2 == sect)) { if (faFdRunPara[fd].oc_en[sect] == TRUE) { result |= checkAllPhasesOverCurrent( fd, sect, faFdRunPara[fd].oc_limit[sect], returnRatio2); } } /* 第1+2段:两段模式 */ else if ((3 == faFdPara[fd].dwFACfg[FA_CFG_SecondHar_Brake]) && (sect <= FA_FD_SECT_OC_2)) { if (faFdRunPara[fd].oc_en[sect] == TRUE) { result |= checkAllPhasesOverCurrent( fd, sect, faFdRunPara[fd].oc_limit[sect], returnRatio2); } } } } else { /* ============ 非广州模式(标准/分布式) ============ */ if ((FA_ENABLE_MASK == faEnable[fd]) && ((sect >= FA_FD_SECT_OC_1) && (sect <= FA_FD_SECT_OC_3))) { if (faFdRunPara[fd].oc_en[sect] == TRUE) { result |= checkAllPhasesOverCurrent( fd, sect, faFdRunPara[fd].oc_limit[sect], returnRatio2); } } } /* ==================== 集中式模式 ==================== */ if (FA_ENABLE_MASK == fcousEnable[fd]) { if (0 == sect) // 集中式定值结构: 只有过流定值,1次检测 { if (fcousFdRunPara[fd].oc_en[sect] == TRUE) { result |= checkAllPhasesOverCurrent( fd, sect, fcousFdRunPara[fd].oc_limit[sect], returnRatio2); } } } /* ==================== VSP5 模式 ==================== */ if (FA_ENABLE_MASK == vsp5Enable[fd]) { if (0 == sect) { result |= checkAllPhasesOverCurrent( fd, sect, gVspRunPara[fd].value_XJOverFault_1, returnRatio2); } if (1 == sect) { result |= checkAllPhasesOverCurrent( fd, sect, gVspRunPara[fd].value_XJOverFault_2, returnRatio2); } } /* 注意:#if 0 死代码段已在 Phase 1 中移除 */ } return result; } /***************************************************************************** * Procedure: faFdIsBrakeDeal ID:1 * Purpose: 从二次谐波制动状态退出时,清理过流状态 * Input: fd-馈线号 * Output: * Errors: *****************************************************************************/ void faFdIsBrakeDeal(BYTE fd) { int sect, phase; for (sect = 0; sect < FA_FD_SECT; sect++) { if ((faFdRunPara[fd].oc_en[sect] == TRUE || faFdRunPara[fd].oc_en_2[sect] == TRUE) || ((sect < FA_FD_SECT_OC) && (faFdRunPara[fd].oc_en_fanet[sect] == TRUE))) { for (phase = 0; phase < 3; phase++) { faFdInfo[fd].oc_timer[sect][phase] = faFdRunPara[fd].oc_time[sect]; if ((netproEnable[fd] == FA_ENABLE_MASK) && (faEnable[fd] == 0x01) && (vsp5Enable[fd] == 0x01)) { if (sect < FA_FD_SECT_OC) faFdInfo[fd].oc_timer[sect][phase] = faFdRunPara[fd].oc_time_fanet[sect]; } } faFdSetRunInfoStatus(fd, FA_INFO_OC1 + sect, STATUS_OFF); } } } /***************************************************************************** * Procedure: faFdIsBrake ID:1 * Purpose: 判断某相是否在二次谐波制动状态 * Input: Fundamental-基波值, SecondHar-二次谐波值, Ratio-制动系数 * Output: TRUE:制动状态, FALSE:非制动状态 * * 公式说明: * SecondHar 和 Fundamental 变量中存放的是码值²/2(已平方预处理), * 因此判据公式为:SecondHar × 100² > Fundamental × Ratio² * 等价于: 谐波²/2 × 100² > 基波²/2 × Ratio² * 即 (谐波 × 100 / 基波)² > Ratio² * 即 谐波 / 基波 × 100 > Ratio (百分比比较) * 量纲正确。 * Errors: *****************************************************************************/ BOOL faFdIsBrake(DWORD Fundamental, DWORD SecondHar, WORD Ratio) { // 1. 异常参数过滤 if ((Ratio == 0) || (Ratio > 100)) { return FALSE; } if (Fundamental < 15000) { return FALSE; // 门槛值约0.02In=100mA } if (Fundamental < SecondHar) { return TRUE; } // 2. 直接按公式比较(避免一切截断误差) // 判据:谐波² × 100² > 基波² × Ratio² QWORD ullLHS = (QWORD)SecondHar * 100 * 100; QWORD ullRHS = (QWORD)Fundamental * Ratio * Ratio; return (ullLHS > ullRHS); } // 判断是否跳过制动判断 static BOOL ShouldSkipBrake(BYTE fd) { VfaFdRunPara* pRunPara = &faFdRunPara[fd]; // 制动时间定值为0时直接跳过 if (pRunPara->BrakeRatioTime == 0) { return TRUE; } // 过流未投入 if (SecondHar_Brake_Enable(fd)) { return TRUE; } // 广州/集中式模式且过流未配置 BOOL isSpecialMode = (faEnable[fd] == FA_ENABLE_MASK || fcousEnable[fd] == FA_ENABLE_MASK); BOOL isOverTripDisabled = (faFdPara[fd].dwFACfg[FA_CFG_OVER_TRIP_1] == 0) && (faFdPara[fd].dwFACfg[FA_CFG_OVER_TRIP_2] == 0) && (faFdPara[fd].dwFACfg[FA_CFG_OVER_TRIP_3] == 0) && (fcousFaPara[fd].cfg[FA_CFG_OVER_I_WARN] == 0); return (isSpecialMode && isOverTripDisabled); } BOOL SecondHar_Brake_Enable(BYTE fd) { if ((faEnable[fd] == FA_ENABLE_MASK) && (faFdPara[fd].dwFACfg[FA_CFG_SecondHar_Brake] == 0)) { return TRUE; } else if ((vsp5Enable[fd] == FA_ENABLE_MASK) && (getVsp5Para(fd, LF_CFG_SecondHar_Brake) == 0)) { return TRUE; } else if ((fcousEnable[fd] == FA_ENABLE_MASK) && (fcousFaPara[fd].cfg[FCOUS_CFG_SecondHar_Brake] == 0)) { return TRUE; } else { return FALSE; } } /***************************************************************************** * Procedure: faFdBrakeJudge ID:1 * Purpose: 二次谐波制动判断 true-制动 false-非制动 * Input: fd-馈线号 * Output: * Errors: *****************************************************************************/ // 更新制动硬件状态和软件状态 static void UpdateBrakeStatus(BYTE fd, BOOL isActive, VfaFdRunPara* pRunPara) { if (isActive) { if (!faFdGetRunInfoStatus(fd, FA_INFO_HAR_BRAKE)) { fa_FdSBISet(fd, FA_SBI_HAR_BRAKE); faFdRecord(fd, pRunPara->sbi_start + FA_SBI_HAR_BRAKE, FA_REC_TYPE_WARN, 0); } } else { fa_FdSBIReset(fd, FA_SBI_HAR_BRAKE); } faFdSetRunInfoStatus(fd, FA_INFO_HAR_BRAKE, isActive ? STATUS_ON : STATUS_OFF); } // 判断是否满足二次谐波制动条件 static BOOL CheckSecondHarmonicBrake(BYTE fd, VfaFdRunPara* pRunPara) { int phase; // 遍历三相判断是否满足制动条件 for (phase = 0; phase < 3; phase++) { DWORD current = gaProtYcBuf[pRunPara->ai_start + FA_FD_AI_I + phase]; DWORD harm2 = gHarm2Value[fd][phase]; if (faFdIsBrake(current, harm2, pRunPara->wBrakeRatio)) { return TRUE; } } return FALSE; } // ------------------------- 制动去抖参数 ------------------------- #define BRAKE_ENTER_DEBOUNCE 5 // 进入制动去抖计数初值 #define BRAKE_EXIT_DEBOUNCE 20 // 退出制动去抖计数初值 #define BRAKE_JUDGE_TIMEOUT 100 // 判断状态超时初值 BOOL faFdBrakeJudge(BYTE fd) { static BYTE inbrake = 0; // 制动去抖计数 static BYTE outbrake = 0; // 退出制动去抖计数 VfaFdRunPara *pRunPara = &faFdRunPara[fd]; BOOL state = TRUE; // 初始状态为TRUE static BYTE BrakeJudgeStart = FALSE; static BYTE BrakeJudgeEnd = FALSE; static BYTE BrakeJudgeTimeout = FALSE; static int BrakeJudgeCount = BRAKE_JUDGE_TIMEOUT; // ------ 前置条件判断 ------ if (ShouldSkipBrake(fd)) { UpdateBrakeStatus(fd, FALSE, pRunPara); faFdInfo[fd].BrakeRatioTime = 0; state = FALSE; BrakeJudgeStart = FALSE; BrakeJudgeEnd = FALSE; BrakeJudgeCount = 0; return FALSE; } // 计算二次谐波 adCalculateSecHar(fd); if (SecondHarBrake_faFdStateIsOC(fd)) { if (BrakeJudgeStart == FALSE) { BrakeJudgeStart = TRUE; BrakeJudgeEnd = FALSE; faFdInfo[fd].BrakeRatioTime = pRunPara->BrakeRatioTime; } BrakeJudgeCount = BRAKE_JUDGE_TIMEOUT; } else { if (BrakeJudgeCount > 0) { BrakeJudgeCount--; if (BrakeJudgeCount == 0) { state = FALSE; // wh 20230905 非过流态,开始退出计时 BrakeJudgeStart = FALSE; BrakeJudgeEnd = TRUE; } } } if (faFdInfo[fd].BrakeRatioTime > 0) { faFdInfo[fd].BrakeRatioTime--; if (BrakeJudgeEnd == FALSE) // 谐波有效时间内 { if (CheckSecondHarmonicBrake(fd, pRunPara)) { state = TRUE; // 制动状态 inbrake++; if (inbrake > BRAKE_ENTER_DEBOUNCE) { inbrake = BRAKE_ENTER_DEBOUNCE; outbrake = 1; UpdateBrakeStatus(fd, TRUE, pRunPara); } } else { inbrake = 0; if (outbrake > 0) // zp20180501-在制动状态下退出做去抖 { outbrake++; if (outbrake > BRAKE_EXIT_DEBOUNCE) { outbrake = 0; state = FALSE; BrakeJudgeEnd = TRUE; } } else { state = FALSE; } } } else { state = FALSE; } if (faFdInfo[fd].BrakeRatioTime == 0) // 谐波制动超时退出 { BrakeJudgeEnd = TRUE; } } if (BrakeJudgeEnd) // wh 20230905 谐波制动超时退出 { inbrake = 0; state = FALSE; faFdInfo[fd].BrakeRatioTime = 0; } if (FALSE == state) { UpdateBrakeStatus(fd, FALSE, pRunPara); } return state; }