c#定时器顺序控制写法

csharp 复制代码
using System;
using System.Windows.Forms;

namespace c_顺序控制demo
{
    public partial class Form1 : Form
    {
        // =================================================================
        // 核心变量定义:模拟 PLC 内部寄存器
        // =================================================================

        // 定义流程状态枚举,增强可读性(等同于 PLC 的步进状态)
        private enum Step
        {
            Idle = 0,
            StartInfeed = 10,  // 进料步
            Processing = 20,   // 加工步
            Outfeed = 30,      // 出料步
            Complete = 40      // 周期完成
        }

        private Step _currentStep = Step.Idle; // 当前运行步
        private bool _isPaused = false;        // 暂停标志位 (类似中间继电器)
        private int _processCounter = 0;       // 模拟计时器累积值

        public Form1()
        {
            InitializeComponent();
            InitializeCustomSettings();
        }

        private void InitializeCustomSettings()
        {
            // 初始化定时器:模拟 PLC 扫描周期 100ms
            processTimer.Interval = 100;
            processTimer.Enabled = false;

            // 绑定定时器事件(如果在设计器里绑过了,这里可以删掉)
            processTimer.Tick += ProcessTimer_Tick;

            lblStatus.Text = "系统就绪,请点击启动";
        }

        // =================================================================
        // 主扫描逻辑:相当于 PLC 的主程序循环
        // =================================================================
        private void ProcessTimer_Tick(object sender, EventArgs e)
        {
            // 顶尖架构首要规则:优先判断"允许运行"条件
            if (_isPaused) return;

            // 使用 Case 语句实现严格的步进控制
            switch (_currentStep)
            {
                case Step.Idle:
                    UpdateStatus("停止中");
                    break;

                case Step.StartInfeed:
                    UpdateStatus("步骤 10: 正在进料...");
                    if (WaitCycles(20)) // 模拟等待 2 秒 (20 * 100ms)
                    {
                        _currentStep = Step.Processing;
                    }
                    break;

                case Step.Processing:
                    UpdateStatus("步骤 20: 核心加工中...");
                    if (WaitCycles(30)) // 模拟等待 3 秒
                    {
                        _currentStep = Step.Outfeed;
                    }
                    break;

                case Step.Outfeed:
                    UpdateStatus("步骤 30: 正在出料...");
                    if (WaitCycles(15)) // 模拟等待 1.5 秒
                    {
                        _currentStep = Step.Complete;
                    }
                    break;

                case Step.Complete:
                    UpdateStatus("步骤 40: 单次循环完成,准备重启");
                    _currentStep = Step.StartInfeed; // 自动跳转回第一步,实现不停循环
                    break;

                default:
                    _currentStep = Step.Idle;
                    break;
            }
        }

        // =================================================================
        // 功能块封装:模拟 PLC 中的 TON 计时器
        // =================================================================
        private bool WaitCycles(int target)
        {
            _processCounter++;
            if (_processCounter >= target)
            {
                _processCounter = 0; // 计数器清零,准备下一步
                return true;
            }
            return false;
        }

        // =================================================================
        // UI 事件处理:按钮控制
        // =================================================================

        private void btnStart_Click(object sender, EventArgs e)
        {
            _currentStep = Step.StartInfeed;
            _processCounter = 0;
            _isPaused = false;
            processTimer.Start();
            UpdateStatus("流程启动");
        }

        private void btnPause_Click(object sender, EventArgs e)
        {
            // 仅置位暂停标志,不停止 Timer,模拟控制系统的"暂停/挂起"
            _isPaused = true;
            UpdateStatus($"已暂停在: {_currentStep}");
        }

        private void btnResume_Click(object sender, EventArgs e)
        {
            // 复位暂停标志,逻辑从断点自动继续
            _isPaused = false;
            UpdateStatus("恢复运行...");
        }

        private void UpdateStatus(string msg)
        {
            // 实时反馈到界面
            lblStatus.Text = $"状态: {msg} | 计数: {_processCounter}";
        }

       
    }
}

//------------------总结如下-------------------------

为什么说这是"顶尖"的写法?

  1. 业务逻辑与定时器控制分离

    很多初学者会在暂停时调用 Timer.Stop()。高手不这么做。 在工业控制思维中,主 CPU(定时器)应该一直运行,通过一个"允许位"(如 _isPaused)来控制业务逻辑是否执行。这样可以方便地在暂停期间监控传感器状态或处理 UI 更新。

  2. 枚举(Enum)优于数字

    使用 Step.Processing 代替数字 20。当你的程序达到几千行时,你不需要去查文档才知道数字代表什么,代码本身就是文档。

  3. 模拟 PLC 计数器

    我写了一个 WaitCycles 方法。这模仿了 PLC 里的 TON(接通延时定时器)。在 switch 结构中,只有当计数达标时才切换状态,这保证了状态切换的严谨性,不会因为 UI 的卡顿导致逻辑跳步。

  4. 易于实现"断点续传"

    因为我们在暂停时没有重置 _currentStep 和 _processCounter,所以按下"继续"按钮时,程序会精准地从刚才那一秒、那个步骤继续往下跑,完美符合产线逻辑。

相关推荐
Cyber4K1 小时前
【Python专项】Nginx访问日志分析时间范围处理示例
开发语言·python·nginx
中犇科技2 小时前
郑州无代码APP开发公司哪家好呢?推荐
开发语言
周末也要写八哥2 小时前
代码中的注释的重要性(二)
开发语言·python
江南十四行3 小时前
Python生成器与协程:从迭代器到异步编程的进阶之路
开发语言·python
测试员周周3 小时前
【AI测试功能3】AI功能测试的三层架构:单元测试 → 集成测试 → E2E测试——AI系统测试金字塔实战指南
开发语言·人工智能·python·功能测试·架构·单元测试·集成测试
lly2024063 小时前
AppML 案例原型
开发语言
jllllyuz4 小时前
MATLAB 回声抵消(AEC)、噪声抑制(NS)、自动增益控制(AGC)完整实现
开发语言·matlab
froginwe114 小时前
Vue.js 计算属性
开发语言
05候补工程师4 小时前
【408 从零到一】线性表逻辑特征、存储结构对比与 C/C++ 动态内存分配避坑指南
c语言·开发语言·数据结构·c++·考研