S7-1200电机编号启动控制:从梯形图到SCL的完整实现
2026/9/19 6:50:25 网站建设 项目流程

1. 项目概述与需求拆解

1.1 从现场需求说起:为什么需要“编号启动”

先聊一个很常见的现场场景。车间里一排电机,比如水泵、风机、传送带驱动,操作工要通过触摸屏或者柜门按钮启停它们。如果只有几台,一对一启停按钮完全够用,梯形图加起来也快。可一旦电机数量多起来,比如十几个甚至几十个,柜门上密密麻麻全是按钮,你都不知道哪个按钮管哪台电机,调试时挨个核对线号,能把人逼疯。

这时候就自然想到一种更集中的控制方式——操作员不用直接按下某个物理按钮,而是在触摸屏或者上位机里输入一个数字编号,比如“输入5,然后按启动”,设备就知道要启动第5号电机。这就是“编号启动”控制模式。它的本质不是让PLC学会“数数”,而是把“电机编号”这个抽象输入,翻译成PLC内部实实在在的位(M点、Q点、DB位),再通过对应的输出回路驱动接触器或变频器,最终让目标电机得电运转。

我之前做过一个S7-1200的项目,客户就是这么要求的:车间有十几台小型水泵,不要求联动,不要求顺序,就是要求“编号启动”和“编号停止”——触摸屏上输一个编号,点启动,对应水泵转起来;点停止,对应水泵停下来。用S7-1200做这个逻辑非常合适,CPU的运算能力绰绰有余,而且TIA Portal里写逻辑也清晰。这篇文章就把这个项目的设计思路、梯形图实现、常见坑点完整拆开聊一遍,给正在做类似需求的朋友一个参考。

1.2 用S7-1200做这个控制的核心优势

选择S7-1200而不是直接用S7-200 SMART或者三菱FX,有几个实际考量。首先是S7-1200的存储区和数据块管理比老一代PLC更灵活,LED指示灯、工艺对象、诊断缓冲区这些功能在调试多电机系统时特别好用——哪台电机没启动起来,CPU的诊断缓冲区会直接告诉你I/O访问错误的通道号,省去拿万用表一段段量线的痛苦。

另一个优势是TIA Portal的编程环境。S7-1200支持梯形图(LAD)、函数块图(FBD)、结构化控制语言(SCL)和语句表(STL)混合编程。处理“编号启动”这类逻辑,要么用一堆比较指令把编号拆开,要么直接用SCL写一个CASE语句,可读性完全不一样。我一般习惯在OB1里用梯形图做框架,在FC或者FB里用SCL做编号解析逻辑,两者结合在移植、维护、查错方面都更高效。

还有就是通讯扩展能力。一台S7-1200通过Modbus RTU或者Modbus TCP可以带几十台变频器,和“编号启动”的需求天然互补——你不但可以“启动编号对应的电机”,还可以通过变频器通讯修改编号对应的频率、读取电流,做到完整的单机集中监控。这个场景后续我会专门展开。

1.3 项目边界:做什么,不做什么

这个项目不涉及变频器通讯、不涉及PID调节、不涉及多段速控制,就是纯粹的“数字量输出启停电机”逻辑。控制对象是带接触器控制的异步电机,每个电机一个中间继电器,PLC输出点接中间继电器线圈,中间继电器触点控制接触器,接触器主触点控制电机。变频器控制的方式原理相同,只要把启动输出接到变频器的数字量输入端子即可。

安全保护方面,每台电机要有热继电器或者电机保护断路器的辅助触点,反馈到PLC的输入点,用于过载报警和禁止启动。这个必须做,不是可选项——一旦电机过载,热继电器动作,反馈点断开,PLC必须能及时断开输出,避免烧电机。咱们做的是设备控制,安全底线不能丢。

2. 控制方案设计:从编号到电机启动的完整映射

2.1 三种可行的实现思路对比

实现“编号启动”,根据硬件配置和编程风格的不同,常见有三种方案:

方案A:离散输出映射。每个电机对应一个Q点,用一个“编号译码”逻辑,把输入的数值和每个Q点对应的编号比较,相等则置位输出。这个方案最直观,适合控制点数在几十个以内的场景。对于点数特别多的场景,会用I/O子模块扩展或远程I/O,但逻辑本质不变。

方案B:移位寄存器实现。类似流水灯思路,通过一个首地址,把启动脉冲移到对应编号的位。这个方案在老的S7-300里有人用,但在S7-1200里逻辑反而绕,而且查错不直观。我不会推荐。

方案C:SCL+CASE指令。直接从数学映射角度解决,输入编号,通过CASE或者IF语句判断编号落在哪个区间,然后置位对应的输出。这个方案代码量最小、最清晰,特别适合数量多、且编号规划有规律(比如1-8对应第一个输出模块,9-16对应第二个输出模块)的场合。

实际项目中,我最常用的是方案A的“优化版”:用SCL写一个FC,传入需要启动的电机编号,函数内部用一个FOR循环或者CASE逐一比对,返回对应的输出地址索引;然后用POKE或者直接访问IO映射的DB块来写输出。

不过话说回来,如果只是做简单的十几路电机启停,也不一定非得上SCL。梯形图里用比较指令完全能做,一段一段写下来,虽然啰嗦一些,但胜在电工师傅看着也容易理解,后续维护门槛低。这个取舍要看你项目交付后是谁在维护。工业现场,可维护性很多时候比炫技更重要。

2.2 编号映射的三种方式:物理映射、逻辑映射、动态映射

设计“编号启动”前,第一个问题是:电机编号和PLC输出点之间的对应关系怎么建立?

物理映射:编号和PLC输出通道完全一一对应。比如1号电机对应Q0.0,2号电机对应Q0.1。这种最简单,适合电机布局固定、后期不改动的项目。缺点是如果某台电机检修拆走,编号就空了一个坑,其他编号不连续。

逻辑映射:PLC内部建立一个DB块,DB里有数组,数组的下标是电机编号,数组的值是该电机对应的输出点地址。也就是说“1号电机对应哪个输出点”不是固定写死的,而是通过组态数据配置的。这种方式的优势是灵活,电机编号可以自由分配,比如现场因为配电柜调整,原来3号电机的输出点挪到了第24路,只需要改DB里的数据,不需要改逻辑代码。这是我最推荐的做法,而且S7-1200用DB块数组来干这个事非常顺手。

动态映射:通过触摸屏或者上位机在线修改映射关系。这种方式灵活过头了,一般用于工艺经常调整的场景。对于多数固定设备,逻辑映射已经足够。动态映射还有个风险——操作员改错数据导致电机误动作,安全上不好把控,除非有权限管理,否则我不会轻易做。

从我实际经验看,逻辑映射是性价比最高的方案,既要了灵活性,又不会把程序搞得太复杂。下面的实现就以逻辑映射为基线来展开。

2.3 启动与停止逻辑的状态机设计

“编号启动”不能只做一个瞬间的输出动作。完整的电机控制逻辑必须包含状态机:

停止状态:输出为0,电机不转。 启动过程:收到启动指令,对应输出置1,电机开始运转。 运行状态:输出保持1。 停止过程:收到停止指令,对应输出置0,电机降速停止。 故障状态:热继电器动作或反馈丢失,输出强制断开,并且需要手动复位才能重新启动。

在PLC程序里,我通常用一个二维数组或者结构体数组来保存每台电机的状态,比如DB结构:

  • StartCmd(BOOL):启动命令
  • StopCmd(BOOL):停止命令
  • RunFb(BOOL):运行反馈
  • Fault(BOOL):故障信号
  • Output(BOOL):实际输出
  • Mode(INT):手动/自动模式

然后用一个循环或者逐台扫描的逻辑,对每台电机执行“状态机处理”。其实这就是一个简化版的“功能块实例化”——如果你用的TIA Portal V13以上版本,完全可以直接写一个FB叫MotorControl,然后创建多个背景数据块,每个电机一个实例。这样代码写一遍,重复调用就行。热搜词里提到的“多重实例”,就是这个东西,后面第三部分我会讲具体怎么组。

3. 硬件组态与软件架构

3.1 S7-1200的模块化组成架构

S7-1200 CPU本身有集成数字量I/O,1214C DC/DC/DC这款,集成14个数字量输入和10个数字量输出。如果项目规模只有6台电机,一个CPU就够;如果电机数量多,通过添加SM 1222数字量输出模块扩展。

先说模块化架构。S7-1200的组成典型如下:

  • CPU模块(含电源、集成I/O、PROFINET口)
  • 信号板SB(放在CPU前盖板里,可扩展少量I/O或通讯口)
  • 信号模块SM(插在CPU左侧,扩展数字量/模拟量I/O)
  • 通讯模块CM(插在CPU左侧,扩展RS232/RS485/Profibus等通讯)
  • 通讯处理器CP(插在CPU左侧,扩展PROFINET/PROFIBUS DP等)

CPU左侧最多可以插8个信号/通讯模块,右侧是CPU本体的I/O。组态时在TIA Portal的硬件配置里拖拽即可,注意模块版本和固件版本要一致,否则编译会报错。

对于“编号启动”这个项目,IO组态的核心是数字量输出。我会按“每块SM 1222输出16点”来规划,每台电机占用一个输出点,然后预留至少10%的备用点,方便后期增加设备。CPU本身能带多少输出?具体依据不同型号而定,但128点以内的数字量输出,1214C加模块完全够用,价格也合理。

3.2 TIA Portal项目结构规划

在TIA Portal里,我一般建议把程序分成以下几个区域:

  • OB1:主程序循环,调用主控制FB。
  • FB_MotorControl:单台电机控制功能块,包含启动/停止/故障/反馈处理。
  • FB_MotorGroupManage:电机组管理功能块,处理编号解析,查询电机配置,循环调用FB_MotorControl。
  • DB_MotorConfig:电机配置数据块,数组方式存储每台电机的“编号-输出点映射”、参数、当前状态。
  • FC_NumberDecode:编号解码函数,输入操作员给的编号,输出对应的电机索引。
  • HMI变量表和PLC变量表:统一规划变量命名,方便触摸屏绑定。

这种结构的好处是:新增一台电机时,不用改逻辑,只要在DB_MotorConfig里增加一条配置,然后硬件组态里增加一个输出点就行。程序维护成本极低。这也是我坚持用“配置驱动逻辑”的主要原因。

3.3 多重背景数据块的设计思路

热搜词里提到了西门子PLC的多重实例,这个和本项目有关系。

所谓多重背景(Multi-instance),是指在一个FB里调用另一个FB,被调用的FB的数据存储在主FB的静态变量区,而不是生成独立的背景DB。举个实际例子:我写了一个FB_MotorControl,它内部需要用到定时器、沿检测等,如果每台电机生成一个背景DB,10台就有10个DB,看起来很多;但如果我在上层FB_MotorGroupManage里以多重实例方式调用FB_MotorControl,那么所有电机的实例数据都集中在这个管理FB的背景DB里,数据结构变成一个数组,每个数组元素对应一台电机的完整状态。

这样做的好处是:

  1. 数据集中,查看状态方便。
  2. 可以方便地用循环或变量索引来处理多台电机。
  3. 背景DB结构清晰,触摸屏或上位机可以按数组索引统一读数据。
  4. 减少DB数量,项目树干净不少。

实现上其实就是声明一个“MotorControl实例”作为FB的静态变量类型:

VAR MotorInst : Array[1..16] of FB_MotorControl; // 多重实例数组 END_VAR

然后在代码里用FOR循环或者按索引调用:

FOR i := 1 TO MotorCount DO MotorInst[i](RunCmd:=..., StopCmd:=..., Fault:=...); END_FOR;

这个方法在TIA Portal V14及以上版本完全支持,属于正规用法。

3.4 变量表命名规范

这个项目看着逻辑简单,但如果变量命名一塌糊涂,调试时一样抓瞎。我给一个基本的命名规范,大家可以在自己项目里直接套用:

  • 电机启动命令:Mot_Start_Cmd[编号],例如Mot_Start_Cmd1
  • 电机停止命令:Mot_Stop_Cmd[编号]
  • 电机运行反馈:Mot_Run_Fb[编号]
  • 电机故障信号:Mot_Fault[编号]
  • 电机输出地址:Mot_Out_Q[编号]
  • 手自动模式:Sys_Auto_Mode

如果用的是DB块数组方式,那么变量名还是一样的,只是访问时带有数组下标,比如:

"MotorDB".Motor[3].StartCmd "MotorDB".Motor[3].Output

触摸屏上做输入域时,HMI变量一般绑定到DB的具体元素,这样操作员输入编号后,HMI直接调用PLC内部的解析逻辑。

4. 核心逻辑实现:编号解码与启停控制

4.1 输入编号的校验与合法性判断

操作员在触摸屏上输入一个编号,这个编号未必是合法的。比如一共8台电机,编号应该只能填1到8,结果操作员填了9或者填了0,或者填了负数、非数字,这些情况都必须处理,如果不校验直接去访问数组下标,轻则启动错误的电机,重则导致PLC访问越界、程序卡死、CPU进入STOP状态。

我在项目中做的校验逻辑主要分三层:

第一层:HMI端的输入限制。触摸屏上把输入域的类型设置为整数,范围限定到1到最大编号之间。这能拦截大部分误输入。

第二层:PLC内的数值范围检查。SCL里写:

IF #input_number >= 1 AND #input_number <= #max_number THEN // 合法编号,执行启动 ELSE // 非法编号,返回错误代码 END_IF;

第三层:映射表有效性检查。即使编号在范围内,如果该编号对应的输出点被禁用(比如维护模式),也不能启动。DB配置里我加了一个Enable位,只有Enable为TRUE的编号才允许动作。

这三层下来,基本能杜绝“幽灵启动”。千万不要嫌校验麻烦就直接把输入编号当数组下标用,这是大忌。

4.2 梯形图实现:比较指令陷阱与排除

如果不用SCL,用梯形图直接做编号解析,最常见的做法是:

|--[ #input_number == 1 ]----( Mot_Out_Q0.0 )--| |--[ #input_number == 2 ]----( Mot_Out_Q0.1 )--| ...

看起来简单,但有一个很隐蔽的坑:如果启动命令是“沿信号”,也就是只在按下启动按钮的那一拍产生一个脉冲,那么比较结果和输出线圈之间一定要用置位/复位指令。否则你可以想象这个场景:操作员输入编号“5”后按下启动,输入编号的保持寄存器一直是5,输出点就一直得电。如果操作员随后把编号改成“3”,按下了停止按钮,可是因为编号不再是5,5号电机的输出已经自动断了。这变成了“编号决定启停”,而不是“命令决定启停”,置信度完全不对。

正确的逻辑是:

  • 启动按钮的上升沿,加上当前编号的有效性判断,置位对应电机的输出位。
  • 停止按钮的上升沿,复位对应电机的输出位。
  • 故障信号动作时,也复位对应输出。

也就是说,编号输入只负责“告诉PLC操作员想操作哪台电机”,真正的触发还是来自启动命令的沿信号。这个思路在梯形图里一定不能拧过来。

4.3 SCL实现:CASE指令的优雅写法

如果是SCL,代码简洁很多。以一个FC或者FB内部片段为例:

// 输入参数 // #op_code : INT (1=启动, 0=停止) // #motor_no : INT (电机编号) CASE #op_code OF 1: // 启动命令 IF #motor_no >= 1 AND #motor_no <= #max_no THEN "MotorDB".Motor[#motor_no].StartCmd := TRUE; END_IF; 0: // 停止命令 IF #motor_no >= 1 AND #motor_no <= #max_no THEN "MotorDB".Motor[#motor_no].StopCmd := TRUE; END_IF; END_CASE;

然后在下层的FB_MotorControl里处理StartCmd和StopCmd的沿信号:

// 上升沿检测 #start_edge(CLK := #StartCmd, Q => #start_rise); #stop_edge(CLK := #StopCmd, Q => #stop_rise); IF #start_rise AND NOT #Fault THEN #Output := TRUE; END_IF; IF #stop_rise OR #Fault THEN #Output := FALSE; END_IF;

这样逻辑就完整了:操作员的编号输入只是传参,启动/停止动作由命令沿触发,故障信号具有最高优先权。

这里有个额外的细节:用置位/复位而不是直接赋值,好处是故障复位后,输出不会自动恢复,需要操作员重新按下启动。这在工业现场是必须的——如果故障消失了电机自己又转起来,很容易出安全事故。

4.4 故障处理与手动复位机制

每台电机都必须有热继电器或马达保护断路器的辅助触点反馈。通常接法:

  • 热继电器辅助触点常闭点串入接触器控制回路(硬线互锁,防止PLC异常时电机仍然运行)。
  • 同时辅助触点信号接入PLC输入点,用于程序联锁。

PLC程序里:

IF NOT #FbFault THEN // 正常状态 ELSE #Fault := TRUE; #Output := FALSE; END_IF; // 复位按钮 #reset_edge(CLK := #ResetCmd, Q => #reset_rise); IF #reset_rise AND NOT #FbFault THEN #Fault := FALSE; END_IF;

注意复位条件是“故障点已恢复且手动按下复位按钮”。如果故障没有消除,复位按钮是无效的。这种设计是安全惯例,不要省略。

另外,故障信息要在触摸屏上显示是哪台电机什么故障,这样操作员不用查柜子。S7-1200自带的报警指令块用起来也方便,把每台电机的故障信号用Program alarm触发,HMI上就能弹出报警记录。

4.5 顺起逆停与时间间隔联锁

热搜词里提到了“西门子s7-1200顺起逆停”,就是有几台设备要求启动时按顺序1、2、3依次启动,停止时按3、2、1依次停止,防止管道压力突变或者其他工艺问题。这个需求在电机编号启动的基础上很容易扩展。

做法是在上层组管理FB里加入顺序逻辑:

// 启动顺序 IF #auto_start_all THEN FOR i := 1 TO #max_no DO IF #allow_start[i] THEN "MotorDB".Motor[i].StartCmd := TRUE; EXIT; // 一次只启动一台,启动完这台后结束本轮 END_IF; END_FOR; END_IF;

实际项目中还会加“延时继电器”来保证两台电机启动的间隔,比如每台电机启动间隔5秒,防止多台大功率电机同时启动导致变压器过载。S7-1200用TON定时器非常方便:

#ton_interval(IN:=#start_all_active, PT:=#interval_time); IF #ton_interval.Q THEN // 触发下一台 END_IF;

这个话题展开又够一篇长文了,这里点到为止。你只要知道“编号启动”不是孤立的,它可以和顺序启动、联锁逻辑、变频器控制无缝整合。

5. 实操过程:从组态到调试的关键环节

5.1 TIA Portal项目创建与硬件组态步骤

下面是我实际做项目的操作流程,一步步来。

第一步,创建TIA Portal项目。打开TIA Portal V16或V17(我用的V16,新版本操作类似),在“创建新项目”中输入项目名,比如“MotorNumberControl”。

第二步,添加设备。左侧项目树里双击“添加新设备”,选择“控制器→SIMATIC S7-1200→CPU”,选型注意实际订货号和固件版本。以1214C DC/DC/DC为例,订货号是6ES7 214-1AG40-0XB0。如果固件不一致,后续下载时可能报错,要么升级固件,要么在组态里选择兼容版本。

第三步,组态数字量输出模块。如果需要SM 1222,从硬件目录里拖拽到CPU左侧的插槽。SM 1222有16点继电器输出(6ES7 222-1HH32)和16点晶体管输出版本,继电器输出的负载能力强一些。电机控制用继电器输出足够了,但注意继电器输出有机械寿命,频繁启停虽然不至于很快坏,但定期检查是必要的。

第四步,设置PROFINET/以太网参数。双击CPU,在“PROFINET接口”里设置IP地址,比如192.168.0.10,子网掩码255.255.255.0。如果现场有多台PLC,IP地址规划要提前做好,别都配成一样的。建议IP地址和电机编号或者柜号有一定关联,方便记忆。

第五步,PLC变量表的规划。在PLC变量表里建立数字量输入、数字量输出的符号名。我习惯直接用符号编程而不是绝对地址,这样程序可读性强很多。比如:

  • %I0.0 -> "Mot1_Fault"
  • %I0.1 -> "Mot2_Fault"
  • %Q0.0 -> "Mot1_Out"
  • %Q0.1 -> "Mot2_Out"

第六步,编写程序。先建FB_MotorControl,然后建DB_MotorConfig,最后建FB_MotorGroupManage,OB1里调用。

5.2 FB_MotorControl功能块的接口设计与代码示例

以单台电机控制为例,做一个可复用的FB本体:

FUNCTION_BLOCK FB_MotorControl VAR_INPUT StartCmd : BOOL; // 启动命令 StopCmd : BOOL; // 停止命令 RunFb : BOOL; // 运行反馈(接触器辅助触点) FaultIn : BOOL; // 故障信号(热继电器常闭点) ResetCmd : BOOL; // 复位命令 END_VAR VAR_OUTPUT OutQ : BOOL; // 输出到接触器/变频器 IsRunning: BOOL; // 是否在运行 Fault : BOOL; // 故障指示 END_VAR VAR start_edge : R_TRIG; stop_edge : R_TRIG; reset_edge : R_TRIG; END_VAR

代码逻辑:

#start_edge(CLK := #StartCmd); #stop_edge(CLK := #StopCmd); #reset_edge(CLK := #ResetCmd); IF #start_edge.Q AND NOT #Fault THEN #OutQ := TRUE; END_IF; IF #stop_edge.Q OR #FaultIn OR #Fault THEN #OutQ := FALSE; END_IF; // 故障锁存 IF #FaultIn AND NOT #reset_edge.Q THEN #Fault := TRUE; ELSIF #reset_edge.Q AND NOT #FaultIn THEN #Fault := FALSE; END_IF; #IsRunning := #OutQ AND #RunFb;

注释:OutQ置位后,如果运行反馈(RunFb)迟迟没有到位,说明接触器可能没吸合或者电机回路有问题,这时IsRunning一直为FALSE,可以在上位机做“启动失败报警”。这个反馈对于判断现场故障很有价值,建议有条件都接上。

5.3 编号解析与组合调用:DB数组是核心

DB_MotorConfig的结构体设计,我建议这样:

TYPE MotorStruct STRUCT Number : INT; // 电机编号 Enable : BOOL; // 是否启用 OutAddr : INT; // 输出点索引,比如1对应Q0.0 RunFbAddr : INT; // 反馈点索引 FaultAddr: INT; // 故障点索引 StartCmd : BOOL; // 命令 StopCmd : BOOL; Mode : INT; // 0=手动,1=自动 END_STRUCT END_TYPE

然后DB里定义:

MotorArray : ARRAY[1..16] OF MotorStruct

这里“OutAddr”并不直接是I/O地址,而是一个索引。实际输出访问时,可以用S7-1200的PEEK/POKE指令,或者更简单地:把数字量输出通道映射到一个EW/AB字节,然后通过索引操作。比如8台电机用一个字节的8个位,那么:

"OutputByte_1".%X0 := "MotorDB".MotorArray[1].OutQ;

其实最简便的方法是不用间接寻址,直接在程序里指定:

"Mot1_Out" := "MotorDB".MotorArray[1].OutQ; "Mot2_Out" := "MotorDB".MotorArray[2].OutQ;

如果电机数量不多(比如不超过32台),这种显式映射完全没问题,代码量也还好。如果数量很大,那再上间接寻址。

我经常会遇到有人问:为什么不直接用“数组下标=编号”来做映射?因为实际项目里,编号和物理通道往往不是连续对应的。比如厂区改造,1号电机挪到新的配电柜,输出点变到了第9路。如果用数组下标直接映射,那就得把数组重新排序,严重影响后续维护。而加了OutAddr这一层映射之后,只需要改数据库里的一个数字,逻辑完全不用动。这就是之前说的“逻辑映射”的价值所在。

5.4 触摸屏编号输入与操作画面设计

如果项目带HMI(比如西门子KTP700或MTP1000),操作画面可以做得非常简单直观:

画面上有一个“电机编号”输入域,一个“启动”按钮,一个“停止”按钮,一个“复位”按钮,一个故障报警指示灯区。操作员输入编号后,按下启动,PLC收到命令并执行对应电机的启动。

需要注意:输入域的数据类型要和PLC变量一致。比如PLC里编号变量是INT,HMI里也要选“INT”类型,否则通讯时数据类型不匹配,显示乱码或者无法输入。

另外,我习惯在HMI上显示当前编号对应的电机状态。比如操作员输入了5,画面上立即显示“5号电机:运行中/停止/故障”,这样操作员不用傻傻按下按钮才知道结果。这个可以通过HMI的多状态显示域绑定DB里MotorArray[5].IsRunning来实现。

还有一点:HMI按钮的“按下/释放”事件,在标准做法里是把“按下”作为启动信号的置位,“释放”作为复位。但我们的逻辑是沿触发,所以更推荐的做法是:HMI按钮“按下”时置位一个布尔变量,PLC检测该布尔变量的上升沿后执行启动,然后复位该布尔变量。如果用HMI自带的“置位”按钮功能,按一下变量为TRUE,再按一下为FALSE,这也能用,但容易造成误操作——操作员以为按了启动,实际是取消命令。所以我在项目里会做一个“沿触发”转换,而不是直接拿按钮状态来控制电机。

5.5 离线仿真与在线调试

TIA Portal带了S7-PLCSIM仿真器,调试阶段强烈建议先用仿真跑一遍逻辑,再去现场联调。

仿真时注意几件事:

  1. S7-PLCSIM仿真的是PLC的逻辑,不仿真真实I/O接线。所以数字量输入需要手动强制,输出状态要监视。
  2. 仿真模式下,可以用“仿真表”强制变量,模拟热继电器故障、运行反馈丢失等场景,验证故障锁存和复位逻辑。
  3. 如果用了S7-1200的PROFINET或者Modbus通讯功能,S7-PLCSIM不一定能完全模拟(特别是第三方设备通讯),这部分要现场联调。

在线联调时,我用得最多的工具是TIA Portal里的“监控表”(Watch table)。把关键变量拖进去:电机输出位、启动/停止命令、故障标志、反馈信号,强制或者修改数值,观察逻辑是否符合预期。

还有一个非常实用的小技巧:在TIA Portal里右键变量,选择“修改为1”或“修改为0”,可以快速模拟输入信号。比如我要模拟1号电机热继电器故障,直接修改Mot1_Fault为TRUE,观察OutQ是否变为FALSE、Fault是否锁存。整个调试效率高很多。

6. 常见问题与排查技巧实录

6.1 电机编号输入后无响应

这个是最容易遇到的问题。通常排查顺序如下:

第一,确认操作员输入的编号在合法范围内。很多情况就是输了个超范围的编号,HMI上又没提示,感觉“按键没反应”。

第二,检查PLC变量是否成功接收HMI的数据。联机后在监控表里看输入域绑定的变量的值,如果一直为0,要么是HMI变量绑定错误,要么是通讯中断。

第三,检查启动命令的沿检测是否触发。在监控表里看FB里的start_rise变量,如果一直FALSE,说明命令信号没有产生上升沿。可能原因:HMI按钮的“释放”事件把命令变量复位了,导致PLC根本没捕捉到“0→1”的变化。这是HMI编程时最容易犯的毛病——按下置位,释放又复位,命令信号持续时间太短,PLC扫描周期没赶上。

解决方法:要么PLC的扫描周期足够快(S7-1200默认扫描周期通常几毫秒,基本能捕捉到HMI的置位信号),要么HMI按钮改成“置位后保持,由PLC复位”,保证信号宽度足够。

还有一个情况:如果通讯周期正好和扫描周期撞上,偶发丢信号。稳妥的办法是用HMI的“事件-按下时取反”,或者干脆在HMI里做“多重按下确认”,防止误触。不过对于电机启停这种操作,我一般不建议做复杂确认,操作员在触摸屏上按错是正常的,关键是启动后能立刻看到状态反馈,可以马上停止。

6.2 DB块地址偏移导致HMI访问错误

S7-1200的DB块默认有“优化的块访问”属性。这个属性打开后,DB变量没有固定的偏移地址,HMI访问时通过符号名访问,问题不大。但如果程序里用了间接寻址,或者老的HMI项目不支持符号访问,就要小心。

有一种常见报错:HMI连接PLC变量时提示“变量不存在”或“地址区不合法”。多半原因:

  • DB块的“优化块访问”勾选状态和HMI期望的不一致。
  • 变量类型不匹配。HMI里声明的是WORD,PLC里是INT,符号名一样也会报错。
  • 背景DB被多重调用覆盖,导致HMI读取的DB不是目标实例。

我的建议:对于HMI需要直接访问的DB,可以在属性里去掉“优化的块访问”勾选,这样地址变成确定的,比如DB1.DBX0.0,HMI直接按地址访问也没问题。但注意,改了这个选项之后,如果DB结构变化,偏移地址会乱,需要重新生成。

6.3 多台电机启动时电流冲击过大

如果现场是多台大功率电机同时启动,变压器或发电机可能支撑不住,电压骤降甚至跳闸。即使用编号启动,操作员也有可能快速连续输入多个编号启动多台电机。我见过一个案例,操作员在触摸屏上点了4台15kW水泵的启动,间隔不到1秒,结果车间照明明显闪烁了一下,变压器嗡嗡叫,吓得业主赶紧喊停。

解决思路是在PLC里加“最大同时运行电机数”限制。比如设定最多同时运行3台,当第4台启动请求来时,程序直接拒绝并提示“运行数量已满”。这个限制在自动工艺控制里很常用,在手动编号启动场景下同样适用。

还有一种做法是“启动队列”或“启动延时”。把启动请求排队,每5秒释放一台。这其实就是前面提到的顺起逆停的变种,按启动先来后到排序,排队执行。S7-1200做这个逻辑不难,数据块的数组加几个标志位就行。

6.4 触摸屏通讯突然中断

S7-1200自带PROFINET口,和触摸屏组网时最常用的是PROFINET或者普通工业以太网。如果触摸屏和PLC之间的通讯时断时续,常见原因:

  • IP地址冲突。检查现场是否有别的设备占了同一个IP。
  • 网线或者交换机端口故障。S7-1200的网口不是隔离型的,现场干扰大或者接地不好,可能导致通讯异常。
  • HMI项目里PLC连接的“访问点”选错,或者“机架号/插槽号”配置不对。如果组态的是S7-1200,一般不需要填这些参数,但个别HMI型号有默认值,比如机架0插槽0,有时候实际是插槽1。

我处理过一例,也是奇怪得很,触摸屏偶尔弹通讯错误,但过一两秒自己恢复。后来查了半天,发现是交换机的一个端口老化,偶尔丢包。换了个端口就好了。这种隐性故障,现场排查起来确实费时。所以做项目时,网络关键链路尽量用工业级交换机,有些地方省不得。

6.5 TIA Project里FB调用时DB块无法分配

热搜词里有一条“博途调用FB时填不了DB块”,很典型。新手常遇到的情况:在OB1里调用一个FB,系统要求分配背景DB,但下拉列表是空的,没法新建背景。

常见原因:

  1. FB的接口声明没有完成,比如某个VAR_INPUT缺少数据类型。
  2. FB属性里勾选了“在多重实例中调用”,这时候不允许生成自己的背景DB,只能在另一个FB里以多重实例方式调用。
  3. 项目处于离线状态,且对应FB没有编译。先把该FB单独编译一遍,再回OB1调用。

解决办法就按上面三点检查即可。如果是多重实例模式,你不需要也不能生成独立背景DB,就这么设计的。

6.6 常见问题速查表

问题现象可能原因排查与解决
编号启动无反应编号超范围 / HMI绑定错误 / 命令沿丢失检查输入范围、监控表看变量值、修改HMI按钮事件逻辑
电机启动后不停停止命令没有沿信号 / 输出被外部回路保持(接触器自锁)检查PLC停止逻辑,检查接触器控制回路是否有自锁(硬线互锁)。
故障复位不了故障信号未消除 / 复位逻辑条件不满足检查故障输入点实际状态,确认热继电器已复位
多台同时启动缺乏数量限制PLC内增加同时运行数量统计和限制
HMI通讯中断IP冲突 / 网络故障 / 组态参数错误检查IP、交换机端口、连接参数
FB无DB可分配多重实例模式 / 未编译确认FB属性、编译后再调用,或改为非多重实例
输出点爆掉输出过载 / 感性负载无吸收回路PLC输出加中间继电器,继电器线圈两端并联续流二极管或RC吸收,接触器线圈两端也加浪涌抑制

7. 向更复杂场景扩展:变频器通讯与多轴控制

7.1 编号启动加上变频器:从启停到调速

前面的逻辑只处理了接触器控制,如果电机要调速,就得换成变频器了。热搜词里“abb变频器与西门子plc”、“西门子plc与施耐德eta系列变频器modbus通讯”这类词,说明大家实际项目中经常要把PLC和变频器联动。

把编号启动和变频器控制结合起来,逻辑会稍复杂一些。除了启停数字量信号外,还要考虑频率给定方式。最省接线的方式是走通讯:PLC通过Modbus RTU或者Modbus TCP读写变频器的运行命令、频率设定、电流反馈。

S7-1200做Modbus通讯很方便,用MB_COMM_LOAD和MB_MASTER指令(或者Modbus TCP的MB_CLIENT)。不过要注意,S7-1200的Modbus RTU需要额外的通讯模块,比如CM1241 RS485或者CB1241,CPU本体没有串口。

有人问:一台PLC控制32台变频器Modbus通讯可行吗?硬件上是可以的,RS485理论上最多挂32个节点(加中继可以更多),Modbus TCP理论上更多。但关键是通讯轮询周期。每台变频器读一组数据写一组指令,算下来32台,每台通讯时间按50ms算,一轮就1.6秒。如果你需要同时监视32台变频器的实时电流,这个刷新速度可能不够。所以实际项目中会做“分组轮询”:关键数据(比如运行状态、故障)高频刷新,非关键数据(比如累计电量)低频刷新,必要时划分优先级。

7.2 32台变频器轮询程序的基本框架

轮询框架大致如下:

  • 建立一个DB数组,每个元素存一台变频器的读写数据。
  • 用一个INT变量做轮询指针,每个扫描周期(或定时触发)轮到一个变频器,执行MB_MASTER/MB_CLIENT请求。
  • 通信完成后指针加1,到末尾回绕。
  • 每台变频器有独立的超时计数,超时则标记通讯故障,但不影响其他变频器的轮询。

这里有一个容易踩的坑:MB_MASTER或MB_CLIENT是异步指令,调用一次不一定立即完成,需要检查“完成位”和“错误位”。有些新手直接在一个扫描周期里连续调用32次MB_MASTER,以为能并行通讯,结果是串行排队,搞不好卡死。正确的做法是每次调用一个,完成后再调用下一个。

具体的轮询指令时序,网上资料很多,项目里照抄时要注意指令的“REQ”必须用沿信号触发,否则会持续发送请求,导致总线拥堵。

7.3 通过PROFINET与变频器通讯

如果现场变频器支持PROFINET(比如西门子G120、SINAMICS V90),那么控制方式又不一样了。通过GSD文件组态到TIA Portal里,PLC直接以I/O方式访问变频器的控制字、状态字、速度设定值,实时性和可靠性比Modbus高很多。

S7-1200通过PROFINET控制G120,常用的报文是“西门子111报文”,这是标准报文,包含控制字STW1、状态字ZSW1、速度设定值NSOLL_A等。使用时要严格按照报文格式映射数据,控制字里每个位的含义要弄明白,比如位0是“ON/OFF1”,位1是“OFF2”(自由停车),位3是“使能运行”,不能随便乱写。很多人第一次用111报文时,变频器就是转不起来,排查下来往往是对控制字的不熟悉。

#111报文的控制字结构简要如下:

含义
Bit0ON/OFF1
Bit1OFF2
Bit2OFF3
Bit3脉冲使能
Bit7故障确认
Bit10由PLC控制

启动时要同时置位Bit0、Bit1、Bit2、Bit3,并且按顺序来,不能一上来就全写1。停止时要有对应的斜坡停车时序。这些细节都是调试中容易卡壳的地方。

7.4 编码器反馈与视觉/仪表联动

再往大了说,电机编号启动只是底层设备控制,工厂里往往还要上游传感器、仪表联动。热搜词里有“视觉与PLC通讯”、“C#和西门子PLC通讯”,这些都是扩展方向。

如果视觉系统需要和PLC交换数据,最简单的方案是走PROFINET或者Socket通讯,把视觉检测结果(OK/NG)写入PLC,然后PLC根据结果决定是否允许下一次编号启动。比如某工位要求上一站视觉检测合格才允许启动对应电机,那就在电机启动允许条件里加上“视觉判定结果为OK”。

C#和S7-1200通讯一般用的是S7comm协议,网上有Sharp7、S7.Net Plus这些开源库。上位机可以读取PLC的状态,或者在界面上以更灵活的方式操作电机编号启动。不过上位机介入时要注意,PLC侧的控制逻辑必须留有“允许上位机控制”的权限位,否则两个操作端容易打架。

8. 项目总结与我的几点实操心得

结构到这儿,正文核心内容已经完整了。最后分享几个我在类似项目里攒下来的经验,不一定都写在文档里,但对实际交付很有用。

第一点,电机编号和PLC输出点的映射表,一定要在项目交付时同步给电气图。光有PLC程序,没有点表,后续维护电工根本玩不转。我每次都会生成一张“电机编号-柜内中间继电器-接触器-PLC输出点-热继电器反馈点”的对应表,交给业主存档。这个东西比程序还值钱。

第二点,沿信号处理。在S7-1200里,用R_TRIG、F_TRIG这类指令块是处理沿的最稳方式,直接比较当前值和上次值虽然也能实现,但代码冗余且容易出错。建议统一用沿检测指令块。

第三点,程序要写注释。TIA Portal支持在程序段里写注释,不要嫌麻烦。尤其SCL代码,一段复杂逻辑过了半年再回头看,没注释就是天书。这个习惯在项目多的时候尤其实用。

第四点,测试一定要全面。仿真通过只是第一步,现场联调要从单机测试到多机测试逐步来。先手动强制输出点,确认每个中间继电器动作正确;然后通过编号启动测试每台电机;最后才做联锁和故障模拟测试。特别是故障模拟,有价值但容易被忽略——拉掉热继电器测试反馈,确认PLC能锁存故障并停止输出。

就这些。S7-1200做电机编号启动,核心不是什么高深算法,而是清晰的逻辑结构、可靠的信号处理、严谨的故障联锁。把这个基本功打扎实了,后续扩展变频器通讯、PROFINET控制、上位机监控,都是水到渠成的事。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询