/************************************************************************* * 版权所有: * 文件版本: V1.00 * 文件名称:syc.c * 生成日期: 2010年4月20日 * 作 者: xxxxxx * 功 能: 系统相关函数 * 更新信息: * 更新日志1: * 日期: * 修改者: * 修改内容: * 修改原因: 修改遥控、手控标志: 原始需求(来自3100): 1、遥分、手分标志置位: (1)保护跳闸失败时,不释放分闸继电器 // TODO: XBTONG (2)重合闸放电 2、遥合、手合标志置位: (1)保护跳闸时,释放合闸继电器 (在继电器出口判断) (2)整组复归时,不释放合闸继电器 (在继电器出口判断) (3)重合闸返回时,不释放合闸继电器 (脉宽方式不需要) (4)电压时间逻辑分段、联络,解锁 (5)电压时间逻辑返回时,不释放合闸继电器 (脉宽方式不需要) 整理后需求: 1、遥分、手分标志置位: (1)重合闸放电 2、遥合、手合标志置位: (1)电压时间逻辑分段、联络,解锁 3、以分闸为高优先级,有分闸时先关闭合闸,有合闸需求时需无分闸动作。 当前做法: 手合、手分标志 1、在5ms中断保护巡检入口,手合、手分标志,通过手合手分逻辑和同期逻辑,置位 2、置位后,在当前巡检过程中,各需使用的逻辑全部使用一次 3、在当前5ms中断出口,清除手合、手分标志 遥合、遥分标志 1、在规约遥控处理中,将遥合、遥分标志置位,并初始化10ms定时器 2、经过10ms等待,至少让5ms保护巡检中断执行一次,以保证各逻辑使用到该标志 3、在_yk_polling中,经10ms等待后,清除遥合、遥分标志 出口管理:以分闸为高优先级,有分闸时关闭合闸,有合闸需求时需无分闸动作 */ /*------------------------------- 头文件 -------------------------------------- */ #include "head.h" #ifdef __IEC61850_GOOSE_FUNC__ #include "app_61850.h" #endif #include "goose.h" /*------------------------------- 宏定义 -------------------------------------- */ /*------------------------------ 类型结构 ------------------------------------- */ typedef struct YD_YXTABLE // 控制字整定结构 { BYTE type; // 远动类型 WORD no; // 点号 BYTE owner; // 归属 BYTE is_real; // 是否为实 BYTE indexno; // 归属中的索引号 WORD value; // 遥信值 } YD_YXTABLE; struct autorst { u8 xlyy; // 线路有压 u8 xlwy; // 线路无压 u8 swfw; // 开关分位 u8 swhw; // 开关合位 u8 xl_err; // 线路故障 u8 tf; // 瞬时故障 u8 pf; // 永久故障 u8 stu; // 状态机 u32 xl_ok_time; // 线路故障后恢复正常延时 u32 xl_err_time; // 线路故障判定延时 u32 tf_time; // 瞬时故障自动复归 u32 pf_time; // 永久故障自动复归 }; /*------------------------------ 全局变量 ------------------------------------- */ volatile DWORD dTCounter; // 系统定时器 DWORD app_step = 0; DWORD g_dw_led[2]; // 灯状态 DWORD g_dw_ledsave[2]; // 灯状态 bool bMaintain; // 工具进入测试模式,避免被菜单周期检查而退出bHMIMode bool bMaintain_test; // 测试模式,如开入开出测试,避免受应用影响,顺利完成测试 unsigned short m_CodeCrc; // 程序校验码 DWORD dwAppDT = 0; // 应用程序计数器 RMTYCTEST g_rmt_set_yc; // 远动遥测置数 RMTYCTEST g_rmt_set_dd; // 远动电度置数 DWORD dTRstTime; const char *ykownerstr[] = { "--", "1#485", "2#485", "1#232", "2#232", "GPS", "备用1", "备用2", #ifdef FUN_FUXI_ESAM "南网加密", #endif "1#网络", "2#网络", "3#网络", "4#网络", "本地维护", }; struct autorst g_autorst[SWITCH_NUM_MAX]; // 自动复归结构体 #if defined FUNC_DRIVE || defined FUNC_DRIVE_JY YK_DRIVE gb_drive; // 不停电传动功能 #endif /*------------------------------ 函数声明 ------------------------------------- */ extern int pit_156us_main(int is_625us); extern int pit_5ms_main(int dummy); extern int net_if_test(void); static void _yk_polling(void); static void _equerr_check(void); static void _boarderr_check(void); static void _signrst_auto(void); int _yx_is_config(WORD owner, WORD index); #ifdef FUN_ADD_CONFIG_DIR void config_remote_init(void) { int ret = 0; u8 tmp[128]; // 创建目录。如果目录已经存在,就不会再创建 rt_file_mkdir(HF_CONFIG_DIR); rt_file_mkdir(HF_CONFIG_ZF_DIR); rt_file_mkdir(HF_CONFIG_MAIN_DIR); rt_file_mkdir(HF_PROGRAM_DIR); rt_file_mkdir(HF_PROGRAM_MAIN_DIR); rt_file_mkdir(HF_PROGRAM_PROTOCOL_DIR); rt_file_mkdir(HF_PROGRAM_LCD_DIR); /*转发点表*/ sprintf(tmp, "%s%s", HF_CONFIG_ZF_DIR, "iectable.bin"); ret = rt_file_cp("/app/data/iectable.bin", tmp); if (ret != 0) rt_printf("%s 文件拷贝失败(ret=%d)!\r\n", "iectable.bin", ret); /*基本配置表*/ sprintf(tmp, "%s%s", HF_CONFIG_MAIN_DIR, "equ_cfg.bin"); ret = rt_file_cp("/app/data/equ_cfg.bin", tmp); if (ret != 0) rt_printf("%s 文件拷贝失败(ret=%d)!\r\n", "equ_cfg.bin", ret); /*主程序*/ sprintf(tmp, "%s%s", HF_PROGRAM_MAIN_DIR, KO_FILE_NAME_1); ret = rt_file_cp(KO_FILE_NAME, tmp); if (ret != 0) rt_printf("%s 文件拷贝失败(ret=%d)!\r\n", "dftu.ko", ret); /*规约程序*/ sprintf(tmp, "%s%s", HF_PROGRAM_PROTOCOL_DIR, "pcolcfg.ini"); ret = rt_file_cp("/app/data/pcolcfg.ini", tmp); if (ret != 0) rt_printf("%s 文件拷贝失败(ret=%d)!\r\n", "pcolcfg.ini", ret); /*lcd交互文件*/ sprintf(tmp, "%s%s", HF_PROGRAM_LCD_DIR, "lcd_menu.csv"); ret = rt_file_cp("/app/data/lcd_menu.csv", tmp); if (ret != 0) rt_printf("%s 文件拷贝失败(ret=%d)!\r\n", "lcd_menu.csv", ret); } #endif /*------------------------------ 外部函数 ------------------------------------- 外部函数供其它实体文件引用,必须仔细检查传入参数的合法性. */ /************************************************************************** 函数名称:SystemInit 函数版本:1.00 作者: WJJ 创建日期:2008.9.5 函数功能说明:应用系统初始化函数 输入参数: 输出参数:当前遥信的实时状态 返回值: 更新信息: 更新日志1: 日期: 修改者: 修改内容: 修改原因: ***************************************************************************/ void SystemInit(void) { dTCounter = 0; protect_init(); // 保护相关参数初始化 // sys_time_init(); //TODO by ygl m_runsection = 0; MakeRunSet(true); // 将当前运行定值区转换为运行定值区 // pw_quality_init(); MakeRunPara(true, true); // 转换参数到运行参数区 bRunSetModify = false; if (set_create_data_file() != 0) // 重新初始化一下定值,防止工具软件召的数据由于定值区未初始化,是错误值 { rt_err_set(ERR_CODE_SET_DATA, 0); } sw_ext_init(); // 零序电压自产 重新初始化一下, soe_init(); // 使用了内部定值,放在定值参数之后 soe_record_opt(EV_POWER, 0); bMaintain = false; bMaintain_test = false; MainTain_Init(); run_status_init(); rmt_key_init(); ProtectRelayInit(); // 保护定时器初始化 net_debug_s_init(); // 网络发送任务初始化 // 根据环境变量决定是否打开维护接口 if (get_mt_port_proc() == 1 || tRunPara.b104Client) // 104规约是客户端,直接打开维护工具 { net_maintain_init(); net_debug_init(); } #ifdef ENCRYPT_X509 x509_init(); // x509证书初始化 x509_time_init(); // x509时间初始化 #endif net_104_init(); net_104link_init(); #ifdef FUN_FUXI_ESAM spi_fuxi_init(); s1_status_file_init(); read_certification_init(); s1_net_init(); #endif led_init(); PDA_Comm_Init(); #ifdef FUN_GPRS // modfiy for xxxxxx 20220706 GPRS没有使用。 gprs_aux_init(); #endif filelist_createfile(); // esam_init(); FA_Init(); #if !defined CPU_FUXI /* 不支持这个lcd lch 2025年12月18日16:38:52 */ lcdcomm_init(); #else led_init_hmi(); #endif ReadUqua(); fa_g_init(); #ifdef METERING_ENERGY DLInit(); get_eep_dd_data(); energy_curve_init(); #endif #ifdef FUN_ADD_CONFIG_DIR config_remote_init(); #endif #ifdef FUN_JSON_FILE tbl_json_file_init(); #endif #ifndef CPU_FUXI pit_regester_callback(156, pit_156us_main); // 挂入采样中断 pit_regester_callback(5000, pit_5ms_main); // 挂入保护中断 #endif } void app_yb_refresh(void) { int sw; for (sw = 0; sw < g_sw_num; sw++) { if (FA_ALL_EN(sw)) { fresh_set_soe(EV_TYPE_S, !g_tRelay[sw].run_stu.fa_ls, false, sw); // 分段模式 fresh_set_soe(EV_TYPE_L, g_tRelay[sw].run_stu.fa_ls, false, sw); // 联络模式 } // 自供电功能投入 { bool bll; bll = (g_tRelay[sw].tgoc.tllcd.sta.bFlag.bCD && BH_GOOSE_EN(sw)); if (BH_GOOSE_EN(sw)) fresh_set_soe(EV_FA_LL_EN, bll, false, sw); else if (!g_tRelay[sw].run_stu.fa_ls || BH_ALL_EN(sw)) // 分段或者保护模式退出自转电SOE fresh_set_soe(EV_FA_LL_EN, 0, false, sw); } fresh_set_soe(EV_BH_YB, FUN_ALL_EN(sw), false, sw); fresh_set_soe(EV_BH_YBTT, BH_ALL_EN(sw), false, sw); fresh_set_soe(EV_CHZ_YB, CHZ_ALL_EN(sw), false, sw); fresh_set_soe(EV_FA_YBTT, FA_ALL_EN(sw), false, sw); fresh_set_soe(EV_GOOSE_YBTT, BH_GOOSE_EN(sw), false, sw); fresh_set_soe(EV_JZS_YBTT, JZS_ALL_EN(sw), false, sw); fresh_set_soe(EV_TQ_YBTT, TYTQ_ALL_EN(sw), false, sw); fresh_set_soe(EV_JL_YBTT, JL_ALL_EN(sw), false, sw); fresh_set_soe(EV_XDLJD_YBTT, pRunSet->tSwSet[sw].btt_gnyb_xdljd, false, sw); fresh_set_soe(EV_XLDXGJ_YBTT, pRunSet->tSwSet[sw].btt_gnyb_xldxgj, false, sw); fresh_set_soe(EV_BTDCD_YBTT, pRunSet->tSwSet[sw].btt_gnyb_btdcd, false, sw); fresh_set_soe(EV_KZ_YB, pRunSet->tSwSet[sw].btt_yxyb_gnzck, false, sw); fresh_set_soe(EV_EDIT_YB, pRunSet->bTT_EDIT_YB, false, sw); #ifdef YB_STHD_CHECK // 功能总 if ((((short)g_sw_pub.di_cfg_index[PUB_DI_BHALL] != INDEX_INVALLID) && (pRunSet->tSwSet[sw].btt_yxyb_gnztt != g_run_stu.bhall)) || (((short)g_sw[sw].di_cfg_index[SW_DI_BHZTT] != INDEX_INVALLID) && (pRunSet->tSwSet[sw].btt_yxyb_gnztt != g_tRelay[sw].run_stu.bhztt)) || (((short)g_sw_pub.di_cfg_index[PUB_DI_BHALL] != INDEX_INVALLID) && ((short)g_sw[sw].di_cfg_index[SW_DI_BHZTT] != INDEX_INVALLID) && (g_run_stu.bhall != g_tRelay[sw].run_stu.bhztt))) { if (soe_check(EV_FUNALL_CHECK + sw * EV_SW_NUM) == false) // { soe_record_ev(EV_FUNALL_CHECK + sw * EV_SW_NUM, 1, 0, 0, 0); } } else { if (soe_check(EV_FUNALL_CHECK + sw * EV_SW_NUM) == true) // { soe_record_ev(EV_FUNALL_CHECK + sw * EV_SW_NUM, 0, 0, 0, 0); } } // CHZ if ((((short)g_sw[sw].di_cfg_index[SW_DI_CHZ] != INDEX_INVALLID) && (pRunSet->tSwSet[sw].btt_gnyb_zdchz != g_tRelay[sw].run_stu.chzyb)) || (((short)g_sw[sw].di_cfg_index[SW_DI_BSCH] != INDEX_INVALLID) && (pRunSet->tSwSet[sw].btt_gnyb_zdchz == g_tRelay[sw].run_stu.bsch)) || (((short)g_sw[sw].di_cfg_index[SW_DI_CHZ] != INDEX_INVALLID) && ((short)g_sw[sw].di_cfg_index[SW_DI_BSCH] != INDEX_INVALLID) && (g_tRelay[sw].run_stu.chzyb == g_tRelay[sw].run_stu.bsch))) { if (soe_check(EV_CHZ_CHECK + sw * EV_SW_NUM) == false) // { soe_record_ev(EV_CHZ_CHECK + sw * EV_SW_NUM, 1, 0, 0, 0); } } else { if (soe_check(EV_CHZ_CHECK + sw * EV_SW_NUM) == true) // { soe_record_ev(EV_CHZ_CHECK + sw * EV_SW_NUM, 0, 0, 0, 0); } } #if defined GD_AREA_ZHONGSHAN || defined GD_AREA_ZHONGSHAN_2020 // GOOSE if (((short)g_sw[sw].di_cfg_index[SW_DI_FA_GOOSE] != INDEX_INVALLID) && (pRunSet->tSwSet[sw].btt_gnyb_dfa != g_tRelay[sw].run_stu.fa_g_tt)) { if (soe_check(EV_GOOSE_CHECK + sw * EV_SW_NUM) == false) // { soe_record_ev(EV_GOOSE_CHECK + sw * EV_SW_NUM, 1, 0, 0, 0); } } else { if (soe_check(EV_GOOSE_CHECK + sw * EV_SW_NUM) == true) // { soe_record_ev(EV_GOOSE_CHECK + sw * EV_SW_NUM, 0, 0, 0, 0); } } // FA if (((short)g_sw[sw].di_cfg_index[SW_DI_FA_TT] != INDEX_INVALLID) && (pRunSet->tSwSet[sw].btt_gnyb_fa != g_tRelay[sw].run_stu.fatt)) { if (soe_check(EV_FA_CHECK + sw * EV_SW_NUM) == false) // { soe_record_ev(EV_FA_CHECK + sw * EV_SW_NUM, 1, 0, 0, 0); } } else { if (soe_check(EV_FA_CHECK + sw * EV_SW_NUM) == true) // { soe_record_ev(EV_FA_CHECK + sw * EV_SW_NUM, 0, 0, 0, 0); } } // BH if (((short)g_sw[sw].di_cfg_index[SW_DI_BHTT] != INDEX_INVALLID) && (pRunSet->tSwSet[sw].btt_gnyb_cg != g_tRelay[sw].run_stu.cgbhtt)) { if (soe_check(EV_BH_CHECK + sw * EV_SW_NUM) == false) // { soe_record_ev(EV_BH_CHECK + sw * EV_SW_NUM, 1, 0, 0, 0); } } else { if (soe_check(EV_BH_CHECK + sw * EV_SW_NUM) == true) // { soe_record_ev(EV_BH_CHECK + sw * EV_SW_NUM, 0, 0, 0, 0); } } #endif #endif } } bool system_check_proc(void) { static SYSTEM_DATA st; static u32 sysDataSavetick; if ((g_tick_secs - sysDataSavetick) >= 5 || tRunPara.sysData.bWriteFlag) { sysDataSavetick = g_tick_secs; // 系统数据保存检测 if (memcmp(((char *)&st) + 2, ((char *)&tRunPara.sysData) + 2, EEP_SYSTEM_DATA_SIZE - 4) != 0) { memcpy(((char *)&st) + 2, ((char *)&tRunPara.sysData) + 2, EEP_SYSTEM_DATA_SIZE - 4); st.bWriteFlag = TRUE; WriteSysData(&st); sprintf(m_TzCount, "%d", tRunPara.sysData.wSwTzCount); sprintf(m_HzCount, "%d", tRunPara.sysData.wSwHzCount); return TRUE; } tRunPara.sysData.bWriteFlag = FALSE; } return TRUE; } /************************************************************************** 函数名称:AppPolling 函数版本:1.00 作者: WJJ 创建日期:2008.9.5 函数功能说明:应用系统巡检 输入参数: 输出参数: 返回值: 更新信息: 更新日志1: 日期: 修改者: 修改内容: 修改原因: ***************************************************************************/ void AppPolling(void) { if (dTCounter - dwAppDT < T_100ms) // 100 毫秒处理一次 { return; } dwAppDT = dTCounter; app_step++; app_action_result(); led_polling_app(); _equerr_check(); app_yb_refresh(); if ((app_step % 5) == 0) _boarderr_check(); if ((app_step % 5) == 1) _signrst_auto(); if ((app_step % 5) == 2) _yk_polling(); if ((app_step % 5) == 3) bat_proc(); if ((app_step % 5) == 4) system_check_proc(); if ((app_step % 10) == 0) fa_g_app_time(0); } /************************************************************************** 函数名称:Get_Code_CRC 函数版本:1.00 作者: 创建日期:2008.9.24 函数功能说明:计算flash的crc 输入参数: 其他输入: 输出参数: 返回值: 无 ***************************************************************************/ int Get_Code_CRC(void) { struct file *pfile; loff_t file_pos, file_length; unsigned char *file_data; unsigned short crc; // 打开文件 pfile = rt_file_open(KO_FILE_NAME, O_RDONLY, 0); if (IS_ERR(pfile)) { printk("check_file:内核模块文件不能打开(%s)!\n", KO_FILE_NAME); m_CodeCrc = 0; return -1; } // 得到文件长度 file_length = rt_file_getfile_size(pfile); if (file_length <= 0) { rt_file_close(pfile, 0); return -11; } // 分配内存 file_data = rt_malloc(file_length); if (file_data == NULL) { rt_file_close(pfile, NULL); m_CodeCrc = 0; return -2; } // 读出整个文件 file_pos = 0; rt_file_read(pfile, file_data, file_length, &file_pos); // 关闭文件 rt_file_close(pfile, NULL); // 得到CRC crc = CrcStr(file_data, (int)(file_length - 2)); m_CodeCrc = crc; // 释放内存 rt_free(file_data); return 0; } /************************************************************************** 函数名称:Delayms 函数版本:1.00 作者: 创建日期:2008.9.24 函数功能说明:延时函数 输入参数: 其他输入: 输出参数: 返回值: 无 ***************************************************************************/ void Delayms(DWORD dT, DWORD count) { while (dTCounter - dT < count) { } } // 复归合位状态下允许点亮的LED灯,eg:重合灯动作灯、告警灯 void ResetHzLed(int rstsw) { int i, sw; rt_printf("复归动作灯\r\n"); for (sw = 0; sw < g_sw_num; sw++) { TRELAY_T *pR = &g_tRelay[sw]; RUN_STU_SW *prun = &pR->run_stu; pR->run_stu.dz = RY_DZ_NULL; prun->gl = false; prun->jd = false; pR->tCHZ.sta.bFlag.bCHZLed = false; pR->tOVER_U0TZ.bU0GjLed = false; if (rstsw > 0 && ((sw + 1) != rstsw)) continue; for (i = BH_GL1; i <= FA_DLBS; i++) { TOC_T *poc = &g_tRelay[sw].tOC[i]; poc->sta.bFlag.bDzLed = false; poc->sta.bFlag.bGjLed = false; poc->sta.bFlag.bGj = false; poc->sta.bFlag.bTz = false; #ifdef YX_RESET_TIME poc->sta.bFlag.bTzEvent = false; #endif } // 灭过流灯 led_set_sw(sw, SW_LED_GL, LED_OFF); // 灭接地灯 led_set_sw(sw, SW_LED_JD, LED_OFF); // 灭重合动作灯 led_set_sw(sw, SW_LED_CHZ, LED_OFF); // chz reset if (pR->tCHZ.sta.bFlag.bQDFG == false) { pR->tCHZ.sta.wfFlag = 0; pR->tCHZ.wAR_ActTimes = 0; ResetTR(&pR->tCHZ.tTCHJD_HJS); } led_set_sw(sw, SW_LED_FAULT_GJ, LED_OFF); led_set_sw(sw, SW_LED_DZ, LED_OFF); led_set_sw(sw, SW_LED_TZ, LED_OFF); } } /************************************************************************** 函数名称:SignalReset 函数版本:1.00 作者: 创建日期:2008.9.24 函数功能说明:信号复归函数 输入参数: 其他输入: 输出参数: 返回值: 无 ***************************************************************************/ void SignalReset(int rstsw, bool blnk) { int i, sw; bool bRst; bool bBSRst; bool bGLRst; bool bJDRst; bool bCHRst; bool bGJRst; if (blnk) // 级联复归报文 { lnk_rst_set(); } if (run_status_dz_all() && rstsw == 0) // 若有告警灯点亮,记录操作信息 { soe_record_opt(EV_SIG_RESET, 0); } // 收保护动作灯 for (sw = 0; sw < g_sw_num; sw++) { TRELAY_T *pR = &g_tRelay[sw]; bRst = true; bBSRst = true; bGLRst = true; bJDRst = true; bCHRst = true; bGJRst = true; if (rstsw > 0 && ((sw + 1) != rstsw)) continue; for (i = BH_GL1; i <= FA_DLBS; i++) { TOC_T *poc = &g_tRelay[sw].tOC[i]; if (poc->sta.bFlag.bGj || poc->sta.bFlag.bTz) { if (poc->sta.bFlag.bGj) bGJRst = false; bRst = false; if (i == BH_GL1 || i == BH_GL2 || i == BH_GL3 || i == BH_GLJS || i == FA_GL || i == FA_GL2 || i == FA_DLBS || i == FA_GL_II) { bGLRst = false; } if (i == BH_LX1 || i == BH_LX2 || i == BH_LX3 || i == BH_GLJS || i == FA_LX || i == FA_LX2) { bJDRst = false; } } else { poc->sta.bFlag.bDzLed = false; } } #ifdef GD_AREA_ZHONGSHAN_2020 for (i = FAG_GL1; i <= FAG_LX; i++) { TOC_T *poc = &g_tRelay[sw].tgoc.tOc[i]; if (poc->sta.bFlag.bGj || poc->sta.bFlag.bTz) { bRst = false; if (i == FAG_GL1 || i == FAG_GL2) { bGLRst = false; } if (i == FAG_LX) { bJDRst = false; } } else { poc->sta.bFlag.bDzLed = false; } } #endif if (pR->tU0TZ.uZOV.bFlag.bTz || pR->tXXTZ.uZOV.bFlag.bTz || pR->tOVER_U0TZ.uZOV.bFlag.bTz || pR->tU0TZ.bU0Led) // 零序过压跳闸 { bRst = false; bJDRst = false; } else { pR->tU0TZ.bU0Led = false; pR->tOVER_U0TZ.bU0Led = false; } if (pR->tLostVot.uLostVot.bFlag.bTz) // 失压跳闸 { bRst = false; } else { pR->tLostVot.bLostVotLed = false; } #if defined GD_AREA_ZHONGSHAN || defined GD_AREA_ZHONGSHAN_2020 if (pR->tgoc.sta.bFlag.bglTz || pR->tgoc.sta.bFlag.bgl2Tz) // goose 过流跳闸 #else if (pR->tgoc.sta.bFlag.bglTz) // goose 过流跳闸 #endif { bRst = false; } else { pR->tgoc.bglTzLed = false; } if (pR->uGLFSX.bFlag.bFXDZ) // 反时限跳闸 { bRst = false; } else { pR->uGLFSX.bFlag.bDzLed = false; } if (pR->tgoc.sta.bFlag.blxTz) // goose 过流跳闸 { bRst = false; } else { pR->tgoc.blxTzLed = false; } if (pR->tgoc.sta.bFlag.bsdTz) // goose 过流跳闸 { bRst = false; } else { pR->tgoc.bsdTzLed = false; } if (pR->tgoc.sta.bFlag.berrTz) // goose 过流跳闸 { bRst = false; } else { pR->tgoc.berrTzLed = false; } if (pR->tgoc.sta.bFlag.bgzglTz) // goose 过流跳闸 { bRst = false; } else { pR->tgoc.bgzglTzLed = false; } if (pR->tgoc.sta.bFlag.bextTz) // 失灵跳闸 { bRst = false; } else { pR->tgoc.bextTzLed = false; } if (pR->tDYJL.sta.bFlag.bTz) // 失压跳闸 { bRst = false; } else { pR->tDYJL.bLed = false; } if (pR->tPLJL.sta.bFlag.bTz) // 失压跳闸 { bRst = false; } else { pR->tPLJL.bLed = false; } if (pR->tCHZ.sta.bFlag.bHz) // 重合闸 { bRst = false; bCHRst = false; } if (pR->tSDHZ.bL_BSLed) // 联络闭锁 { bRst = false; bBSRst = false; } if (pR->tSDHZ.bS_BSLed) // 分段闭锁 { bRst = false; bBSRst = false; } #ifdef FUN_JDXX if (pR->tJD.sta.bFlag.bTz || pR->tJD.sta.bFlag.bGj) //(jdxx_is_dz(sw)) { // jdxx_rst_dz(sw); bRst = false; bJDRst = false; } else { pR->tJD.sta.bFlag.bTZLed = false; pR->tJD.sta.bFlag.bGJLed = false; } #endif // 灭过流灯 if (bGLRst) { led_set_sw(sw, SW_LED_GL, LED_OFF); } // 灭接地灯 if (bJDRst) { led_set_sw(sw, SW_LED_JD, LED_OFF); } // 灭重合灯 if (bCHRst) { // led_set_sw(sw,SW_LED_CHZ, LED_OFF); } // 灭闭锁灯 if (bBSRst) { // led_set_sw(sw,SW_LED_LOCK, LED_OFF); // 闭锁灯程序自动处理,不需要人工干预 } // 灭动作灯 if (bRst) { sw_do(sw, SW_DO_BHDZ, SW_DO_TYPE_OFF); led_set_sw(sw, SW_LED_DZ, LED_OFF); led_set_sw(sw, SW_LED_TZ, LED_OFF); pR->run_stu.dz = RY_DZ_NULL; if (rstsw > 0) soe_record_opt(EV_SIG_RESET, 0); if (soe_check(EV_ARBS + sw * EV_SW_NUM) == true) { g_tRelay[sw].run_stu.chzbs = false; soe_record_ev(EV_ARBS + sw * EV_SW_NUM, 0, 0, 0, 0); // 重合闸闭锁 led_set_sw(sw, SW_LED_CHZBS, LED_OFF); ResetTR(&g_tRelay[sw].tCHZ.tTCHJBSTime); // chzbs reset pR->tCHZ.sta.wfFlag = 0; pR->tCHZ.wAR_ActTimes = 0; ResetTR(&pR->tCHZ.tTCHJD_HJS); led_set_sw(sw, SW_LED_CHZ, LED_OFF); } if (soe_check(EV_HI_CHZ_LOCK + sw * EV_SW_NUM) == true) { soe_record_ev(EV_HI_CHZ_LOCK + sw * EV_SW_NUM, 0, 0, 0, 0); // 大电流闭锁重合闸 led_set_sw(sw, SW_LED_CHZBS, LED_OFF); } } if (bGJRst) led_set_sw(sw, SW_LED_FAULT_GJ, LED_OFF); pR->run_stu.fgbs = 0; } // 灭公共动作灯 if (rstsw == 0) g_run_stu.pubdz = 0; #if defined(BSP_CAN_ENABLE) if (g_led_aux_test_st && rstsw == 0) { g_led_aux_test_st = 0; // TODO EWen 待合并 // led_aux_test(0); } #endif } // 遥控处理 char *const g_RmtCtrl_ErrCode[] = { "遥控成功!", // 0 "非远方状态!", // 1 "无遥控信息,请检查遥控点表!", // 2 "不同主站遥控,拒绝!", // 3 "没有实际对应点,请检查遥控点表!", // 4 "重复选择!", // 5 "选择公共开出超范围!", // 6 "选择必须总软压板投入!", // 7 "选择公共开出失败!", // 8 "选择线路开出超范围!", // 9 "选择总软压板或线路软压板必须投入!", // 10 "选择线路开出失败!", // 11 "遥控执行和遥控选择不对应!", // 12 "执行必须总软压板投入!", // 13 "执行总软压板或线路软压板必须投入!", // 14 "线路保护出口,禁止动作!", // 15 "合环闭锁或出口,禁止动作!", // 16 "重合闸出口,禁止动作!", // 17 "执行开出失败!", // 18 "非选择状态下撤销!", // 19 "遥控类型错误!", // 20 "遥控超时错误!", // 21 "级联遥控错误!", // 22 "遥控未知错误!", // 23 "遮断,禁止分闸!", // 24 "FA闭锁操作", // 25 "遥控压板退出", // 26 "开关未储能,禁止合闸", // 27 "检修状态!", // 28 }; #define ERRCODE_NUM (sizeof(g_RmtCtrl_ErrCode) / sizeof(g_RmtCtrl_ErrCode[0])) char *RmtCtrl_Err(int err_code) { err_code = abs(err_code); if (err_code < ERRCODE_NUM) { return g_RmtCtrl_ErrCode[err_code]; } return g_RmtCtrl_ErrCode[ERRCODE_NUM - 1]; } // 遥控修改软压板判断 bool ykEditYb(BYTE ykTypeNo) { switch (ykTypeNo - 1) { case PUB_CHYB_HZ: case PUB_CHYB_FZ: case PUB_BHYB_HZ: case PUB_BHYB_FZ: case PUB_KZYB_HZ: case PUB_KZYB_FZ: #ifdef BHFA_YB_YK case PUB_BHYBTT_HZ: // 虚遥控,常规保护投退合闸压板(线路保护投停&&保护投入软压板) case PUB_BHYBTT_FZ: // 虚遥控,常规保护投退分闸压板(线路保护投停&&保护投入软压板) case PUB_FAYBTT_HZ: // 虚遥控,FA保护投退合闸压板(线路保护投停&&保护投入软压板) case PUB_FAYBTT_FZ: // 虚遥控,FA保护投退分闸压板(线路保护投停&&保护投入软压板) case PUB_GOOSEYBTT_HZ: // 虚遥控,goose保护投退合闸压板(线路保护投停&&保护投入软压板) case PUB_GOOSEYBTT_FZ: // 虚遥控,goose保护投退分闸压板(线路保护投停&&保护投入软压板) #endif case PUB_TQ_YB_HZ: // 虚遥控,同期合闸软压板 case PUB_TQ_YB_FZ: // 虚遥控,同期合闸软压板 case PUB_JZS_YB_HZ: case PUB_JZS_YB_FZ: #ifdef YK_SOFT_YB case PUB_YK_YB_HZ: // 虚遥控,遥控软压板 case PUB_YK_YB_FZ: // 虚遥控,遥控软压板 #endif #ifdef YK_FA_ENBLE case PUB_YK_BS_FA_HZ: // "FA遥控闭锁-合", case PUB_YK_BS_FA_FZ: #endif #ifdef YK_FA_S_L_ENBLE case PUB_YK_FA_S_L_HZ: // "分段/联络-合", case PUB_YK_FA_S_L_FZ: // "分段/联络-分", #endif case PUB_JL_YB_HZ: // 虚遥控,停用自动解列软压板 case PUB_JL_YB_FZ: // 虚遥控,停用自动解列软压板 #ifdef FUNC_DRIVE case PUB_DRIVE_YB_ON: // 虚遥控,不停电传动软压板投入 case PUB_DRIVE_YB_OFF: // 虚遥控,不停电传动软压板退出 #endif return TRUE; // 当前遥控修改软压板 default: return FALSE; } } static bool yk_pub_yb(int no) { switch (no - 1) { #if defined GD_AREA_ECZD_2020 || defined CN_AREA_NANWANG_2022 // 二次指导意见开始将公共软压板放到公共定值 case PUB_BHYB_HZ: case PUB_BHYB_FZ: case PUB_KZYB_HZ: case PUB_KZYB_FZ: #ifdef BHFA_YB_YK case PUB_BHYBTT_HZ: case PUB_BHYBTT_FZ: case PUB_FAYBTT_HZ: case PUB_FAYBTT_FZ: case PUB_GOOSEYBTT_HZ: case PUB_GOOSEYBTT_FZ: #endif case PUB_JL_YB_HZ: case PUB_JL_YB_FZ: case PUB_TQ_YB_HZ: case PUB_TQ_YB_FZ: #endif #ifdef FUNC_DRIVE case PUB_DRIVE_YB_ON: case PUB_DRIVE_YB_OFF: #endif #ifdef CN_AREA_NANWANG_2022 case PUB_CHYB_HZ: // 虚遥控,重合闸压板 case PUB_CHYB_FZ: // 虚遥控,分闸压板 #endif return true; default: return false; } } int _RemoteCtrl(BYTE yktype, BYTE index, BYTE ykval, WORD wID) { static SET_VALUE tmpSetBuf[MAX_SET_NUMBER]; // 定义定值查看及整定时的buf BYTE no, owner; int ret; WORD soeno; TRELAY_T *pR; // 无遥控信息空间 if (g_yk_info == NULL) { return -2; } // 遥控前,先检查是否需要先复归。 // 经过10ms等待,至少让5ms保护巡检中断执行一次,以保证各逻辑使用到遥分、遥合标志 if (g_yk_info[index].yk_st == YK_STATUS_EXE && (dTCounter - g_yk_info[index].dTStart >= T_10ms)) // 遥控执行完成 { // TODO: xbtong if (g_yk_info[index].owner > 0) { owner = g_yk_info[index].owner - 1; if (g_yk_info[index].no == (SW_DO_YKH + 1) || g_yk_info[index].no == (SW_DO_BHH + 1)) { g_tRelay[owner].uRmtSW.bYHExecute = false; g_tRelay[owner].uRmtSW.bYHExecute_fa = false; } if (g_yk_info[index].no == (SW_DO_YKT + 1) || g_yk_info[index].no == (SW_DO_BHT + 1)) { g_tRelay[owner].uRmtSW.bYTExecute = false; g_tRelay[owner].uRmtSW.bYTExecute_fa = false; } } memset(&g_yk_info[index], 0, sizeof(REMOTEYKSTATUS)); } // 不同主站遥控时,要拒绝 if (!(g_yk_info[index].wMaster == 0 || g_yk_info[index].wMaster == wID)) { return -3; } if (ykval == YK_VAL_HZ) { no = g_do_table[index].indexno[0]; owner = g_do_table[index].owner; } else { no = g_do_table[index].indexno[1]; owner = g_do_table[index].owner; } // 没有实际对应点 if (no == 0) { return -4; } #if defined IEC_JXYB_DEAL if (g_run_stu.bjx) return -28; #endif g_yk_info[index].wMaster = wID; pR = &g_tRelay[owner - 1]; // 是遥控选择 if (yktype == YK_TYPE_SEL) { #if !defined IEC_YK_MORE_PRESET // 支持多次预置,每次预置重新计时 // 国网最新要求:同一点不接受多次预置,就是说连续预置的情况下, // 第一次预置成功,第二次预置失败,第3次预置成功。 if (g_yk_info[index].yk_st != YK_STATUS_NONE && g_yk_info[index].yk_st != YK_STATUS_TIMEOUT) { // 已经有遥控命令选择或在执行 memset(&g_yk_info[index], 0, sizeof(REMOTEYKSTATUS)); return -5; } else #endif { // 公共开出选择 if (owner == 0) { if (no > PUB_DO_NUM) { // 超范围 return -6; } else if (no == PUB_DO_RST + 1) { // 远方复归 } else if (no == PUB_DO_JS + 1) { // 解除闭锁 } #ifdef YK_FG_FAJS else if (no == PUB_DO_RST_FAJS + 1) { // 远方复归+FA解锁 } #endif else if (no == PUB_DO_RESTART + 1) { // 远方重启 } #ifdef METERING_ENERGY else if (no == PUB_DD_CLR + 1) { } else if (no == PUB_LLSOE_CLR + 1) { } #endif #ifdef FUNC_DRIVE else if (no == PUB_DRIVE_HZ + 1) { } #endif #ifdef FUNC_DRIVE_JY else if (no == PUB_UNSTOP_V_DRI_HZ + 1) { ; } #endif #ifdef FUNC_RESET_EQU else if (no == PUB_RESET_EQU + 1) { ; } #endif else if (ykEditYb(no)) { // 压板定值操作 if (!g_run_stu.yf) { return -1; } } #ifdef BATTERY_WITH_COMM else if (no == (PUB_DO_DCHH + 1)) { // 电池启动活化 } else if (no == (PUB_DO_HHTC + 1)) { // 电池退出活化 } #endif else { if (sw_do_pub(no - 1, SW_DO_TYPE_SELECT_ON) != 0) { return -8; } } } // 线路开出选择 else { if (owner > g_sw_num || no > SW_DO_NUM) { // 超范围 dp_err_n_c("owner = %d, no = %d, g_sw_num = %d, SW_DO_NUM = %d, ", owner, no, g_sw_num, SW_DO_NUM); return -9; } else if ((no == SW_DO_BHH + 1) || (no == SW_DO_BHT + 1)) { return -9; } #ifdef YK_SOFT_YB else if (!pRunSet->bTT_SOFT_YK_YB && ykval == YK_VAL_TZ && no == SW_DO_YKT + 1) { return -26; } else if (!pRunSet->bTT_SOFT_YK_YB && ykval == YK_VAL_HZ && no == SW_DO_YKH + 1) { return -26; } #endif else if ((fa_bs_fz(owner - 1) || pR->bBSTZ) && ykval == YK_VAL_TZ && no == SW_DO_YKT + 1) { // rt_printf("遮断闭锁,禁止分闸操作\r\n"); return -24; } else if (fa_bs_hz(owner - 1) && ykval == YK_VAL_HZ && no == SW_DO_YKH + 1) { return -25; } else if (pR->run_stu.wcn && pRunSet->tSwSet[owner - 1].bTT_WCN && ykval == YK_VAL_HZ && no == SW_DO_YKH + 1) { return -27; } else // 不是压板操作,判断软压板状态 { // 非远方状态 ,不允许遥控 if (!g_run_stu.yf) { return -1; } if (sw_do(owner - 1, no - 1, SW_DO_TYPE_SELECT_ON) != 0) { return -11; } } } // 记录选择动作 g_yk_info[index].yk_st = YK_STATUS_SEL; g_yk_info[index].no = no; g_yk_info[index].owner = owner; g_yk_info[index].val = ykval; g_yk_info[index].dTStart = dTCounter; soeno = (ykval == YK_VAL_HZ) ? EV_YH_SELECT : EV_YT_SELECT; soe_record_opt(soeno, ((owner << 8) | no | (wID << 16))); return 0; } } else if (yktype == YK_TYPE_EXE) // 是遥控执行 { if ((g_yk_info[index].yk_st != YK_STATUS_SEL) // 和遥控选择的数据不对应 || (ykval != g_yk_info[index].val) || (owner != g_yk_info[index].owner) || (no != g_yk_info[index].no)) { if (g_yk_info[index].yk_st == YK_STATUS_TIMEOUT) { // 遥控超时 ret = -21; } else { // 遥控不对应 ret = -12; } memset(&g_yk_info[index], 0, sizeof(REMOTEYKSTATUS)); return ret; } g_yk_info[index].yk_st = YK_STATUS_EXE; g_yk_info[index].dTStart = dTCounter; // 公共开出执行 if (owner == 0) { if (no == PUB_DO_RST + 1) // 远方复归 { ResetHzLed(0); SignalReset(0, true); // SignalReset(0,false); ret = 0; } else if (no == PUB_DO_JS + 1) // 远方解锁 { ResetHzLed(0); g_run_stu.rmtjs = true; ret = 0; } #ifdef YK_FG_FAJS else if (no == PUB_DO_RST_FAJS + 1) // 远方复归+FA解锁 { ResetHzLed(0); SignalReset(0, true); g_run_stu.rmtjs = true; ret = 0; } #endif else if (no == PUB_DO_RESTART + 1) // 远方重启 { rt_printf("遥控装置重启\r\n"); g_restart_count = 3; // 3秒后重启 ret = 0; } #ifdef BATTERY_WITH_COMM else if (no == (PUB_DO_DCHH + 1)) { bat_active(1); // 电池启动活化 ret = 0; } else if (no == (PUB_DO_HHTC + 1)) { bat_act_off(1); // 电池退出活化 ret = 0; } #endif #ifdef METERING_ENERGY else if (no == PUB_DD_CLR + 1) // 电度清零 { u8 sw = 0; DWORD dd_val; dd_val = g_sw[0].dd[SW_DD_NOW1].fv * 65536.0f; soe_record_ev(EV_DD_CLR + sw * EV_SW_NUM, 1, dd_val, 0, 0); if (pRunSet->dd_calc_mode == 0) can_app_energy_clear(0, get_can_slot(0)); soft_dd_val_clr(); rt_printf("遥控电度清零\r\n"); ret = 0; } #if 1 else if (no == PUB_LLSOE_CLR + 1) { bool b_ll_err = false; int ret2; ret2 = DelAllListDataFile(&eventd_pnaList); if (!ret2) { init_ll_db_file(&eventd_pnaList, "eventd_pna.dat", 10, 1 + 8 + 4 + 4 * 8 + 8 + 4 * 8); } else { b_ll_err = true; } rt_printf("%s(1):ret2=%d\r\n", __func__, ret2); ret2 = DelAllListDataFile(&eventd_pnbList); if (!ret2) { init_ll_db_file(&eventd_pnbList, "eventd_pnb.dat", 10, 1 + 8 + 4 + 4 * 8 + 8 + 4 * 8); } else { b_ll_err = true; } rt_printf("%s(2):ret2=%d\r\n", __func__, ret2); ret2 = DelAllListDataFile(&eventd_pncList); if (!ret2) { init_ll_db_file(&eventd_pncList, "eventd_pnc.dat", 10, 1 + 8 + 4 + 4 * 8 + 8 + 4 * 8); } else { b_ll_err = true; } rt_printf("%s(3):ret2=%d\r\n", __func__, ret2); ret2 = DelAllListDataFile(&eventd_flownList); if (!ret2) { init_ll_db_file(&eventd_flownList, "eventd_flown.dat", 10, 1 + 8 + 4 + 4 * 8); } else { b_ll_err = true; } rt_printf("%s(4):ret2=%d\r\n", __func__, ret2); ret2 = DelAllListDataFile(&eventd_llclrList); if (!ret2) { init_ll_db_file(&eventd_llclrList, "eventd_llclr.dat", 10, 1 + 8 + 4 + 4 * 8); } else { b_ll_err = true; } rt_printf("%s(5):ret2=%d\r\n", __func__, ret2); ret2 = DelAllListDataFile(&eventd_syntList); if (!ret2) { init_ll_db_file(&eventd_syntList, "eventd_synt.dat", 10, 1 + 8 + 4); } else { b_ll_err = true; } rt_printf("%s(6):ret2=%d\r\n", __func__, ret2); if (line_loss_event_start(METERING_EVT_CLEAR, EventNumData.sSOEClr_Num + 1) >= 1) { EventNumData.sSOEClr_Num++; // 本地保存潮流方向总次数 rt_printf("%s:SOEClr_Num=%d\r\n", __func__, EventNumData.sSOEClr_Num); } if (b_ll_err) ret = -30; else ret = 0; } #endif #endif #ifdef FUNC_DRIVE else if (no == PUB_DRIVE_HZ + 1) { int sw = 0; if (pRunSet->tSwSet[sw].btt_gnyb_btdcd && !gb_drive.b_err && !gb_drive.b_warning && !g_tRelay[sw].run_stu.chzbs && (!g_tRelay[sw].run_stu.bs || soe_check(EV_SH_BSFZ + sw * EV_SW_NUM) || soe_check(EV_BS_HA + sw * EV_SW_NUM)) && !g_tRelay[sw].uBHQD.bFlag.bFZQD && !g_tRelay[sw].uBHQD.bFlag.bBHQD) { gb_drive.b_drive_on = true; gb_drive.b_drive_soe = true; gb_drive.b_drive_process = true; if (soe_check(EV_DRIVE_BEGIN + sw * EV_SW_NUM) == false) { soe_record_ev(EV_DRIVE_BEGIN + sw * EV_SW_NUM, 1, 0, 0, 0); } ret = 0; } else { return -23; } } #endif #ifdef FUNC_DRIVE_JY else if (no == (PUB_UNSTOP_V_DRI_HZ + 1)) { int sw = 0; bool sb_mode_drive = false; // 常规模式投入重合闸或就地FA模式投入得电合闸时为true if (FA_ALL_EN(sw)) { if (g_tRelay[sw].tSWST.uSWST.bFlag.bDIHW && (pRunSet->tSwSet[sw].bTT_fa_poweron || pRunSet->tSwSet[sw].bTT_fa_lineon)) // 电源侧得电合/负荷侧得电合 { sb_mode_drive = true; } } else if (BH_ALL_EN(sw)) { if (g_tRelay[sw].tCHZ.sta.bFlag.bCDWC) // 重合闸充电完成 { sb_mode_drive = true; } } if (pRunSet->tSwSet[sw].bTT_drive && !gb_drive.b_err && !gb_drive.b_warning && !g_tRelay[sw].run_stu.chzbs && !g_tRelay[sw].tSWST.uSWST.bFlag.bKZHL && (!g_tRelay[sw].run_stu.bs || soe_check(EV_SH_BSFZ + sw * EV_SW_NUM) || soe_check(EV_BS_HA + sw * EV_SW_NUM)) && !g_tRelay[sw].uBHQD.bFlag.bFZQD && !g_tRelay[sw].uBHQD.bFlag.bBHQD && sb_mode_drive) { gb_drive.b_drive_on = true; gb_drive.b_drive_on_check = true; gb_drive.b_drive_success = true; if (soe_check(EV_DRIVE_TT_ERR + sw * EV_SW_NUM) == true) // 定值投退异常返回 { soe_record_ev(EV_DRIVE_TT_ERR + sw * EV_SW_NUM, 0, 0, 0, 0); } rt_printf_time("遥控执行传动功能\r\n"); ret = 0; } else { rt_printf("遥控执行传动功能失败,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\r\n", pRunSet->tSwSet[sw].bTT_drive, gb_drive.b_err, gb_drive.b_warning, g_tRelay[sw].run_stu.chzbs, g_tRelay[sw].tSWST.uSWST.bFlag.bKZHL, g_tRelay[sw].run_stu.bs, soe_check(EV_SH_BSFZ + sw * EV_SW_NUM), soe_check(EV_BS_HA + sw * EV_SW_NUM), g_tRelay[sw].uBHQD.bFlag.bFZQD, g_tRelay[sw].uBHQD.bFlag.bBHQD); gb_drive.b_drive_on = false; gb_drive.b_drive_on_check = false; gb_drive.b_drive_success = false; if (soe_check(EV_DRIVE_FAIL + sw * EV_SW_NUM) == false) // 传动启动失败 { soe_record_ev(EV_DRIVE_FAIL + sw * EV_SW_NUM, 1, 0, 0, 0); } if (soe_check(EV_DRIVE_FAIL + sw * EV_SW_NUM) == true) // 传动启动失败返回 { soe_record_ev(EV_DRIVE_FAIL + sw * EV_SW_NUM, 0, 0, 0, 0); } if (!pRunSet->tSwSet[sw].bTT_drive) // 定值投退异常 { if (soe_check(EV_DRIVE_TT_ERR + sw * EV_SW_NUM) == false) { soe_record_ev(EV_DRIVE_TT_ERR + sw * EV_SW_NUM, 1, 0, 0, 0); } } else // 定值投退异常返回 { if (soe_check(EV_DRIVE_TT_ERR + sw * EV_SW_NUM) == true) { soe_record_ev(EV_DRIVE_TT_ERR + sw * EV_SW_NUM, 0, 0, 0, 0); } } if (soe_check(EV_DRIVE_END + sw * EV_SW_NUM) == false) // 传动结束 { soe_record_ev(EV_DRIVE_END + sw * EV_SW_NUM, 1, 0, 0, 0); } if (soe_check(EV_DRIVE_END + sw * EV_SW_NUM) == true) // 传动结束返回 { soe_record_ev(EV_DRIVE_END + sw * EV_SW_NUM, 0, 0, 0, 0); } return -23; } } #endif #ifdef FUNC_RESET_EQU else if (no == PUB_RESET_EQU + 1) { gb_ResetEqu = true; rt_printf_time("遥控装置硬重启..\r\n"); ret = 0; } #endif else if (ykEditYb(no)) { int setno = 0; int val = 0; if (!g_run_stu.yf) { return -1; } #ifdef YK_SOFT_YB else if (!pRunSet->bTT_SOFT_YK_YB && ykval == YK_VAL_HZ && no == SW_DO_YKH + 1) { return -26; } #endif else if (fa_bs_hz(owner - 1) && ykval == YK_VAL_HZ && no == SW_DO_YKH + 1) { return -25; } else if (pR->run_stu.wcn && pRunSet->tSwSet[owner - 1].bTT_WCN && ykval == YK_VAL_HZ && no == SW_DO_YKH + 1) { return -27; } if (no == PUB_BHYB_HZ + 1) { setno = SET_BH_YB; val = 1; } else if (no == PUB_BHYB_FZ + 1) { setno = SET_BH_YB; val = 0; } else if (no == PUB_CHYB_HZ + 1) { setno = SET_CHZ_YB; val = 1; } else if (no == PUB_CHYB_FZ + 1) { setno = SET_CHZ_YB; val = 0; } else if (no == PUB_KZYB_FZ + 1) { setno = SET_KZ_OUT_YB; val = 0; } else if (no == PUB_KZYB_HZ + 1) { setno = SET_KZ_OUT_YB; val = 1; } #if (defined BHFA_YB_YK) else if (no == PUB_BHYBTT_FZ + 1) { setno = SET_BH_YBTT; val = 0; } else if (no == PUB_BHYBTT_HZ + 1) { setno = SET_BH_YBTT; val = 1; } else if (no == PUB_FAYBTT_FZ + 1) { setno = SET_FA_YBTT; val = 0; } else if (no == PUB_FAYBTT_HZ + 1) { setno = SET_FA_YBTT; val = 1; } else if (no == PUB_GOOSEYBTT_FZ + 1) { setno = SET_GOOSE_YBTT; val = 0; } else if (no == PUB_GOOSEYBTT_HZ + 1) { setno = SET_GOOSE_YBTT; val = 1; } #endif else if (no == PUB_TQ_YB_FZ + 1) { setno = SET_TQ_YB; val = 0; } else if (no == PUB_TQ_YB_HZ + 1) { setno = SET_TQ_YB; val = 1; } #ifdef JZS_FUNCTION else if (no == PUB_JZS_YB_FZ + 1) { setno = SET_MODE_JZS_TT; val = 0; } else if (no == PUB_JZS_YB_HZ + 1) { setno = SET_MODE_JZS_TT; val = 1; } #endif #ifdef YK_SOFT_YB else if (no == PUB_YK_YB_FZ + 1) { setno = SET_YK_YBTT; val = 0; } else if (no == PUB_YK_YB_HZ + 1) { setno = SET_YK_YBTT; val = 1; } #endif #ifdef YK_FA_ENBLE else if (no == PUB_YK_BS_FA_HZ + 1) // "FA遥控闭锁-合", { if (soe_check(EV_YK_BS_FA + 0 * EV_SW_NUM) == false) // soe_record_ev(EV_YK_BS_FA + 0 * EV_SW_NUM, 1, 0, 0, 0); ret = -1; // 不需要保存 } else if (no == PUB_YK_BS_FA_FZ + 1) // "FA遥控闭锁-分", { if (soe_check(EV_YK_BS_FA + 0 * EV_SW_NUM) == true) // soe_record_ev(EV_YK_BS_FA + 0 * EV_SW_NUM, 0, 0, 0, 0); ret = -1; // 不需要保存 } #endif #ifdef YK_FA_S_L_ENBLE else if (no == PUB_YK_FA_S_L_HZ + 1) { setno = SET_SL_TT; #if defined GD_AREA_ECZD_2020_2021 val = 0; #else val = 2; #endif } else if (no == PUB_YK_FA_S_L_FZ + 1) { setno = SET_SL_TT; val = 1; } #endif else if (no == PUB_JL_YB_FZ + 1) { setno = SET_JL_YB; val = 0; } else if (no == PUB_JL_YB_HZ + 1) { setno = SET_JL_YB; val = 1; } #ifdef FUNC_DRIVE else if (no == PUB_DRIVE_YB_ON + 1) { setno = SET_TRASW_YB; val = 1; } else if (no == PUB_DRIVE_YB_OFF + 1) { setno = SET_TRASW_YB; val = 0; } #endif else { ret = -1; } #ifdef GD_AREA_ECZD_2020 // 二次指导意见开始将公共软压板放到公共定值 /*if((no == PUB_BHYB_HZ+1) || (no ==PUB_BHYB_FZ+1)||(no == PUB_KZYB_HZ+1) || (no ==PUB_KZYB_FZ+1) ||(no==PUB_BHYBTT_HZ+1)||(no==PUB_BHYBTT_FZ+1)||(no == PUB_FAYBTT_HZ+1) || (no ==PUB_FAYBTT_FZ+1)||(no == PUB_GOOSEYBTT_HZ+1) || (no ==PUB_GOOSEYBTT_FZ+1) ||(no == PUB_JL_YB_HZ+1) || (no ==PUB_JL_YB_FZ+1) ||(no == PUB_TQ_YB_HZ+1) || (no ==PUB_TQ_YB_FZ+1) ) //公共定值*/ if (yk_pub_yb(no)) // 公共定值 { if (!ReadPara((void *)tmpSetBuf, EEP_PUB_ADDR + m_runsection * PUB_SETSIZE, PUB_SET_NUMBER, &tPubSetTable[0])) { rt_err_set(ERR_CODE_SET, 0); GetDefPara((void *)tmpSetBuf, PUB_SET_NUMBER, &tPubSetTable[0]); } tmpSetBuf[setno].ff = val; if (SavePara((void *)tmpSetBuf, EEP_PUB_ADDR + m_runsection * PUB_SETSIZE, PUB_SET_NUMBER, &tPubSetTable[0])) { soe_record_opt(EV_YBSET_OK, 0); MakeRunSet(false); rt_err_clr(ERR_CODE_SET, 0); ret = 0; } else { ret = -1; } } else // 开关定值 { if (!ReadPara((void *)tmpSetBuf, EEP_SET_ADDR + m_runsection * SETSIZE, SW_SET_NUMBER, &tSwSetTable[0])) { rt_err_set(ERR_CODE_SET, 0); GetDefPara((void *)tmpSetBuf, SW_SET_NUMBER, &tSwSetTable[0]); } tmpSetBuf[setno].ff = val; if (SavePara((void *)tmpSetBuf, EEP_SET_ADDR + m_runsection * SETSIZE, SW_SET_NUMBER, &tSwSetTable[0])) { soe_record_opt(EV_YBSET_OK, 0); MakeRunSet(false); rt_err_clr(ERR_CODE_SET, 0); ret = 0; } else { ret = -1; } } #else if (!ReadPara((void *)tmpSetBuf, EEP_SET_ADDR + m_runsection * SETSIZE, SW_SET_NUMBER, &tSwSetTable[0])) { rt_err_set(ERR_CODE_SET, 0); GetDefPara((void *)tmpSetBuf, SW_SET_NUMBER, &tSwSetTable[0]); } tmpSetBuf[setno].ff = val; if (SavePara((void *)tmpSetBuf, EEP_SET_ADDR + m_runsection * SETSIZE, SW_SET_NUMBER, &tSwSetTable[0])) { soe_record_opt(EV_YBSET_OK, 0); MakeRunSet(false); rt_err_clr(ERR_CODE_SET, 0); ret = 0; } else { ret = -1; } #endif } else { ret = sw_do_pub(no - 1, SW_DO_TYPE_ON); dp_err_n_c("no = %dret = %d", no, no); } } // 线路开出执行 else { { // 必须是总软压板投入和对应的线路软压板投入才允许动作。 // if(pRunSet->tSwSet[owner-1].bTT_YB == 0 ||pRunSet->bTT_ZYB == 0 ) //{ // return -14; //} // 非远方状态 ,不允许遥控 if (!g_run_stu.yf) { return -1; } if ((no == SW_DO_YKH + 1)) { if (g_tRelay[owner - 1].uBHDZ.bFlag.bBHT) // 正在保护出口,退出 { return -15; } else if (pRunSet->tSwSet[0].btt_gnyb_tqhz) { g_tRelay[owner - 1].uRmtSW.bTQHz = true; return 0; } } if ((no == SW_DO_YKT + 1)) { if (g_tRelay[owner - 1].tCHZ.sta.bFlag.bHz) // 正在重合闸出口,退出 { return -17; } #ifdef YK_SOFT_YB else if (!pRunSet->bTT_SOFT_YK_YB && ykval == YK_VAL_TZ && no == SW_DO_YKT + 1) { return -26; } #endif if ((fa_bs_fz(owner - 1) || pR->bBSTZ) && ykval == YK_VAL_TZ) { // rt_printf("遮断闭锁,禁止分闸操作\r\n"); return -24; } sw_do(owner - 1, SW_DO_BHDZ, SW_DO_TYPE_ON); } #ifdef CUSTOMIZE_BZT // 备自投 if (((no - 1) != SW_DO_DL1_HZ) && ((no - 1) != SW_DO_DL2_HZ) && ((no - 1) != SW_DO_FD_HZ) && ((no - 1) != SW_DO_DL1_FZ) && ((no - 1) != SW_DO_DL2_FZ) && ((no - 1) != SW_DO_FD_FZ)) ret = sw_do(owner - 1, no - 1, SW_DO_TYPE_ON); else { rt_printf("\r\n 备自投遥控执行..."); ret = BZT_ManualOnOffHandle(owner - 1, no - 1); } #else ret = sw_do(owner - 1, no - 1, SW_DO_TYPE_ON); #endif if (ret == 0) { if (ykval == YK_VAL_HZ) { g_tRelay[owner - 1].uRmtSW.bYHExecute = true; g_tRelay[owner - 1].uRmtSW.bYHExecute_fa = true; } else { g_tRelay[owner - 1].uRmtSW.bYTExecute = true; g_tRelay[owner - 1].uRmtSW.bYTExecute_fa = true; } } } } if (ret == 0) { if (ykval == YK_VAL_HZ) { soeno = EV_YH_EXECT; } else { soeno = EV_YT_EXECT; } soe_record_opt(soeno, ((owner << 8) | no | (wID << 16))); return 0; } return -18; } else if (yktype == YK_TYPE_CANCEL) { if (g_yk_info[index].yk_st != YK_STATUS_SEL) { return -19; } else { owner = g_yk_info[index].owner; no = g_yk_info[index].no; if (owner == 0) // 公共开出 { sw_do_pub(no - 1, SW_DO_TYPE_SELECT_OFF); } else { sw_do(owner - 1, no - 1, SW_DO_TYPE_SELECT_OFF); } { char buf[64]; sprintf(buf, "遥控取消成功--%s:开关%02d开出%02d", get_yk_owner(wID), owner, no); log_str_time(LOG_OPERATE, buf, 0, 0); } soeno = (ykval == YK_VAL_HZ) ? EV_YH_EXCANCEL : EV_YT_EXCANCEL; soe_record_opt(soeno, ((owner << 8) | no | (wID << 16))); memset(&g_yk_info[index], 0, sizeof(REMOTEYKSTATUS)); return 0; } } return -20; } int RemoteCtrl(BYTE yktype, BYTE index, BYTE ykval, WORD wID) { int ret; char buf[128]; ret = _RemoteCtrl(yktype, index, ykval, wID); if (ret != 0) { BYTE no, owner; WORD soeno; if (ykval == YK_VAL_HZ) { no = g_do_table[index].indexno[0]; owner = g_do_table[index].owner; } else { if (g_do_table[index].indexno[1]) { no = g_do_table[index].indexno[1]; } else { no = g_do_table[index].indexno[0]; } owner = g_do_table[index].owner; } // soe if (yktype == YK_TYPE_SEL) { soeno = (ykval == YK_VAL_HZ) ? EV_YH_SELFAIL : EV_YT_SELFAIL; soe_record_opt(soeno, ((owner << 8) | no | (wID << 16))); } else if (yktype == YK_TYPE_EXE) { soeno = (ykval == YK_VAL_HZ) ? EV_YH_EXFAIL : EV_YT_EXFAIL; soe_record_opt(soeno, ((owner << 8) | no | (wID << 16))); } sprintf(buf, "遥控失败--%s:%s(ykno=0x%04x,yktype=%d,ykThz=%d)", get_yk_owner(wID), RmtCtrl_Err(ret), g_do_table[index].cp, yktype, ykval); log_str_time(LOG_OPERATE, buf, 0, 0); rt_printf_time("%s\r\n", buf); } return ret; } /************************************************************************** 函数名称:ResetRctrl 函数版本:1.00 作者: 创建日期:2005.6.14 函数功能说明:复归遥控信息表,在通道通信异常时调用,清相关标志 修改原因: ***************************************************************************/ void ResetRctrl(WORD wID) { int i; for (i = 0; i < g_table_head->do_num; i++) { if (g_yk_info[i].wMaster == wID) // 对应通道的遥控主站标示清零 { memset(&g_yk_info[i], 0, sizeof(REMOTEYKSTATUS)); } } } char *get_comm_name(int index) { return (char *)ykownerstr[index]; } char *get_yk_owner(u8 owner) { // BYTE owner=(lv>>16)&0xff; // 遥控来源 int index = 0; // 101遥控来源 if (owner >= MASTER_101 && (owner < (MASTER_101 + CFG_UART_NUM_MAX))) { index = owner - MASTER_101 + 1; } // 104遥控来源 else if (owner >= MASTER_104 && (owner < (MASTER_104 + CFG_UART_NUM_MAX + IEC104_TOTAL_SOCKETS))) { index = owner - MASTER_104 + 1; } // 维护工具 else if (owner >= MASTER_MAINTAIN && (owner < (MASTER_MAINTAIN + 1))) { index = owner - MASTER_MAINTAIN + CFG_UART_NUM_MAX + IEC104_TOTAL_SOCKETS + 1; } return (char *)ykownerstr[index]; } /****************************************************************************** 函数名称: send_rmt_yc 函数版本: 01.01 创建作者: xxxxxx 创建日期: 2014-12-16 函数说明: 远动测试--遥测 参数说明: buf 返回值: 成功返回0. 修改记录: */ int send_rmt_yc(u8 *buf) { g_rmt_set_yc.owner = buf[5]; g_rmt_set_yc.indexno = buf[7]; g_rmt_set_yc.val = (buf[8] | buf[9] << 8 | buf[10] << 16 | buf[11] << 24); return 0; } int send_rmt_dd(u8 *buf) { g_rmt_set_dd.owner = buf[5]; g_rmt_set_dd.indexno = buf[7]; g_rmt_set_dd.val = (buf[8] | buf[9] << 8 | buf[10] << 16 | buf[11] << 24); return 0; } /****************************************************************************** 函数名称: send_rmt_yx 函数版本: 01.01 创建作者: xxxxxx 创建日期: 2014-12-16 函数说明: 远动测试--遥信 参数说明: buf 返回值: 成功返回0. 修改记录: */ int send_rmt_yx(u8 *buf) { bool bY1, bY2; struct timespec ts; YD_YXTABLE yd_yxtable; u8 stu = 0; // 取当前时间 clk_time_get(&ts); // 点表类型 yd_yxtable.type = buf[2]; // 点号 yd_yxtable.no = buf[3] | buf[4] << 8; // 归属 yd_yxtable.owner = buf[5]; // 实点、虚点 yd_yxtable.is_real = buf[6]; // 资源表中索引 yd_yxtable.indexno = buf[7]; // 值 yd_yxtable.value = (buf[8] | buf[9] << 8 | buf[10] << 16 | buf[11] << 24); // 双点 if (yd_yxtable.type == 0x03) { int m; for (m = 0; m < g_table_head->di_db_num; m++) { if (yd_yxtable.no == g_di_db_table[m].cp) { // 检索双点是否有效 bY1 = _yx_is_config(((g_di_db_table[m].no[0] >> 8) & 0xff), (g_di_db_table[m].no[0] & 0xff)); bY2 = _yx_is_config(((g_di_db_table[m].no[1] >> 8) & 0xff), (g_di_db_table[m].no[1] & 0xff)); if (bY1 && bY2) { stu = yd_yxtable.value; break; } else { return 0; } } } } // 合并点 else if (yd_yxtable.type == 0x04) { int m; for (m = 0; m < g_table_head->dimerge_num; m++) { if (yd_yxtable.no == g_di_merge_table[m].cp) { // 检索合并点是否有效 bY1 = _yx_is_config(((g_di_merge_table[m].no[0] >> 8) & 0xff), (g_di_merge_table[m].no[0] & 0xff)); if (bY1) { stu = g_di_merge_table[m].is_inv_all ? !yd_yxtable.value : yd_yxtable.value; break; } else { return 0; } } } } // 单点 else { int m; for (m = 0; m < g_table_head->di_num; m++) { if (yd_yxtable.no == g_di_table[m].cp) { bY1 = _yx_is_config(yd_yxtable.owner, yd_yxtable.indexno); if (bY1) { stu = g_di_table[m].is_inverse ? !yd_yxtable.value : yd_yxtable.value; break; } else { return 0; } } } } // TODO:值需要确认 soe_record_tst(yd_yxtable.no, stu); return 0; } /****************************************************************************** 函数名称: send_rmt_yk 函数版本: 01.01 创建作者: xxxxxx 创建日期: 2014-12-16 函数说明: 远动测试--遥控 参数说明: buf 返回值: 成功返回0. 修改记录: */ int send_rmt_yk(u8 *buf) { u32 value, i; u16 indexno; u8 ykThz, v; int ret; indexno = buf[3] | buf[4] << 8; value = (buf[8] | buf[9] << 8 | buf[10] << 16 | buf[11] << 24); if (value == 0) { ykThz = YK_VAL_TZ; } else { ykThz = YK_VAL_HZ; } for (i = 0; i < g_table_head->do_num; i++) // 查找遥控转发表,看是否有有效的遥控点 { if (indexno != g_do_table[i].cp) // 遥控点号对应 { continue; } // 如果配置了级联通道,转发 if (g_do_table[i].link_ch) { v = (ykThz == YK_VAL_HZ) ? 1 : 0; if (lnk_master_yk(&g_do_table[i], 0xff, 6, v) == 0) { return 0; } { return -22; } } else { ret = RemoteCtrl(YK_TYPE_SEL, i, ykThz, MASTER_MAINTAIN); if (ret != 0) { return ret; } ret = RemoteCtrl(YK_TYPE_EXE, i, ykThz, MASTER_MAINTAIN); if (ret != 0) { return ret; } return 0; } } // 返回"没有实际对应点,请检查遥控点表" return -4; } /*------------------------------ 内部函数 ------------------------------------- 内部函数以下划线‘_’开头,不需要检查参数的合法性. */ bool check_fault(void) { int sw; bool bY = false; for (sw = 0; sw < g_sw_num; sw++) // 保护动作 { TRELAY_T *pR = &g_tRelay[sw]; int i; bool bY1 = false; for (i = 0; i <= FA_DLBS; i++) { bY1 |= (pR->tOC[i].sta.bFlag.bTz || pR->tOC[i].sta.bFlag.bGj); } bY1 |= pR->tgoc.sta.bFlag.bglTz #if defined GD_AREA_ZHONGSHAN || defined GD_AREA_ZHONGSHAN_2020 || pR->tgoc.sta.bFlag.bgl2Tz #endif || pR->tgoc.sta.bFlag.blxTz || pR->tgoc.sta.bFlag.bgzglTz || pR->tgoc.sta.bFlag.bsdTz || pR->tgoc.sta.bFlag.bextTz || pR->tgoc.sta.bFlag.berrTz || pR->tgoc.sta.bFlag.bllhz; bY1 |= pR->uGLFSX.bFlag.bFXDZ; bY1 |= (pR->tCHZ.sta.bFlag.bHz || pR->tU0TZ.uZOV.bFlag.bTz || pR->tDYJL.sta.bFlag.bTz || pR->tPLJL.sta.bFlag.bTz || pR->tXXTZ.uZOV.bFlag.bTz || pR->tLostVot.uLostVot.bFlag.bTz); pR->bARSTFLT = bY1; // sw sgz bY |= bY1; // sgz } // sgz 标志 if (bY) { g_protect.bARSTFLT = true; return true; } return false; } /****************************************************************************** 函数名称: _yk_polling 函数版本: 01.01 创建作者: xxxxxx 创建日期: 2014-12-16 函数说明: 遥控巡检 参数说明: 无 修改记录: */ static void _yk_polling(void) { int i; if (g_yk_info == NULL) { return; } for (i = 0; i < g_table_head->do_num; i++) { switch (g_yk_info[i].yk_st) { case YK_STATUS_SEL: if (dTCounter - g_yk_info[i].dTStart >= tRunPara.dYKTime) // 遥控选择超时 { WORD soeno; if (g_yk_info[i].val == YK_VAL_HZ) { soeno = EV_YH_SELTOUT; } else { soeno = EV_YT_SELTOUT; } soe_record_opt(soeno, ((g_yk_info[i].owner << 8) | g_yk_info[i].no | (g_yk_info[i].wMaster << 16))); memset(&g_yk_info[i], 0, sizeof(REMOTEYKSTATUS)); // 置遥控超时状态,方便用户查看 g_yk_info[i].yk_st = YK_STATUS_TIMEOUT; } break; case YK_STATUS_EXE: // 经过10ms等待,至少让5ms保护巡检中断执行一次,以保证各逻辑使用到遥分、遥合标志 if (dTCounter - g_yk_info[i].dTStart >= T_10ms) // 遥控执行完成 { // TODO: xbtong if (g_yk_info[i].owner > 0) { int owner = g_yk_info[i].owner - 1; if ((g_yk_info[i].no == (SW_DO_YKH + 1)) || (g_yk_info[i].no == (SW_DO_BHH + 1))) { g_tRelay[owner].uRmtSW.bYHExecute = false; g_tRelay[owner].uRmtSW.bYHExecute_fa = false; } if ((g_yk_info[i].no == (SW_DO_YKT + 1)) || (g_yk_info[i].no == (SW_DO_BHT + 1))) { g_tRelay[owner].uRmtSW.bYTExecute = false; g_tRelay[owner].uRmtSW.bYTExecute_fa = false; } } memset(&g_yk_info[i], 0, sizeof(REMOTEYKSTATUS)); } break; default: break; } } } /************************************************************************** 函数名称:_equerr_check 函数版本:1.00 作者: 创建日期:2008.9.24 函数功能说明:装置故障判断 输入参数: 其他输入: 输出参数: 返回值: 无 */ static void _equerr_check(void) { // 装置硬件故障 if (rt_err_count_hw() == 0) { if (soe_check(EV_EQU_ERR_HW)) { soe_record_ev(EV_EQU_ERR_HW, 0, 0, 0, 0); } } else { if (!soe_check(EV_EQU_ERR_HW)) { soe_record_ev(EV_EQU_ERR_HW, 1, 0, 0, 0); } } // 装置软件故障 if (rt_err_count_sw() == 0) { if (soe_check(EV_EQU_ERR_SW)) { soe_record_ev(EV_EQU_ERR_SW, 0, 0, 0, 0); } } else { if (!soe_check(EV_EQU_ERR_SW)) { soe_record_ev(EV_EQU_ERR_SW, 1, 0, 0, 0); } } #ifdef __IEC61850_GOOSE_FUNC__ if (goose_get_init_flag() > 0) { if (gi_platelib_state != IEC61850_LIB_INIT_SUCCESS && BH_GOOSE_EN(0)) // 智能FA投入,61850库初始化失败 { if (soe_check(EV_61850_ERR) == false) { soe_record_ev(EV_61850_ERR, 1, 0, 0, 0); } } else { if (soe_check(EV_61850_ERR) == true) { soe_record_ev(EV_61850_ERR, 0, 0, 0, 0); } } } #endif } /************************************************************************** 函数名称:_boarderr_check 函数版本:1.00 作者: 创建日期:2008.9.24 函数功能说明:子板故障判断 输入参数: 其他输入: 输出参数: 返回值: 无 */ static void _boarderr_check(void) { int i; for (i = 0; i < EQU_SLOT_NUM_MAX; i++) // 分板故障判断 { if (g_board_info[i].is_check == 0) // 不需要检查的子板,直接跳过 { continue; } if (g_board_info[i].errcode == 0) // 板卡正常 { if (rt_err_clr(ERR_CODE_SB_FAULT, i) == 2) { soe_record_ev(EV_BOARDERR, 0, 0, 0, 0); } } else { if (rt_err_set(ERR_CODE_SB_FAULT, i) == 2) { soe_record_ev(EV_BOARDERR, 1, 0, 0, 0); } } } } /************************************************************************** 函数名称:_signrst_auto 函数版本:1.00 作者: 创建日期:2008.9.24 函数功能说明:告警信号自动复归 输入参数: 其他输入: 输出参数: 返回值: 无 */ static void _signrst_auto(void) { if (tRunPara.dTRstT > 0 && tRunPara.bAutoRst) // 自动复归投入,且复归时间不为零,故障消失后,启动定时自动复归 { bool bY1; bool bFault = g_protect.bARSTFLT; // check_fault(); g_protect.bARSTFLT = false; bY1 = ((!bFault) && (run_status_dz_all() || g_tRelay[0].run_stu.chzdz)); // 计时启动条件,有告警信号,故障已消失 if (bFault) // 计时启动条件,有告警信号 { dTRstTime = dTCounter; } if (bY1) { // if((dTCounter-dTRstTime) tRunPara.dTRstT) { rt_printf_time("自动复归时间到...\r\n"); ResetHzLed(0); SignalReset(0, false); g_run_stu.button_on = true; dTRstTime = dTCounter; } } else { dTRstTime = dTCounter; } } else { dTRstTime = dTCounter; } if (tRunPara.dTRstT >= 0 && tRunPara.bAutoRst) // 自动复归投入,且复归时间为0 ,装置正常运行后自动复归 { int sw; for (sw = 0; sw < g_sw_num; sw++) // 按开关复归,复归条件为无故障、故障产生过,开关在合位 { TRELAY_T *pR = &g_tRelay[sw]; RUN_STU_SW *prun = &g_tRelay[sw].run_stu; bool bY1 = pR->bARSTFLT; pR->bARSTFLT = 0; if ((!bY1) && (prun->dz == RY_DZ_XYBS || prun->dz == RY_DZ_BHT) && pR->run_stu.sw == 2) // 开关在合位,并且本开关无故障()(!pR->tCHZ.sta.bFlag.bCHDZ)&& { // rt_printf("合位复归...\r\n"); // rt_printf("."); } } } } /****************************************************************************** 函数名称: _yx_is_config 函数版本: 01.01 创建作者: xxxxxx 创建日期: 2014-12-16 函数说明: 检索遥信的板卡和硬件编号 参数说明: buf 返回值: 成功返回0. 修改记录: */ int _yx_is_config(WORD owner, WORD index) { if (index == 0) { return false; } index--; if (owner == 0) // 公共开入 { if (index < PUB_DI_NUM) { if ((short)g_sw_pub.di_cfg_index[index] == INDEX_INVALLID) { return false; } } } else { if (index < SW_DI_NUM) { if ((short)g_sw[owner - 1].di_cfg_index[index] == INDEX_INVALLID) { return false; } } } return true; } #ifdef FUNC_RESET_EQU bool gb_ResetEqu = false; void equ_PowerRest(void) { static DWORD s_dT_3s = 0; static bool b_FirstIn = true; if (gb_ResetEqu) { if (b_FirstIn) { s_dT_3s = dTCounter; b_FirstIn = false; } if ((dTCounter - s_dT_3s) >= 3 * T_1s) { s_dT_3s = 0; b_FirstIn = true; gb_ResetEqu = false; rt_printf_time("3S延时到,断开常闭继电器重启装置\r\n"); if (sw_do_pub(PUB_RESET_EQU, SW_DO_TYPE_ON) != 0) { rt_printf("硬重启失败,检查通道配置!!!\r\n"); } } } } #endif /*------------------------------ 测试函数 ------------------------------------- 一个实体文件必须带一个本模块的测试函数来进行单元测试,如果的确不方便在本模块中 进行单元测试,必须在此注明实际的测试位置(例如在哪个实体文件中使用哪个测试函数). */ /*------------------------------ 文件结束 ------------------------------------- */