checkroutine.c
来自「电力系统中的保护装置全部代码」· C语言 代码 · 共 550 行 · 第 1/2 页
C
550 行
{
pSOE = &pRPT->pro_report_soe;
if (pSOE->SOE_Inf = pCheck->SOE_Inf)
{
pRPT->mmi_flag &= ~MMIPICKUP;
break;
}
else
{
if (++pRPT > &ReportRAM[REPORTRAM - 1])
pRPT = ReportRAM;
}
}
}
/***********************************************************************************/
/* A/D报警程序 */
/***********************************************************************************/
extern UNSIGNED uADErrorCNT;
VOID AD_Check_Routine(CHECK *pCheckx)
{
register CHECK *pCheck = pCheckx;
if (!pCheck->pickup_flag) //自检没动作
{
if (uADErrorCNT >= 3) //连续3次AD转换出错(在采样中断中计数)
{
TestFailure(pCheck); //告警
}
}
}
/***********************************************************************************/
/* 开出自检程序 */
/***********************************************************************************/
UNSIGNED uDOCheckInterval = 0 - 60 * 60 * 1000; //开出驱动自检,间隔为1小时,赋此初值可使上电即自检一次
UNSIGNED uDOCheckCHN[] = {TZJ,HZJ,YTJ,YHJ,GXJ,BY1,BY2,BY3,BY4,BY5,QDJ}; //指定自检的开出通道
VOID DO_Check_Routine(CHECK *pCheck)
{
register UNSIGNED i;
register UNSIGNED *p;
register UNSIGNED uTestFail,uClock;
register OPTION old_preempt;
old_preempt = NU_Change_Preemption(NU_NO_PREEMPT); //不再切换任务,避免被其他任务打断,造成误动
if(DOChn[BSJ].state) //必须已经开放24VGND,击穿自检实时进行,驱动自检每小时进行一次
{
if(!pCheck->pickup_flag) //开出回路自检未动作
{
uClock = TMD_System_Clock; //记下当前时间
while((*pDIN3PORT & OUTRET) == 0) //有开出反馈
{
if((Switchout_buf & 0x1fff) != 0x1fff) break; //有开出被驱动,正常
if(TMD_System_Clock - uClock >= 5) //没有开出被驱动,等待5ms
{
TestFailure(pCheck); //5ms后,开出仍有反馈,告警
break;
}
}
if (TMD_System_Clock - uDOCheckInterval >= 60 * 60 * 1000) //间隔是否超过1小时
{
uDOCheckInterval = TMD_System_Clock; //刷新间隔时间
if ((Switchout_buf & 0x1fff) == 0x1fff) //只有开出未驱动时,才进行自检
{
uTestFail = 0; //初始化失败标志
p = uDOCheckCHN; //指向要自检的通道
for (i = 0; i < sizeof(uDOCheckCHN); i++) //把指定自检的通道,逐个自检
{
*pDOPORT = Switchout_buf & ~(1 << *p++); //驱动开出
uClock = TMD_System_Clock; //记下时间
while (*pDIN3PORT & OUTRET) //读反馈
{
if (TMD_System_Clock - uClock < 10) continue; //10ms内无反馈,继续
TestFailure(pCheck); //超过10ms,报告失败
uTestFail = 1;
break;
}
if (uTestFail) break;
*pDOPORT = Switchout_buf; //收开出
uClock = TMD_System_Clock; //记下时间
while (!(*pDIN3PORT & OUTRET)) //读反馈
{
if (TMD_System_Clock - uClock < 10) continue; //10ms内有反馈,继续
TestFailure(pCheck); //超过10ms,报告失败
uTestFail = 1;
break;
}
if (uTestFail) break;
}
}
}
}
}
else
{ //自检闭锁继电器是否击穿
/* *pDOPORT = Switchout_buf & ~GXJ;
uClock = TMD_System_Clock; //记下时间
while (TMD_System_Clock - uClock < 2) //等待2毫秒
{
if (!(*pDIN3PORT & OUTRET)) //无反馈,继续
{
TestFailure(pCheck); //有反馈,报告失败
break;
}
}*/
}
NU_Change_Preemption(old_preempt); //可以切换任务
}
/***********************************************************************************/
/* 定值区号自检程序 */
/***********************************************************************************/
VOID SET_ZONE_Routine(CHECK *pCheckx) //定值区自检
{
register CHECK *pCheck = pCheckx;
if (iLONC_SetZoneNum < 0 || iLONC_SetZoneNum >= SETTINGNUM) //定值区越界
{
if (!pCheck->pickup_flag) //告警
{
iLONC_SetZoneNum = SETTINGNUM; //定值区设为SETTINGNUM,以免是一随机的大值
TestFailure(pCheck);
}
}
else
if (pCheck->pickup_flag) //自检返回
{
TestRecovery(pCheck);
}
}
/***********************************************************************************/
/* 参数自检程序 */
/***********************************************************************************/
VOID PARA_SET_Routine(CHECK *ptr)
{
}
/***********************************************************************************/
/* 定值自检程序 */
/***********************************************************************************/
VOID PRO_SET_Routine(CHECK *pCheckx) //定值自检
{
register UNSIGNED i,k,n;
register INT j;
register PROTECT *protect;
register SETTING *pSets;
register CHECK *pCheck = pCheckx;
float fHigh,fLower;
if (iLONC_SetZoneNum < 0 || iLONC_SetZoneNum >= SETTINGNUM) return; //定值区号出错,不自检定值
j = iLONC_SetZoneNum; //当前定值区
k = 0; //初始化标志
protect = PRO_Created_Protect_List; //保护指针
for (i = 0; i < PRO_Total_Protect; i++, protect = protect->pro_link_next)
{
if (k) break;
pSets = protect->pro_setting;
for (n = 0; n < protect->pro_setting_number; n++)
{
fHigh = pSets->set_high_limit;
fLower = pSets->set_lower_limit;
if (pSets->set_calculate_style == CHL_FOURIER1_)
{
fHigh *= fHigh;
fLower *= fLower;
}
if (pSets->set_value_zone[j] > fHigh || pSets->set_value_zone[j] < fLower) //判定值是否越界
{
k = 1;
break;
}
pSets++;
}
}
if (k)
{
if (!pCheck->pickup_flag) //告警
{
TestFailure(pCheck);
}
}
else
if (pCheck->pickup_flag)
{
TestRecovery(pCheck); //告警返回
}
}
/***********************************************************************************/
/* 控制回路自检程序 */
/***********************************************************************************/
VOID ControlCircuitTest_Routine(CHECK *pCheckx)
{
register CHECK *pCheck = pCheckx;
if (!(DIChn[HW].state ^ DIChn[TW].state)) //判断跳位,合位是否全部有或没有
{
if (!pCheck->startup_flag)
{
if ((TMD_System_Clock - pCheck->delay_time) >= 3000) //延时3秒
TestFailure(pCheck);
}
}
else if(pCheck->startup_flag) //跳位,合位之一有,控制回路断线告警返回
{
if(TMD_System_Clock - pCheck->delay_time >= 500) //延时0.5秒返回
TestRecovery(pCheck); //告警返回
}
else
{
pCheck->delay_time = TMD_System_Clock; //不启动延时,刷新ControlCircuitTime
}
}
/***********************************************************************************/
/* 弹簧蓄能自检程序 */
/***********************************************************************************/
VOID Spring_Test_Routine(CHECK *pCheckx)
{
register CHECK *pCheck = pCheckx;
if(DIChn[THWXN].state) //弹簧未蓄能开入状态
{
if(!pCheck->pickup_flag) //有开入,且未告警
{
if(TMD_System_Clock - pCheck->delay_time >= 5000) //延时5秒
{
THFailure(pCheck); //报告失败
}
}
}
else if(pCheck->pickup_flag) //无开入,且以前为告警状态
{
if(TMD_System_Clock - pCheck->delay_time >= 500) //延时0.5秒
{
THRecovery(pCheck); //告警返回
}
}
else
{
pCheck->delay_time = TMD_System_Clock; //刷新时间
// THWXN_Flag = 0;
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?