C#工业上通用的顺序控制写法

工业软件里,顺序程序控制最常见、最稳妥的是:

👉「状态机(Step / State) + 周期扫描(Timer/Loop) + 条件推进」

👉 延时用 TON(或等效逻辑),而不是 Thread.Sleep / await Delay

这就是PLC 思想在上位机里的延续。

工业顺序控制常见写法排名(按"真实使用率")

✅ 第一名(⭐⭐⭐⭐⭐):

状态机(Step)+ 周期扫描(Timer)【最常见】

写法特征

switch (Step)

{

case 10:

if (条件A)

Step = 20;

break;

复制代码
case 20:
    if (ton.Q(3000))
    {
        ton.Reset();
        Step = 30;
    }
    break;

}

//----------------------------下面用一个简单的示例,说明此种写法的好处---------------------------------

第一步:先定义一个定时器类

public sealed class Ton

{

private bool _running = false;

private long _startTick = 0;

复制代码
 public void Reset()
 {
     _running = false;
     _startTick = 0;
 }

 // 返回 true 表示"到时了"(相当于 TON.Q)
 public bool Q(int presetMs)
 {
     if (!_running)
     {
         _running = true;
         _startTick = Environment.TickCount64;
     }

     long elapsed = Environment.TickCount64 - _startTick;
     return elapsed >= presetMs;
 }

}

第二步:定义步序枚举类型和定时器实例化、枚举实例化

// ===== 步序枚举 =====

private enum Step

{

step10 = 0,

step20 = 10,

step30 = 20,

step40 = 30,

step50 = 40,

step60 = 50,

step70 = 900

}

// ===== TON 定时器(PLC 的 TON)=====

private readonly Ton _ton = new Ton();

//枚举实例化

private Step stepNumber = Step.step10;

第三步:开始在定时器中编写顺序控制逻辑

private async void timer1_Tick(object sender, EventArgs e)

{

switch (stepNumber)

{

case Step.step10:

_ton.Reset();

if (stepNumber == Step.step10)

{

richTextBox1.AppendText(DateTime.Now + " step10" + "\r\n");

}

stepNumber = Step.step20;

break;

复制代码
     case Step.step20:    
         stepNumber = Step.step30;
         Step1 = 100; //标志位赋值
         if (stepNumber == Step.step20)
         {
             richTextBox1.AppendText(DateTime.Now + "    step20" + "\r\n");
         }                              
         break;

     case Step.step30:                    
         if (Step1==100)
         {
             Step1= 0; //标志位清零
             richTextBox1.AppendText(DateTime.Now + "    step30" + "\r\n");
         }   
         if(_ton.Q(4000))
         {
            stepNumber = Step.step40;
         }
         break;

     case Step.step40:
         if (stepNumber == Step.step40)
         {
             richTextBox1.AppendText(DateTime.Now + "    step40" + "\r\n");
             stepNumber = Step.step50;
         }                    
         break;

     case Step.step50:
         if (stepNumber == Step.step50)
         {
             richTextBox1.AppendText(DateTime.Now + "    step50" + "\r\n");
             stepNumber = Step.step60;
         }
         break;
 }

}

//-----------下面是输出的结果----------------

打印出来的结果如下: