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 + -
显示快捷键?