肥仔教程网

SEO 优化与 Web 开发技术学习分享平台

[codesys]CodeSys程序架构(基于 st编写)

  • 为什么会写下这篇?

8 月份旅游回来之后,这段时间我一直挺迷茫的。工作不忙了,我就自学起了 C++和 QT。寻思着反正也不太忙,就打算总结一下过去的经验,写一篇文章讲讲我对 PLC 以及 codesys 程序架构的理解。最初接触基恩士 KV7000 和台达的 EH、AS 系列 PLC,后来 我能独当一面,用上了基于 codesys 的台达 AX8 和汇川的 AC800,这可是我八年多积累的经验。同行们,咱们可以一起探讨探讨。

  • 开始思考

对于一台或者一条自动化设备的程序来讲,基本上就是各种信号的相互交流,像传感器的输入、电磁阀的输出、伺服驱动器的输入输出以及收发信息、视觉控制器的信号对接,还有触摸屏的界面输入和显示。那要怎么把这些信息整合到一块儿,弄出能正常运行而且还挺完美的设备呢?以前刚从电工变成助理编程工程师的时候,我也一开始就在琢磨这样的问题。刚开始弄的那一两台设备还撞机了,现在回想起来,真是觉得挺不好意思的。从现在开始,我来和大家分享一下我的经验。

  • 思路流程图

一台设备从流程上可以分成初始化模块、手动模块、自动运行模块、异常处理模块、统计模块以及通讯模块。

初始化模块:

设备上电之后,要处理所有非保持变量,把所有非保持的变量复位到工程师依照设备运行状况设定的状态,简单说就是给所有非保持变量设定一个初始值。比如说,所有电磁阀的输出肯定是处于 OFF 状态,但要是机构有干涉,担心会撞机,那就可以用保持型的电磁阀,或者保持型的变量,来保持开机时的输出。


手动模块:

这里面包含了电磁阀、继电器、伺服步进、UV 控制器、点胶控制器、四轴运动控制卡。在非自动运行的情况下,可以通过外部按钮输入,还能通过人机界面来操纵设备的机构。比如说,在触摸屏上点击按钮,就能操作气缸进行伸缩,也能操作伺服轴进行点到点的运动,这样能方便调试人员去调整结构的位置。


以下是在codesys里面,电磁阀控制的模块的代码:

FUNCTION_BLOCK CylControlVAR_INPUT  In                   :  Cyl_In            ;  CylSection           :  INT              ;//气缸模式选择 0:单线圈气缸 1:吸真空,破真空 2:继电器输出 3:双线圈保持型电磁阀 4:UV控制输出 5:双线圈中泄型电磁阀 6:针对夹爪气缸,空夹原限位亮和夹治具动限位亮  HideCylHomeSensor    :  BOOL            ;//是否屏蔽气缸原限位  HideCylMotionSensor  :  BOOL            ;//是否屏蔽气缸动限位  ChooseAlrm           :  BOOL            ;//TRUE: UNAlarm FALSE:Alarm  AutoHandMode         :  BOOL            ;// 手自动切换选择  ClearAlarm           :  BOOL            ;//解除报警  DelayAlarm           :  TIME            ;//报警延时  EMGS                 :  BOOL            ;//急停  bCylMoveLimit        :  BOOL := TRUE        ;// 气缸移动限制,为TRUE时可运行END_VARVAR_OUTPUT  Out                  :  Cyl_Out            ;END_VARVAR  tCylAlarm            :  ARRAY[0..6] OF TON      ;  tCylAlarmOK          :  BOOL            ;  CylGOTR              :  BOOL            ;//气缸GOT控制上升沿  CylGOTF              :  BOOL            ;//气缸GOT控制下降沿  CylGOTRb             :  BOOL            ;//气缸GOT控制上升沿  CylGOTFb             :  BOOL            ;//气缸GOT控制下降沿  tCylGOTRreset        :  TON              ;  tCylGOTFreset        :  TON              ;  tCylGOTRresetOK      :  BOOL            ;  tCylGOTFresetOK      :  BOOL            ;  R_TRIG               :  ARRAY[0..6] OF R_TRIG    ;//上升沿保持  F_TRIG               :  ARRAY[0..6]  OF F_TRIG    ;//下降沿保持aEND_VAR

CASE CylSection OF    0,6:      Out.CylA S=  ((CylGOTR AND AutoHandMode) OR (In.CylPLCa AND NOT AutoHandMode AND NOT Out.CylAlarm AND EMGS)) AND bCylMoveLimit;      //提取手动GOT的上升沿      R_TRIG[0](CLK:=In.CylGOTa,Q=>CylGOTR);      //上升沿标志的自复位,目前发现会自复位      //tCylGOTRreset(IN:=CylGOTR,PT:=T#10000MS,Q=> tCylGOTRresetOK,ET=>);      //CylGOTR R= tCylGOTRresetOK;
      Out.CylA R=  ((CylGOTF AND AutoHandMode) OR (NOT In.CylPLCa AND NOT AutoHandMode AND NOT Out.CylAlarm AND EMGS)) AND bCylMoveLimit;      //提取手动GOT的下降沿      F_TRIG[0](CLK:=In.CylGOTa,Q=>CylGOTF);      //下降沿标志的自复位      //tCylGOTFreset(IN:=CylGOTF,PT:=T#10000MS,Q=> tCylGOTFresetOK,ET=>);      //CylGOTF R= tCylGOTFresetOK;    1:      Out.CylA S=  (CylGOTR AND AutoHandMode) OR (In.CylPLCa AND NOT AutoHandMode );      R_TRIG[1](CLK:=In.CylGOTa,Q=>CylGOTR);      Out.CylA R=  (CylGOTF AND AutoHandMode) OR (NOT In.CylPLCa AND NOT AutoHandMode );      F_TRIG[1](CLK:=In.CylGOTa,Q=>CylGOTF);            Out.CylB S=  (CylGOTRb AND AutoHandMode) OR (In.CylPLCb AND NOT AutoHandMode );      R_TRIG[2](CLK:=In.CylGOTb,Q=>CylGOTRb);      Out.CylB R=  (CylGOTFb AND AutoHandMode) OR (NOT In.CylPLCb AND NOT AutoHandMode);      F_TRIG[2](CLK:=In.CylGOTb,Q=>CylGOTFb);    2:        Out.CylA S=  (CylGOTR AND AutoHandMode) OR (In.CylPLCa AND NOT AutoHandMode );      R_TRIG[4](CLK:=In.CylGOTa,Q=>CylGOTR);      Out.CylA R=  (CylGOTF AND AutoHandMode) OR (NOT In.CylPLCa AND NOT AutoHandMode );      F_TRIG[4](CLK:=In.CylGOTa,Q=>CylGOTF);    3:      Out.CylB S=  (CylGOTR AND AutoHandMode) OR (In.CylPLCa AND NOT AutoHandMode AND NOT Out.CylAlarm AND EMGS);      Out.CylA R= (CylGOTR AND AutoHandMode) OR (In.CylPLCa AND NOT AutoHandMode AND NOT Out.CylAlarm AND EMGS);      R_TRIG[3](CLK:=In.CylGOTa,Q=>CylGOTR);            Out.CylB R=  (CylGOTF AND AutoHandMode) OR (NOT In.CylPLCa AND NOT AutoHandMode AND NOT Out.CylAlarm AND EMGS);      Out.CylA S=  (CylGOTF AND AutoHandMode) OR (NOT In.CylPLCa AND NOT AutoHandMode AND NOT Out.CylAlarm AND EMGS);      F_TRIG[3](CLK:=In.CylGOTa,Q=>CylGOTF);    4:      Out.CylA :=  (In.CylGOTa AND AutoHandMode) OR (In.CylPLCa AND NOT AutoHandMode );    5:      R_TRIG[5](CLK:=In.CylGOTa,Q=>CylGOTR);      F_TRIG[5](CLK:=In.CylGOTa,Q=>CylGOTF);      R_TRIG[6](CLK:=In.CylGOTb,Q=>CylGOTRb);      F_TRIG[6](CLK:=In.CylGOTb,Q=>CylGOTFb);            IF  NOT In.CylPLCa    AND        NOT AutoHandMode        THEN          Out.CylA S= TRUE;      END_IF            IF  In.CylPLCa      AND        NOT AutoHandMode        THEN          Out.CylA R= TRUE;      END_IF            IF  F_TRIG[5].Q      AND        AutoHandMode        THEN          Out.CylA S= TRUE;      END_IF            IF  R_TRIG[5].Q      AND        AutoHandMode        THEN          Out.CylA R= TRUE;      END_IFEND_CASE
(*****************气缸的报警的产生以及清除,还有是否屏蔽气缸的传感器************************)CASE CylSection OF  0:    tCylAlarm[0](IN:=(((Out.CylA AND NOT In.CylMotion) OR (NOT Out.CylA AND In.CylMotion)) AND NOT HideCylMotionSensor)OR(((NOT Out.CylA AND NOT In.CylHome)OR(Out.CylA AND In.CylHome))AND NOT HideCylHomeSensor),PT:=DelayAlarm,Q=> tCylAlarmOK,ET=>);  1:// 当破真空有反应,吸真空关闭和吸真空有感应,也不会报警    tCylAlarm[1](IN:=(Out.CylA AND NOT In.CylMotion)OR(NOT Out.CylA AND NOT Out.CylB AND In.CylMotion),PT:=DelayAlarm,Q=> tCylAlarmOK,ET=>);  3:    tCylAlarm[2](IN:=((Out.CylB AND NOT In.CylMotion) AND NOT HideCylMotionSensor)OR((Out.CylA AND NOT In.CylHome)AND NOT HideCylHomeSensor),PT:=DelayAlarm,Q=> tCylAlarmOK,ET=>);    4:    tCylAlarm[4](IN:=In.CylMotion,PT:=DelayAlarm,Q=> tCylAlarmOK,ET=>);    5:    tCylAlarm[5](IN:=(Out.CylA AND (NOT In.CylHome OR In.CylMotion))OR(NOT Out.CylA AND (In.CylHome OR NOT In.CylMotion)),PT:=DelayAlarm,Q=> tCylAlarmOK,ET=>);    6:    tCylAlarm[6](IN:=(Out.CylA AND In.CylMotion) OR (Out.CylA AND In.CylHome) OR(NOT Out.CylA AND NOT In.CylHome AND NOT In.CylMotion),PT:=DelayAlarm,Q=> tCylAlarmOK,ET=>);END_CASEOut.CylAlarm S= tCylAlarmOK AND NOT ChooseAlrm;Out.CylAlarm R= ClearAlarm;
In.CylAutoRunningAlarm  R=  ClearAlarm;


自动运行模块:

设备处于自动状态时,能够实现机械工程师和工艺工程师最初对设备的构想,生产出合格的产品,而且产能也能达到要求。这个模块只要按下启动按钮,在设备没有异常的情况下,就能进行自动化运行。这部分或许对于初学者来说是最难的了。


以下的代码是最新的自动线其中一个模块的自动化的程序:

(*********************************程序急停后处理*********************************)(*  IF  NOT GVL.bEMGS    THEN  //模块状态的复位        Mode.AMacA3Mode.bIniting            := FALSE;        Mode.AMacA3Mode.bInitOK             := FALSE;        Mode.AMacA3Mode.bAlone              := FALSE;        Mode.AMacA3Mode.bAloneRunning          := FALSE;        Mode.AMacA3Mode.bAutoHandMode          := FALSE;                //自动运行标志的复位        bAMacA3ModeAuto                  := FALSE;                //吸真空 破真空的关闭        //各模块信号对接的信号复位        //托盘当前数目的复位        //各程序控制流程标志的复位        Mode.AMacA3Mode.iInit              := 0;        Mode.AMacA3Mode.iAutoRunning[0]          := 0;                //停料标志的复位  END_IF  *)(*********************************自动线可运动处理***********************************)  Mode.AMacA3Mode.bAutoMacMoveSafe := NOT IOVar.Cyl_A3_Fixed.In.CylHome    OR                    NOT IOVar.Cyl_A3_Rise.In.CylHome;(*********************************程序托盘处理*************************************)(*********************************程序单独运行处理*********************************)  IF  Mode.AMacA3Mode.bAlone    THEN      GVL.bAutoRunning  R= TRUE;      GVL.bAutoHandMode S= TRUE;      Mode.AMacA3Mode.bUnAloneRunning R= TRUE;  END_IF    Mode.AMacA3Mode.bAloneRunning  S=  NOT Mode.AMacA3Mode.bAlarm      AND                    GVL.bEMGS              AND                    Mode.AMacA3Mode.bAlone        AND                    NOT Mode.AMacA3Mode.bAutoHandMode  AND                    Mode.AMacA3Mode.bInitOK        AND                    Mode.AMacA3Mode.bGOTRunButton    AND                    NOT GVL.bAutoRunning;    Mode.AMacA3Mode.bAloneRunning  R=  Mode.AMacA3Mode.bAlarm      OR                    NOT GVL.bEMGS          OR                    NOT Mode.AMacA3Mode.bAlone    OR                          Mode.AMacA3Mode.bAutoHandMode  OR                    NOT Mode.AMacA3Mode.bInitOK    OR                    Mode.AMacA3Mode.bGOTStopButton  OR                    GVL.bAutoRunning;(*********************************程序非单独整机自动运行处理*********************************)  // 自动运行处理  Mode.AMacA3Mode.bUnAloneRunning  S=  NOT GVL.bAutoHandMode      AND                    NOT Mode.AMacA3Mode.bAlarm    AND                    Mode.Line.bInitOK        AND                    GVL.bRunButton          AND                    NOT GVL.b_Tips_ModeInAlone;  Mode.AMacA3Mode.bUnAloneRunning  R=  GVL.bAutoHandMode        OR                    Mode.AMacA3Mode.bAlarm      OR                    NOT Mode.Line.bInitOK      OR                    GVL.bStopButton          OR                    GVL.b_Tips_ModeInAlone                    ;(*********************************模块报警处理*********************************)  Mode.AMacA3Mode.bAlarm      :=  IOVar.Cyl_A3_Fixed.Out.CylAlarm                OR                    IOVar.Cyl_A3_Rise.Out.CylAlarm                OR                    GVL.b_Alarm_A3_HightNG                    ;(*********************************报警解除处理*********************************)  GVL.b_Alarm_A3_HightNG R= GVL.bClearAlarm OR Mode.AMacA3Mode.bGOT_ClearAlarm;(*********************************调用节拍功能快*********************************)  FBModeCycleTime(bCycleTime:= Mode.AMacA3Mode.bAutoMacTellModeStart, bAutoRunning:= bAMacA3ModeAuto, uiCycleTime=> Mode.AMacA3Mode.uiCycleTime);(*********************************当前模块自动运行处理*********************************)  bAMacA3ModeAuto  :=  (Mode.AMacA3Mode.bAlone AND Mode.AMacA3Mode.bAloneRunning )  OR            (NOT Mode.AMacA3Mode.bAlone AND Mode.AMacA3Mode.bUnAloneRunning);(*********************************A机台A3模块延时处理*********************************)  // 升降气缸压合治具到位后  TonDelay[0](  IN:=IOVar.Cyl_A3_Rise.Out.CylA  AND          IOVar.Cyl_A3_Rise.In.CylMotion,          PT:=UINT_TO_TIME(PG.ui_A3_Mode_TiemDelay[0])        );  // 升降气缸压合治具到位后检测时长  TonDelay[1](  IN:=IOVar.Cyl_A3_Rise.Out.CylA  AND          IOVar.Cyl_A3_Rise.In.CylMotion,          PT:=UINT_TO_TIME(PG.ui_A3_Mode_TiemDelay[1])        );        (*********************************A机台A3模块复位流程*********************************)  CASE  Mode.AMacA3Mode.iInit  OF    0:      //单独运行的复位程序        IF  Mode.AMacA3Mode.bGOTInit  AND          Mode.AMacA3Mode.bAlone    AND          NOT Mode.AMacA3Mode.bInitOK          THEN  Mode.AMacA3Mode.bIniting := TRUE;              Mode.AMacA3Mode.bInitOK := FALSE;              Mode.AMacA3Mode.iInit := SEL(Mode.AMacA3Mode.bAlone AND NOT Mode.AMacA3Mode.bAutoHandMode AND NOT Mode.AMacA3Mode.bAlarm,0,10);        END_IF              //整机运行的复位程序        IF  GVL.bInitButton   AND          NOT Mode.AMacA3Mode.bInitOK          THEN            Mode.AMacA3Mode.bIniting := TRUE;            Mode.AMacA3Mode.bInitOK := FALSE;            Mode.AMacA3Mode.iInit := SEL(NOT GVL.bAutoHandMode AND NOT GVL.bAlarm,0,10);        END_IF    10://定位气缸 升降气缸回原      Mode.AMacA3Mode.bIniting S= TRUE;      IOVar.Cyl_A3_Fixed.In.CylPLCa R= TRUE;      IOVar.Cyl_A3_Rise.In.CylPLCa R= TRUE;      IF  Mode.AMacA3Mode.bIniting      AND        NOT  IOVar.Cyl_A3_Fixed.In.CylPLCa  AND        IOVar.Cyl_A3_Fixed.In.CylHome    AND        NOT  IOVar.Cyl_A3_Rise.In.CylPLCa  AND        IOVar.Cyl_A3_Rise.In.CylHome        THEN          Mode.AMacA3Mode.iInit := SEL((Mode.AMacA3Mode.bAlone AND NOT Mode.AMacA3Mode.bAutoHandMode AND NOT Mode.AMacA3Mode.bAlarm)OR (NOT GVL.bAutoHandMode AND NOT GVL.bAlarm),10,100);      END_IF    100://复位完成      Mode.AMacA3Mode.bIniting R= TRUE;      Mode.AMacA3Mode.bInitOK S= TRUE;      Mode.AMacA3Mode.iInit := 0;  END_CASE(*********************************A机台A3治具压合兼高度检测循环*********************************)  CASE  Mode.AMacA3Mode.iAutoRunning[0]  OF    0:// 等待自动运行      Mode.AMacA3Mode.iAutoRunning[0]:=SEL(bAMacA3ModeAuto,0,10);    10:// 等待主线体通知运行      IF  Mode.AMacA3Mode.bAutoMacTellModeStart          OR        (Mode.AMacA3Mode.bGotSimulationTellModelStart AND Mode.AMacA3Mode.bAlone)        THEN          Mode.AMacA3Mode.iAutoRunning[0]:=SEL(bAMacA3ModeAuto,10,20);      END_IF    20:// 空      Mode.AMacA3Mode.iAutoRunning[0]:=SEL(bAMacA3ModeAuto,20,30);    30:// 判定治具左右穴是否有盆架      Mode.AMacA3Mode.bGotSimulationTellModelStart R= TRUE;      // 单模块开启:单模块运行下,A3小车定位气缸动作      IF  Mode.AMacA3Mode.bAlone        THEN          IOVar.Cyl_A3_Fixed.In.CylPLCa S= TRUE;          IF  IOVar.Cyl_A3_Fixed.In.CylPLCa  AND            IOVar.Cyl_A3_Fixed.In.CylMotion            THEN              Mode.AMacA3Mode.iAutoRunning[0]:=SEL(bAMacA3ModeAuto,30,40);          END_IF      END_IF      // 单模块关闭:      IF  NOT Mode.AMacA3Mode.bAlone          AND        IOVar.Cyl_A3_Fixed.In.CylPLCa        AND        IOVar.Cyl_A3_Fixed.In.CylMotion        THEN          //模块开启运行,左右穴有盆架          IF  PG.b_A3_ModeUse                AND            (Mode.AMacA3Mode.b_F4_Left_Frame_Have    OR            Mode.AMacA3Mode.b_F4_Right_Frame_Have)                THEN              Mode.AMacA3Mode.iAutoRunning[0]:=SEL(bAMacA3ModeAuto,30,40);          END_IF          //模块没有开启运行,左右穴没有盆架          IF  NOT PG.b_A3_ModeUse              OR            (NOT Mode.AMacA3Mode.b_F4_Left_Frame_Have  AND            NOT Mode.AMacA3Mode.b_F4_Right_Frame_Have)            THEN              Mode.AMacA3Mode.iAutoRunning[0]:=SEL(bAMacA3ModeAuto,30,10000);          END_IF      END_IF    40:// 升降气缸下降      IOVar.Cyl_A3_Rise.In.CylPLCa S= IOVar.Cyl_A3_Rise.In.CylHome;      IF  IOVar.Cyl_A3_Rise.In.CylPLCa  AND        IOVar.Cyl_A3_Rise.In.CylMotion  AND        TonDelay[0].Q        THEN          // 不是单模块单独运行,则不需要进行高度的判定          IF  NOT Mode.AMacA3Mode.bAlone            THEN              // 使用高度检测              IF  PG.b_A3_Mode_High_Use                THEN                  // 高度检测NG,报警                  IF  NOT IOVar.Sensor_A3_High                      THEN                      GVL.b_Alarm_A3_HightNG S= TRUE;                  END_IF                  // 检测高度在设定检测时间内合格                  IF  IOVar.Sensor_A3_High      AND                    TonDelay[1].Q                    THEN                      Mode.AMacA3Mode.iAutoRunning[0]:=SEL(bAMacA3ModeAuto,40,50);                  END_IF              END_IF              // 不使用高度检测              IF  NOT PG.b_A3_Mode_High_Use                THEN                  Mode.AMacA3Mode.iAutoRunning[0]:=SEL(bAMacA3ModeAuto,40,50);              END_IF          END_IF          //单模块单独运行开启          IF  Mode.AMacA3Mode.bAlone            THEN              Mode.AMacA3Mode.iAutoRunning[0]:=SEL(bAMacA3ModeAuto,40,50);          END_IF      END_IF    50:// 升降气缸缩回      IOVar.Cyl_A3_Rise.In.CylPLCa R= TRUE;      IF  NOT IOVar.Cyl_A3_Rise.In.CylPLCa  AND        IOVar.Cyl_A3_Rise.In.CylHome        THEN          Mode.AMacA3Mode.iAutoRunning[0]:=SEL(bAMacA3ModeAuto,50,60);      END_IF    60:// 是否单机运行?      // 是单机运行      IF  Mode.AMacA3Mode.bAlone        THEN          IOVar.Cyl_A3_Fixed.In.CylPLCa R= TRUE;          IF  NOT IOVar.Cyl_A3_Fixed.In.CylPLCa    AND            IOVar.Cyl_A3_Fixed.In.CylHome            THEN              Mode.AMacA3Mode.iAutoRunning[0]:=0;          END_IF      END_IF      // 非单机运行,通知主线放治具完成      IF  NOT Mode.AMacA3Mode.bAlone        THEN          Mode.AMacA3Mode.bModeTellAutoMacDone S= TRUE;          IF  Mode.AMacA3Mode.bModeTellAutoMacDone    AND            NOT Mode.AMacA3Mode.bAutoMacTellModeStart            THEN              Mode.AMacA3Mode.iAutoRunning[0]:=70;          END_IF      END_IF    70:// 信号处理      Mode.AMacA3Mode.bModeTellAutoMacDone R= TRUE;      IF  NOT Mode.AMacA3Mode.bModeTellAutoMacDone        THEN          Mode.AMacA3Mode.iAutoRunning[0]:=0;      END_IF    10000:// 通知主线此岗位没有开启运行,左右穴没有盆架      Mode.AMacA3Mode.bModeTellAutoMacDone S= TRUE;      IF  Mode.AMacA3Mode.bModeTellAutoMacDone    AND        NOT Mode.AMacA3Mode.bAutoMacTellModeStart        THEN          Mode.AMacA3Mode.iAutoRunning[0]:=10010;      END_IF    10010:// 信号处理      Mode.AMacA3Mode.bModeTellAutoMacDone R= TRUE;      IF  NOT Mode.AMacA3Mode.bModeTellAutoMacDone        THEN          Mode.AMacA3Mode.iAutoRunning[0]:=0;      END_IF  END_CASE


异常处理模块:

当设备出现这样的情况:电磁阀已经动作了,但是气缸却没有到达动限位,这部分会有一个报警延时。当报警延时结束后,首先设备得切换成手动状态,然后在触摸屏上会有个提醒,这时三色灯的红色灯就得亮起。当操机人员在手动状态下处理完异常后,就能够进入自动运行状态。


统计模块:

就是在生产过程中,对物料的投入、损耗和产出做一个统计。这样能方便对产线进行每小时的监控,从大概的方向排查不良情况。


通讯模块:

其实有一个模块,它可以包含在手动模块和自动模块之中,这个模块包括了提供网口、串口、IO 口用于外接设备的通讯,这样能方便我们使用和控制。

PLC程序架构(基于codesys st编写) PLC论坛-全力打造可编程控制器专业技术论坛 -

http://bbs.plcjs.com/forum.php?mod=viewthread&tid=503874&fromuid=42656

(出处: PLC论坛-全力打造可编程控制器专业技术论坛)

#非标自动化#

#codesys#

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言