简介:本资源是一套面向零基础初学者的西门子S7-1200 PLC实战仿真教程,聚焦电气控制与工业自动化核心技能训练,特别适合高职院校学生、转行工程师及自学者系统掌握移位与循环指令的实际应用。教程基于TIA Portal博途V15.1开发,含完整可运行程序与HMI仿真工程,支持一键启动/停止、单灯流水与多灯跑马灯两种模式,严格按0.5秒步进、4秒周期循环点亮8个LED,真实还原硬件按键控制逻辑。压缩包共48个文件,约7MB,涵盖PLC程序(db、gdbak)、HMI界面(tvd、tis、jpg)、系统索引(idx、plf)、配置数据(cfs、xml)及日志调试文件(pwl1、pwl2),结构规范,便于理解项目组织方式。已有4428人学习下载,配套清晰的功能说明与典型截图(如正/反转运行图),无需实物设备即可深度理解指令时序、HMI交互与仿真验证全流程。
1. 零基础无实物学PLCS7-1200仿真:为什么八位流水灯是绕不开的“第一道真题”?
很多人以为S7-1200仿真只是点开TIA Portal、拖几个块、按一下“下载到PLC”——结果卡在第一步:连不上仿真PLC,或者灯根本不亮,更别说“跑”起来。其实,八位流水灯/跑马灯这个看似简单的项目,恰恰是检验你是否真正打通“逻辑→硬件映射→时序控制→仿真验证”全链路的试金石。它不依赖真实PLC或IO模块,纯靠软件仿真就能跑通;但又足够真实:你要手动配置CPU型号、分配DB块地址、写OB1主循环、用定时器做节拍、用移位指令控制灯序,甚至要处理“首尾衔接”“方向切换”这些实际产线里天天遇到的细节。我带过不少某高校自动化实训班的A同学,他们常在“灯怎么只亮一个就不动了”“为什么左移变右移就乱码”这类问题上卡两三天——不是不会写STL,而是没理清仿真环境下“虚拟IO”和“程序扫描周期”的隐含约束。这篇笔记,就是从零开始,不插一根线、不碰一块板,只靠TIA Portal V18(兼容V17/V19)+ PLCSIM Advanced V4.0,把八位流水灯从原理图、符号表、梯形图逻辑、仿真调试到波形验证,一步步拆解清楚。适合刚装好软件、还没见过PLC扫描周期概念的新手,也适合想补全仿真调试底层逻辑的熟手。
2. 用TIA Portal V18 + PLCSIM Advanced V4.0 搭建最小可运行仿真环境
2.1 创建项目并选择匹配的CPU型号:别让仿真器“不认识”你的CPU
新建项目后,必须在“设备组态”中添加一个S7-1200 CPU。这里有个关键细节:PLCSIM Advanced 并非支持所有1200型号。实测稳定可用的是6ES7 214-1AG40-0XB0(CPU 1214C DC/DC/DC)或6ES7 215-1AG40-0XB0(CPU 1215C DC/DC/DC)。如果你选了带“AC/DC/RLY”后缀的型号(比如214-1BG40),PLCSIM Advanced 启动时会报错“Unsupported CPU type”,因为仿真器对继电器输出型CPU的支持存在兼容性缺口。
// 在TIA Portal中操作路径: 项目树 → 设备组态 → 右键“设备名称” → “添加新设备” → 产品类别:控制器 → SIMATIC S7-1200 → 选择:SIMATIC S7-1200 (6ES7214-1AG40-0XB0) → 确定提示:不要选“S7-1200 (Generic)”或“S7-1200 (Simulation)”,那是旧版PLCSIM的占位符,与PLCSIM Advanced不互通。必须选具体订货号,且该订货号需在PLCSIM Advanced的官方支持列表内(V4.0支持至固件V4.5,CPU 1214C需固件≥V4.2)。
选对型号后,双击进入设备视图,在“常规”选项卡下确认“IP地址”设为192.168.0.1(这是PLCSIM Advanced默认监听地址)。同时勾选“启用仿真”——这步常被忽略,不勾选则PLCSIM Advanced无法识别该CPU实例。
2.2 配置PLCSIM Advanced:启动虚拟PLC前的三步必设
PLCSIM Advanced不是安装完就能用,它需要与TIA Portal建立“仿真连接通道”。常见翻车点在于:TIA Portal里点了“启动仿真”,但PLCSIM Advanced窗口黑屏无响应。根本原因是未完成以下三步绑定:
- 启动PLCSIM Advanced独立进程:在Windows开始菜单找到“PLCSIM Advanced”,以管理员身份运行(右键→“以管理员身份运行”)。首次运行会弹出许可提示,选择“Use existing license”即可(TIA Portal许可证已包含)。
- 创建仿真实例并绑定CPU:在PLCSIM Advanced主界面,点击“Create new instance” → 命名(如
Sim_1214C_Light)→ 在“CPU Type”下拉框中严格匹配你在TIA Portal中添加的CPU订货号(如6ES7214-1AG40-0XB0)→ 点击“Create”。 - 在TIA Portal中激活连接:回到TIA Portal,右键项目树中的CPU设备 → “在线” → “连接到PLCSIM Advanced” → 在弹出窗口中选择刚创建的实例名(如
Sim_1214C_Light)→ 点击“连接”。
此时PLCSIM Advanced窗口状态栏应显示“RUN”绿色指示灯,TIA Portal底部状态栏显示“已连接到仿真器”。若仍失败,请检查Windows防火墙是否阻止了PLCSIMAdvanced.exe的网络通信(需放行TCP端口102及UDP端口2222)。
2.3 定义八位输出变量:为什么必须用M区或DB块,而不能直连Q0.0-Q0.7?
S7-1200仿真中,Q点(物理输出)在PLCSIM Advanced里是只读的——你无法在监控表中直接修改Q0.0的值来“点亮灯”,因为仿真器模拟的是真实PLC的输出锁存行为:Q点只能由程序写入,不能被外部强制。所以,新手常犯的错误是:在程序里写Q0.0 := TRUE;,却在仿真器里看不到灯亮。真相是:PLCSIM Advanced默认不显示Q点状态,它只提供“虚拟IO映射视图”,而该视图需手动启用。
更可靠的做法,是完全避开Q点,改用M存储器或DB块变量作为“灯信号”的中间载体,再通过一个“输出映射块”统一刷新Q点。这样做的好处有三:
- 调试时可直接在监控表中修改M0.0-M0.7观察逻辑流;
- 避免因Q点刷新时机与扫描周期不同步导致的“灯闪烁异常”;
- 为后续扩展(如加按钮控制、速度调节)预留接口。
我们采用DB块方案,因其结构清晰、易扩展。新建数据块DB_Light,声明如下:
// DB_Light 中定义 "LightState" : ARRAY [0..7] OF Bool; // 八位灯状态,索引0为最左灯 "CurrentIndex" : Int; // 当前点亮位置(0~7) "Direction" : Bool; // FALSE=左移,TRUE=右移 "StepTime_ms" : DInt; // 步进时间(毫秒),初始设为500参数说明:
"LightState"数组是核心,它替代了物理Q点,所有移位逻辑都在此数组内运算;"CurrentIndex"用于定位当前灯,比用SHR/SHL指令硬移位更可控;"Direction"布尔量实现双向跑马,避免用ROL/ROR带来的进位干扰;"StepTime_ms"为后期加HMI调节埋点,此处先写死。
3. 编写八位流水灯核心逻辑:从单灯循环到双向跑马的三层递进
3.1 第一层:固定方向单循环(左移)——用定时器+数组索引实现精准节拍
很多教程直接用TON定时器触发SHL指令移位,但这样会导致两个问题:一是SHL对字节操作时,最高位移出后会丢失,无法自动回环;二是节拍精度受扫描周期影响(若OB1执行时间波动,灯速就不稳)。更鲁棒的做法是:用高精度时基定时器(TP)生成固定间隔中断,再在OB1中用索引查表更新状态。
我们在Main (OB1)中编写:
// OB1 主程序(部分) // 1. 初始化(首次扫描) IF "FirstScan" THEN "DB_Light"."CurrentIndex" := 0; "DB_Light"."Direction" := FALSE; "DB_Light"."StepTime_ms" := 500; "FirstScan" := FALSE; END_IF; // 2. 生成500ms节拍脉冲(使用TP定时器) "Timer_Pulse".IN := NOT "Timer_Pulse".Q; // 自振荡触发 "Timer_Pulse".PT := T#500MS; "Timer_Pulse"(IN := "Timer_Pulse".IN, PT := "Timer_Pulse".PT); IF "Timer_Pulse".Q THEN // 脉冲上升沿处理 IF NOT "DB_Light"."Direction" THEN // 左移:索引递增 "DB_Light"."CurrentIndex" := "DB_Light"."CurrentIndex" + 1; IF "DB_Light"."CurrentIndex" > 7 THEN "DB_Light"."CurrentIndex" := 0; // 回环 END_IF; END_IF; END_IF; // 3. 根据CurrentIndex更新LightState数组 FOR #i := 0 TO 7 DO "DB_Light"."LightState"[#i] := (#i = "DB_Light"."CurrentIndex"); END_FOR;逻辑说明:
"Timer_Pulse"是一个TP(Pulse Timer)指令,通过IN端自反馈实现500ms周期振荡。关键在IF "Timer_Pulse".Q THEN这一段——它确保每次节拍只执行一次索引更新,不受OB1扫描时间影响。FOR循环将当前索引对应位置置TRUE,其余置FALSE,彻底规避了移位指令的边界问题。参数"CurrentIndex"全程用Int类型,计算清晰,无溢出风险。
3.2 第二层:双向切换——用全局标志位+条件分支实现平滑转向
单向循环只是热身。真实场景中,常需按钮控制方向。我们用M10.0作为方向切换触发点(仿真中可在“监视与修改表”中强制该位)。升级后的逻辑加入状态机思想:
// OB1 中追加方向切换逻辑(接在节拍处理后) IF "M10.0" AND NOT "M10.0_Last" THEN // 上升沿检测 "DB_Light"."Direction" := NOT "DB_Light"."Direction"; // 切换瞬间重置索引,避免“跳灯” IF "DB_Light"."Direction" THEN // 切为右移,从最右开始 "DB_Light"."CurrentIndex" := 7; ELSE // 切为左移,从最左开始 "DB_Light"."CurrentIndex" := 0; END_IF; END_IF; "M10.0_Last" := "M10.0"; // 边沿检测记忆位 // 更新CurrentIndex的逻辑改为双向 IF "Timer_Pulse".Q THEN IF NOT "DB_Light"."Direction" THEN // 左移 "DB_Light"."CurrentIndex" := "DB_Light"."CurrentIndex" + 1; IF "DB_Light"."CurrentIndex" > 7 THEN "DB_Light"."CurrentIndex" := 0; END_IF; ELSE // 右移 "DB_Light"."CurrentIndex" := "DB_Light"."CurrentIndex" - 1; IF "DB_Light"."CurrentIndex" < 0 THEN "DB_Light"."CurrentIndex" := 7; END_IF; END_IF; END_IF;参数说明:
"M10.0_Last"是边沿检测必备的记忆位,防止长按按钮导致多次切换;索引重置策略(切右移时设为7,切左移时设为0)保证视觉连续性——否则用户会看到灯“突然跳到另一端”,体验割裂。此处不用MOVE指令批量赋值数组,而坚持用FOR循环,是因为FOR在TIA Portal中编译效率高,且便于后续加“渐变亮灭”等效果。
3.3 第三层:输出映射——把LightState数组安全写入Q点
现在"DB_Light"."LightState"已正确反映八位状态,下一步是将其映射到Q点。注意:S7-1200的Q0.0-Q0.7对应一个字节QB0,但直接QB0 := BYTE#16#01;会覆盖整个字节,破坏其他可能存在的输出。因此,我们用位操作指令逐位写入:
// OB1 末尾追加输出映射 // 将LightState[0]~[7] 映射到 Q0.0 ~ Q0.7 Q0.0 := "DB_Light"."LightState"[0]; Q0.1 := "DB_Light"."LightState"[1]; Q0.2 := "DB_Light"."LightState"[2]; Q0.3 := "DB_Light"."LightState"[3]; Q0.4 := "DB_Light"."LightState"[4]; Q0.5 := "DB_Light"."LightState"[5]; Q0.6 := "DB_Light"."LightState"[6]; Q0.7 := "DB_Light"."LightState"[7];逻辑说明:虽然写了8行,但TIA Portal编译后会优化为高效字节操作。比用
CONV指令转BYTE再MOVE更直观、更易调试。若未来扩展为16位灯,只需增加Q1.0到Q1.7的映射,逻辑结构不变。此处不推荐用USINT变量接收数组再整体赋值,因为USINT与ARRAY[0..7] OF Bool之间转换需额外CONV指令,增加扫描时间。
4. 仿真调试与波形验证:三个避坑指南让你少走两天弯路
4.1 现象:PLCSIM Advanced中Q点始终灰色,灯不亮
原因:PLCSIM Advanced默认不启用“IO映射视图”,且Q点状态需在“Virtual IO”窗口中手动开启。新手常误以为Q点状态应实时显示在TIA Portal的监控表中,但仿真器Q点是“只写不读”的。
解决:在PLCSIM Advanced主界面,点击顶部菜单“View” → “Virtual IO” → 勾选“Show Output Area”。此时窗口下方会出现Q0.0-Q0.7的LED指示灯,颜色随程序输出实时变化。若仍不亮,检查OB1中Q点赋值语句是否被条件块包裹(如IF FALSE THEN ... END_IF),或"DB_Light"."LightState"数组是否全为FALSE。
4.2 现象:灯跑着跑着就“卡住”不动,监控发现"CurrentIndex"停在某个值不再变化
原因:"Timer_Pulse".Q为TRUE的时间仅一个扫描周期,但若"Timer_Pulse"的IN端被其他逻辑意外置FALSE(如OB1中某处写了"Timer_Pulse".IN := FALSE;),则定时器停止振荡。更隐蔽的是:"Timer_Pulse".PT被动态修改为T#0MS,导致Q永远为FALSE。
解决:在TIA Portal中打开“交叉引用”,搜索"Timer_Pulse",确认其IN和PT端只在初始化和节拍逻辑中被写入;在监控表中添加"Timer_Pulse".Q和"Timer_Pulse".IN两列,观察其波形是否为标准方波(500ms高电平+500ms低电平)。若IN端恒为FALSE,检查是否有其他网络误写了该变量。
4.3 现象:切换方向时,灯出现“双亮”或“全灭”一帧
原因:方向切换与节拍脉冲不同步。例如,"M10.0"上升沿发生在"Timer_Pulse".Q为TRUE期间,导致同一扫描周期内既执行了索引重置(如设为7),又执行了右移逻辑(7-1=6),最终"CurrentIndex"变为6而非预期的7。
解决:将方向切换逻辑移出节拍条件块,并在索引更新前加“防抖锁”:
// 修改节拍内索引更新逻辑 IF "Timer_Pulse".Q THEN // 加入防抖:仅当无方向切换请求时才执行移位 IF NOT "DirectionChangePending" THEN // 原移位逻辑... END_IF; END_IF; // 方向切换逻辑(独立于节拍) IF "M10.0" AND NOT "M10.0_Last" THEN "DirectionChangePending" := TRUE; // 标记待处理 "NewDirection" := NOT "DB_Light"."Direction"; END_IF; // 在节拍外、OB1末尾处理切换 IF "DirectionChangePending" THEN "DB_Light"."Direction" := "NewDirection"; IF "DB_Light"."Direction" THEN "DB_Light"."CurrentIndex" := 7; ELSE "DB_Light"."CurrentIndex" := 0; END_IF; "DirectionChangePending" := FALSE; END_IF;这样,方向切换被延迟到下一个节拍周期开始前完成,彻底消除竞争。
4.4 现象:仿真运行几分钟后,PLCSIM Advanced报错“Instance stopped due to memory overflow”
原因:PLCSIM Advanced V4.0对DB块数量和大小有限制。若项目中无意创建了大量未使用的DB块(如复制粘贴时生成DB_Light_1,DB_Light_2...),或DB_Light中声明了超大数组(如ARRAY[0..1000] OF Real),会快速耗尽仿真器内存。
解决:在TIA Portal项目树中,展开“PLC tags” → “Data blocks”,删除所有未被程序调用的DB块;打开DB_Light,检查是否有多余变量(如调试用的"DebugCounter"未删);将"StepTime_ms"类型从DInt改为Int(节省2字节),虽小但积少成多。
4.5 现象:在“监视与修改表”中能强制"DB_Light"."LightState"[0]为TRUE,但Q0.0仍不亮
原因:强制(Force)功能在PLCSIM Advanced中默认关闭。即使你在TIA Portal里点了“启用强制”,仿真器本身需单独授权。
解决:在PLCSIM Advanced主界面,点击“Settings” → “Force Settings” → 勾选“Enable forcing for all instances” → 点击“Apply”。然后回到TIA Portal的监视表,右键变量 → “强制” → 输入值。注意:强制仅在仿真模式下生效,下载到真实PLC前务必取消所有强制。
5. 进阶技巧:用PLCSIM Advanced波形图验证时序,揪出隐藏的扫描周期偏差
5.1 启用波形记录:捕获5秒内"Timer_Pulse".Q与"CurrentIndex"的真实关系
PLCSIM Advanced自带波形分析工具,比TIA Portal的“趋势图”更精准,因为它直接采样CPU内部信号,不受通信延迟影响。要验证我们的500ms节拍是否真的稳定,必须用它:
- 在PLCSIM Advanced中,点击“View” → “Trace Configuration”;
- 点击“Add Variable”,输入变量名:
"Timer_Pulse".Q(注意引号和点号); - 再添加:
"DB_Light"."CurrentIndex"; - 设置采样周期为
10ms(足够捕捉节拍边沿); - 点击“Start Trace”,运行仿真5秒;
- 点击“Stop Trace”,自动生成波形图。
你会看到两条曲线:"Timer_Pulse".Q是标准方波,高电平宽度严格为500ms;"CurrentIndex"是一条阶梯线,每500ms跳变一次。若发现"CurrentIndex"跳变时刻比"Timer_Pulse".Q上升沿晚1~2个采样点(即10~20ms),说明OB1中逻辑运算耗时较长——此时应检查是否有冗余FOR循环或未优化的字符串操作。
5.2 用波形反推最大允许逻辑负载:当扫描周期逼近500ms时的预警阈值
PLC最关键的指标是扫描周期(Cycle Time)。若OB1执行时间接近节拍周期(500ms),则定时器精度崩塌。PLCSIM Advanced可直接显示当前扫描周期:
- 在PLCSIM Advanced主界面,点击“View” → “CPU Information”;
- 查看“Cycle time”字段,正常应≤10ms(我们逻辑极简,实测约3ms);
- 若该值持续>100ms,立即打开“Trace Configuration”,添加
"CycleTime"变量(系统内置),观察其波动。
我曾在一个模拟项目X中遇到类似问题:加入HMI通信后,扫描周期飙升至480ms,导致流水灯忽快忽慢。解决方案是:将HMI数据交换逻辑移入OB35(100ms定时中断),而OB1只保留灯控核心,最终扫描周期压回5ms以内。这个教训让我养成习惯:任何新增功能,必先用波形图测扫描周期,再决定放哪个OB里。
5.3 表格:八位流水灯仿真实战参数速查表(基于V18+V4.0实测)
| 参数项 | 推荐值 | 说明 | 调整影响 |
|---|---|---|---|
| CPU型号 | 6ES7214-1AG40-0XB0 | 固件V4.2+,PLCSIM Advanced V4.0原生支持 | 换AC型号会启动失败 |
| PLCSIM Advanced实例名 | Sim_1214C_Light | 建议含CPU型号和用途,避免多实例混淆 | 名称错误导致TIA Portal连接失败 |
| 节拍定时器类型 | TP(Pulse Timer) | 比TON更易实现自振荡 | TON需额外复位逻辑,易出错 |
| 节拍时间(PT) | T#500MS | 初始值,后续可由HMI修改 | <100ms时人眼难分辨,>1s显迟滞 |
| LightState数组类型 | ARRAY[0..7] OF Bool | 直观对应八位灯 | 改用BYTE需位运算,调试困难 |
| CurrentIndex类型 | Int | 范围0~7,安全无溢出 | 用USInt在减1时会溢出为255 |
| 波形采样周期 | 10ms | 平衡精度与内存占用 | <5ms易致仿真器卡顿 |
最后说个血泪经验:别在第一次仿真时就追求“完美HMI”。先把八位灯在PLCSIM Advanced的Virtual IO窗口里跑顺,用波形图确认时序干净,再加按钮、再加速度滑块。我见过太多A同学,花三天调HMI通信,却没发现灯逻辑本身在第17次扫描时就因"CurrentIndex"越界而崩溃——那才是真正的玄学源头。希望帮到你。
本文还有配套的精品资源,点击获取