在PLC编程中,最令工程师头疼的往往不是单一逻辑的实现,而是复杂流程的维护与扩展。传统的“线圈叠加”写法容易导致程序结构混乱、跳转逻辑不明,最终形成难以维护的“面条代码”。状态机设计模式通过将控制流程拆解为有限个独立的状态,并明确定义状态间的转移条件,是解决此类问题的核心方案。
一、 核心概念:什么是状态机?
状态机并非一种特定的编程语言,而是一种逻辑思维模型。在PLC程序中,它表现为一组有规则的变量切换。想象一列火车:它只能在“停靠”、“加速”、“匀速”、“减速”这几个状态中存在,而不能处于“半加速半停靠”的模糊状态。
1. 状态机的三要素
构建状态机必须包含以下三个核心要素:
| 要素名称 | 定义 | PLC中的表现形式 |
|---|---|---|
| 当前状态 | 系统此刻正在做什么 | 一个整数变量(如 Step = 1) |
| 触发条件 | 什么情况下进入下一步 | 传感器信号、定时器完成位、按钮输入 |
| 转移动作 | 切换状态时需要执行的操作 | 复位上一个动作,置位下一个动作 |
2. 为什么必须使用状态机?
如果采用传统的“自锁/互锁”梯形图写法,当工艺流程变更(例如增加一个“预清洗”步骤)时,你需要修改多处逻辑,极易造成双线圈冲突或逻辑死锁。而状态机模式下,你只需增加一个状态编号,并修改跳转目标即可,各状态之间天然隔离,互不干扰。
二、 实战模式一:整数状态法(推荐首选)
这是最通用、最清晰的实现方式,适用于西门子、三菱、欧姆龙等所有品牌PLC。核心思路是使用一个整数变量(如 Step 或 State_No)来标记当前步骤。
1. 变量规划
建立 一个全局变量 Current_State (INT类型)。
| 状态编号 | 工艺阶段 | 执行动作 |
|---|---|---|
0 |
待机/复位 | 所有输出复位,等待启动信号 |
10 |
进料 | 打开 进料阀 Y1,启动 进料泵 M1 |
20 |
加热 | 接通 加热器 H1,监测 温度传感器 |
30 |
排料 | 打开 出料阀 Y2 |
2. 程序结构搭建
使用 顺序扫描的编程结构(如ST语言中的 CASE...OF 或梯形图中的比较指令)。
// 示例:ST语言状态机框架
CASE Current_State OF
0: // 待机状态
// 动作:复位所有输出
Y1 := FALSE;
M1 := FALSE;
H1 := FALSE;
Y2 := FALSE;
// 转移条件
IF Start_Button = TRUE AND Safety_Sensor = TRUE THEN
Current_State := 10; // 跳转至进料
END_IF;
10: // 进料状态
// 动作
Y1 := TRUE;
M1 := TRUE;
// 转移条件:液位达到高位
IF Level_High = TRUE THEN
Current_State := 20; // 跳转至加热
END_IF;
20: // 加热状态
// 动作
H1 := TRUE;
// 转移条件:温度达到设定值
IF Temp_Real >= Temp_Set THEN
Current_State := 30; // 跳转至排料
END_IF;
30: // 排料状态
// 动作
Y2 := TRUE;
// 转移条件:液位达到低位且计时2秒结束
IF Level_Low = TRUE AND T1.Q = TRUE THEN
Current_State := 0; // 返回待机
END_IF;
END_CASE;
3. 关键细节:状态暂存与输出分离
在实际工程中,严禁 在状态内部直接驱动物理输出(如 Y1 := TRUE)。如果状态跳转瞬间发生断电,输出可能会保持异常状态。
采用 “中间变量映射法”:
- 在状态逻辑中,只驱动中间标志位(如
M_Run_Pump)。 - 在程序末尾的输出映射段,执行
Y1 := M_Run_Pump AND NOT Emergency_Stop。
三、 实战模式二:置位复位法(S/R逻辑)
如果不习惯整数比较,或者PLC内存极为有限,可以使用置位/复位指令构建状态流。这种方法在梯形图中非常直观。
1. 逻辑构建原理
利用“步进继电器”的概念。每一个状态对应一个内部位。
AND 安全OK"--> S2["状态 S2 (进料)"] S2 -- "液位高限" --> S3["状态 S3 (加热)"] S3 -- "温度达标" --> S4["状态 S4 (排料)"] S4 -- "排空完成" --> S1 S4 -- "急停触发" --> S0["故障状态"]
2. 梯形图逻辑描述
编写 逻辑时遵循“一步激活下一步,下一步复位前一步”的链条规则。
- 检测 启动信号:
如果State_0(待机) 接通,且Start按下,则 置位State_10(进料),同时 复位State_0。 - 执行 进料动作:
State_10接通时,驱动进料阀。 - 等待 进料完成:
如果State_10接通,且Level_High到位,则 置位State_20(加热),同时 复位State_10。
3. 致命陷阱:竞争冒险
当使用S/R指令时,如果在同一个扫描周期内,State_10 被复位,而 State_20 的条件也同时满足(例如由于传感器抖动),可能会导致状态“滑步”(瞬间跳过某一步)。
解决 方案:在状态转移逻辑中,串联 前一步的状态常开触点作为“使能信号”。或者,优先采用 整数状态法,因为整数在同一时刻只能有一个值,从根本上杜绝了双状态并存。
四、 进阶应用:带分支与并行处理的状态机
实际生产线往往不是简单的单线条流程,常包含“分支选择”和“并行动作”。
1. 分支选择逻辑
例如:包装机根据产品颜色(黑/白)选择不同的包装盒。
设计 一个判断状态(State 50)。
50: // 颜色判断分支
IF Color_Sensor = 1 THEN
Current_State := 60; // 黑色包装路径
ELSIF Color_Sensor = 2 THEN
Current_State := 70; // 白色包装路径
END_IF;
此处逻辑简单明了,但必须确保互斥性,即 Color_Sensor 不能同时为 1 和 2。
2. 并行处理逻辑
例如:灌装的同时进行瓶盖预热。两条支路需要同时开始,最后汇合。
引入 “汇合计数器”或“汇合标志位”机制。
实现 步骤:
- 定义 两个子状态机:
State_A和State_B。 - 在主程序中,当主状态跳转至“并行工作”步骤时,同时置位 两个子状态机的启动位。
- 监控 两个子状态机的完成标志(如
Bit_A_Done和Bit_B_Done)。 - 当两者均为
TRUE时,主状态机 跳转 至下一步,并 复位 两个完成标志。
五、 必须规避的五大编程错误
在状态机设计中,错误的模式会导致设备停机甚至安全事故。
1. 缺失“待机复位”逻辑
很多新手直接从 Step 1 开始。当设备断电重启或急停复位后,Step 变量可能保持断电前的数值(如有掉电保持),导致设备一上电就突然动作。
必须 在程序的第一个扫描周期(如西门子的 First_Scan 位)或急停复位逻辑中,强制写入 Current_State := 0。
2. 状态内部的“长耗时任务”
如果一个状态内部包含复杂的循环计算或通信请求,可能会拉长PLC的扫描周期,导致看门狗超时。
处理 方法:将长任务拆分为多个子步骤,或者利用PLC的“任务中断”机制,不要在单个状态循环中阻塞主程序。
3. 输出线圈重复使用
在 Step 10 驱动了 Motor_1,在 Step 20 又写了 Motor_1 的逻辑。如果逻辑处理不当,Motor_1 的状态会变得不可预测。
整改 方案:建立输出映射表。在状态机中只置位 Flag_Motor_1_Run,在主程序末尾统一 执行 Motor_1 := Flag_Motor_1_Run。
4. 忽略急停与故障处理
状态机正在执行 Step 30,此时按下急停。如果不处理,状态机会卡在 Step 30,急停解除后设备可能瞬间继续动作。
植入 全局故障处理逻辑:
编写 一段独立的逻辑块,优先级高于状态机。当 Emergency_Stop 触发时:
- 强制跳转 状态至
Step 0(或专用故障状态Step 999)。 - 切断 所有输出映射位。
- 锁存 当前故障前的状态值(可选,用于恢复工艺),但禁止自动恢复运行。
5. 定时器的错误调用
在某些状态下需要延时(如加热30秒)。如果在状态内部直接调用定时器指令,当状态跳转离开后,定时器可能未被正确复位。
正确 做法:
在进入定时状态(如 Step 20)时,利用上升沿 触发 定时器启动位。
在离开 Step 20 时,显式 复位 定时器。
或者,使用“自复位定时器”结构,确保状态离开后定时器线圈断电重置。
六、 调试与维护技巧
一个成熟的状态机不仅要能运行,还要方便现场电工调试。
1. 状态可视化
务必 在HMI(触摸屏)上做一个“当前步骤号”的显示元件,链接到 Current_State 变量。同时,制作 一个对照表文本显示,当 Current_State = 10 时,显示文本“正在进料”。这能让操作员瞬间判断设备卡在哪一步。
2. 单步调试模式
开发 一个“单步运行”开关。
当 Single_Step_Mode = TRUE 时,在状态转移逻辑中 串联 一个“继续按钮”条件。
例如:
IF (Level_High OR Single_Step_Mode) AND Button_Next THEN ...
这样,调试人员可以手动控制每一步的跳转,防止机械碰撞。
3. 状态保留与追溯
对于复杂的故障排查,使用 FIFO(先进先出)数组记录最近10次状态变化的时间戳和状态号。当设备报警停机时,通过查看历史轨迹,可以轻松发现是哪一步导致了逻辑死锁。
通过以上结构化的设计模式,PLC程序将从杂乱无章的继电器堆叠,转变为清晰严谨的工业控制算法。无论是简单的单机设备,还是复杂的流水线系统,状态机都是实现高可靠性控制的不二之选。

暂无评论,快来抢沙发吧!