简介:面向零基础电气自动化学习者,这份西门子S7-1200/1500仿真教程围绕八位流水灯/跑马灯案例,介绍通过按键控制LED灯的方法,重点学习移位和循环指令,也适用于中职、高职及本科电气相关专业课后实操。项目要求设置启动、停止按钮和8个圆形LED灯,按下启动后按0.5秒间隔依次点亮或成组跑马,4秒循环一次,形成直观的流水/跑马效果,便于理解程序时序与HMI面板的配合方式。压缩包共48个文件,包含博途V15.1项目文件、HMI仿真配置和运行截图等,核心文件涵盖PLC程序、触摸屏界面定义与仿真数据,整体约7MB,需使用V15.1及以上版本打开。已有4420人学习该资源。学习后可获得可直接运行的PLC程序与HMI仿真工程,无需实物即可观察实际运行效果,同时理解移位循环指令与组态软件的基本用法,适合日常练习和教学演示。 流水灯这个练习,玩过 PLC S7-1200 仿真的朋友基本都绕不过去。它看着就是八个灯轮流亮,可真要自己从头到尾写出来,定时器怎么自复位、计数器怎么循环、输出怎么映射,每一步都在考察你是不是真正理解了扫描周期和位逻辑。这一篇是零基础无实物系列第九次更新,继续用仿真环境把八位流水灯完整跑一遍。全程不需要任何实体 PLC,只要电脑上装了 TIA Portal 和 PLCSIM 就能跟着做。
我会直接按实际操作的顺序走,先把方案思路讲透,再一步步搭梯形图,最后把仿真运行、调试观察、常见坑都过一遍。这套程序我会刻意用“计数器 + 比较器”的方式写,虽然看着比移位指令啰嗦,但对零基础来说每条网路在做什么一清二楚,逻辑上不容易绕晕。
1. 一到八位流水灯,为什么值得专门练一次
1.1 流水灯不是炫技,是PLC基础指令的综合体检
很多初学者学完位逻辑、定时器、计数器之后,总觉得这些指令是散的,不知道它们怎么配合。流水灯恰好把这几样东西串了起来:定时器负责产生稳定的时间节拍,计数器在这个节拍下做 0 到 7 的循环,比较器再把计数值翻译成 8 个输出点的亮灭。这样一个程序里既有时间的控制,又有数据的转换,还有输出驱动的概念,比单独练某一条指令有意义得多。
从实际应用角度来说,流水灯的逻辑和传送带工位指示、设备状态轮流显示、多步骤动作顺序启动都是一路的。你把这个八位循环写明白了,后面做顺序控制、工步切换的时候,思路会顺很多。这也是为什么很多培训课都把流水灯当成“入门毕业设计”,它不是让你背指令,而是逼你把程序的执行流程捋清楚。
1.2 三种实现思路对比,新手先别急着用最省事的
我见过不少群里讨论流水灯怎么写,主流方案大概有三种:
| 方案 | 核心指令 | 优点 | 缺点 | 适合人群 |
|---|---|---|---|---|
| 计数器+比较器 | CTU、CMP | 逻辑直白,每行程序都能看懂 | 程序段较多,输出点多了会有点啰嗦 | 零基础、刚接触PLC编程 |
| 移位寄存器 | SHRB | 程序简洁,几条网络就搞定 | 要理解移位方向、数据流入流出,首尾循环容易接错 | 有一定基础后优化使用 |
| 数据块循环赋值 | SHL/SHR、MOVE | 代码量少,扩展方便 | 涉及数据位操作,概念抽象,不适合第一遍学 | 熟悉数据存取后进阶 |
这次我选择第一种,原因很简单:仿真环境下没有硬件IO可以观察,程序写得太“高级”反而容易出问题。计数器 + 比较器的写法,每个扫描周期做了什么,你打开监控表一眼就能看穿。等这套跑通了,你想优化成 SHRB 移位寄存器写法,那就是顺手的事。
1.3 核心控制逻辑先画在脑子里
动手写程序之前,先把整个循环的节奏想明白。我的目标很简单:八个灯 Q0.0 到 Q0.7,从左到右轮流点亮,每个灯亮 0.5 秒,然后无限循环。
这个需求拆成三个步骤就很清晰:
- 第一步,产生一个周期性的脉冲,每隔 0.5 秒来一次。
- 第二步,用一个计数器数这个脉冲,数到 8 就归零重来。
- 第三步,根据计数器的当前值,决定哪个输出点得电。
为什么计数器要 0 到 7 循环而不是 1 到 8 循环?因为八位流水灯最方便的是让计数值和输出位一一对应:计数 0 对应 Q0.0,计数 1 对应 Q0.1,以此类推。这样后面写比较器的时候,每个网络都是“如果当前值等于几,就点亮第几个灯”,思路不会乱。
2. 仿真前的准备工作和项目搭建
2.1 软件环境:TIA Portal + PLCSIM,缺一不可
做无实物仿真,主力工具就是西门子的 TIA Portal(博途)和 PLCSIM。我以 TIA Portal V17 为例操作,如果你用的是 V15.1、V16、V18,步骤基本一样,只是界面细节略有区别。
需要说明的是,PLCSIM 是包含在博途安装包里的,不需要额外找破解版。安装博途的时候勾选对应组件,装好之后桌面会多一个“S7-PLCSIM”图标。我这个系列一直强调无实物,靠的就是这个仿真器——它能在电脑里模拟出一个完整的 S7-1200 CPU 运行环境,梯形图程序下载进去之后,变量状态、定时器、计数器全部真实运行。
2.2 新建项目并添加 S7-1200 设备
打开 TIA Portal,第一步是“创建新项目”。项目名称建议写成“FlowLight_8bit”这类一眼能看懂的,路径尽量不要带中文,有些人电脑上博途对中文路径支持不好,容易出现莫名其妙的编译问题。
项目建好后,进入“添加设备”向导:
- 控制器类型选择“SIMATIC S7-1200”。
- CPU型号选 CPU 1214C DC/DC/DC。
- 固件版本选你 PLCSIM 支持的最高版本,比如 V4.5。
- 确认后系统会生成一个默认的 PLC 站点。
选 CPU 1214C 是因为它带 8 路数字量输出,Q0.0 到 Q0.7 正好齐全,不会出现输出端子不够的情况。实际上你选 1211C 这类小型 CPU 也能做逻辑仿真,但输出点不够八路,不方便观察。
2.3 定义变量:把仿真里的输入输出规划好
打开 PLC 变量表,我习惯先把要用到的变量建好,避免写程序的时候一边写一边翻地址。这个案例的变量表可以做成这样:
| 变量名称 | 数据类型 | 地址 | 注释 |
|---|---|---|---|
| Start | Bool | %I0.0 | 启动按钮(仿真中强制为TRUE) |
| ClockPulse | Bool | %M1.0 | 定时器产生的0.5秒脉冲 |
| CountValue | Int | %MW10 | 计数器当前值,0~7循环 |
| ResetCounter | Bool | %M4.0 | 计数器复位标志 |
| Q0_0 ~ Q0_7 | Bool | %Q0.0 ~ %Q0.7 | 八位流水灯输出 |
这里有个细节:流水灯的输出点能不能直接用 Q0.0 到 Q0.7?可以。虽然在真实设备中输出点对应端子,但在 PLCSIM 仿真中它们会被模拟成一个变量,你可以像观察 M 变量一样查看它们的状态。
3. 核心程序一步一步搭出来
3.1 网络1:自复位定时器,生成 0.5 秒脉冲
流水灯的速度控制,本质上是定时器的定时时间控制。我在 OB1 的第一个网络里放一个 TON 定时器,用它产生 0.5 秒的脉冲。
最常见的写法是“定时器常闭触点接到定时器输入”:
- %M1.0 是定时器 T1 的 Q 输出。
- 把 T1.Q 的常闭触点接到 T1 的 IN 输入。
- PT 定时时间设为 T#500ms。
逻辑是这样走的:定时器初始 Q=0,常闭触点闭合,IN=1,定时开始;经过 500ms 后 Q 变为 1,下一扫描周期常闭触点断开,IN=0,Q 又变回 0;再下一周期常闭触点重新闭合,又开始新的一轮定时。结果就是 %M1.0 每隔 0.5 秒接通一个扫描周期,形成固定节拍。
如果你在博途里直接写这个电路,系统会提示你用“定时器”类型的背景数据块。可以在 PLC 数据类型里先建一个“MyTimer”变量,类型选 TON,然后在程序里把定时器指令实例指过去。这个背景数据块是定时器正常运行的工作区,不要删除。
3.2 网络2:计数器开始数脉冲
把网络1生成的脉冲 %M1.0 作为计数器的计数输入。我使用 CTU 加计数器,PV(预设值)设为 8。
CTU 指令有四个关键端口:
- CU:计数脉冲输入端。
- R:复位端,R 为 1 时计数值清零。
- Q:输出端,当当前值大于等于 PV 时为 1。
- CV:当前值,输出到变量 %MW10。
现在计数器会随着脉冲从 0 往上数,数到 8 之后要重置回 0,否则就停在那里不循环了。所以我在网络3里专门做计数复位判断。
3.3 网络3:计数值到 8 就复位
这一步是循环的关键。我在网络3里写一个比较指令:
- 比较 %MW10 >= 8。
- 比较结果输出到 %M4.0(ResetCounter)。
- 把 %M4.0 接回网络2 CTU 的 R 端。
大致的逻辑链是:计数器计到 8 时,%MW10等于8,比较器输出 %M4.0=1,于是计数器复位,%MW10 会被清零;清零之后比较器条件不成立,%M4.0 变回 0,计数器开始下一轮计数。
很多初学者会在这里踩坑:为什么计数器到 8 之后不停一下?因为 CTU 在 R 端为 1 时复位是一个即时行为,不需要等一个特殊信号。所以你看到的现象就是 0→1→2→3→4→5→6→7→0→1→2……无限循环,不会像普通加法那样一直涨上去。
3.4 网络4到网络11:把计数值变成 8 个输出
接下来是输出的映射。我在后续的网络里连续放 8 个比较指令,每个网络对应一个输出位。
- 网络4:比较 %MW10 == 0,输出 Q0.0。
- 网络5:比较 %MW10 == 1,输出 Q0.1。
- 网络6:比较 %MW10 == 2,输出 Q0.2。
- 网络7:比较 %MW10 == 3,输出 Q0.3。
- 网络8:比较 %MW10 == 4,输出 Q0.4。
- 网络9:比较 %MW10 == 5,输出 Q0.5。
- 网络10:比较 %MW10 == 6,输出 Q0.6。
- 网络11:比较 %MW10 == 7,输出 Q0.7。
这里的“输出”,在梯形图里直接用普通的输出线圈写 Q0.0 到 Q0.7 就行。因为当前值在一个扫描周期内只有一个确定数值,所以任意时刻最多只有一个比较指令条件成立,也就只有一个灯会亮,不会出现两个灯同时亮的混乱情况。
如果你觉得 8 个网络太占地方,后面可以使用“选择性置位”或“SCL 的 CASE 语句”来优化。但第一次练习,我不建议你为了省网络把逻辑写得很花哨,直白一点反而容易查错。
3.5 完整的程序段清单
把整个 OB1 里的网络按顺序拉出来,应该是这样:
| 网络号 | 功能 | 关键逻辑 | 输出 |
|---|---|---|---|
| 1 | 自复位定时器 | TON,PT=500ms | %M1.0 |
| 2 | 脉冲计数 | CTU,PV=8,R接%M4.0 | %MW10 |
| 3 | 计数复位 | 比较%MW10>=8 | %M4.0 |
| 4 | 输出灯0 | 比较%MW10==0 | Q0.0 |
| 5 | 输出灯1 | 比较%MW10==1 | Q0.1 |
| 6 | 输出灯2 | 比较%MW10==2 | Q0.2 |
| 7 | 输出灯3 | 比较%MW10==3 | Q0.3 |
| 8 | 输出灯4 | 比较%MW10==4 | Q0.4 |
| 9 | 输出灯5 | 比较%MW10==5 | Q0.5 |
| 10 | 输出灯6 | 比较%MW10==6 | Q0.6 |
| 11 | 输出灯7 | 比较%MW10==7 | Q0.7 |
这个结构看着长,但每段做什么一目了然。编译时如果某条指令报错,你只需要检查对应网络里的变量名是不是写错了,排查成本非常低。
4. 仿真运行、观察与验证
4.1 编译下载,把程序灌进仿真PLC
程序写完之后,先点一下“编译”,让博途检查有没有语法错误。编译通过后,点击“下载”按钮,博途会提示你要选择一个设备。这时候如果你还没启动 PLCSIM,就先打开 S7-PLCSIM,创建一个新的仿真 PLC,然后在博途里刷新设备列表,选中仿真节点后下载。
下载成功之后,把 PLCSIM 里的运行状态切换到 RUN。你可能会注意到仿真 PLC 面板上有 STOP/RUN 按钮,手动点成 RUN 会让程序开始循环扫描。
这里有个小提示:如果下载时提示“硬件配置不一致”,多半是 PLCSIM 里选的 CPU 型号和博途项目里的不一致。删掉 PLCSIM 的旧实例重新创建一个,再下载一次就好了。
4.2 用监控表观察数据流
程序跑起来后,我习惯先在“监控表”里添加几行观察变量:Start、ClockPulse、CountValue、ResetCounter,以及 Q0.0 到 Q0.7。把视图切到“全部在线”,就能看到变量值实时变化。
你看到的现象应该是这样:%MW10 从 0 跳到 1、2、3……一直到 7,然后跳回 0,每秒变化两次(因为 0.5 秒一次脉冲)。同时 Q0.0 到 Q0.7 跟着 %MW10 的数值轮流变 TRUE。这就是一个标准的八位流水灯。
如果你的 Start 变量接在某个触发条件上,先强制 Start 为 TRUE 再观察。仿真器里强制变量很快,在监控表那一行右键“修改为1”即可。
4.3 修改速度:把 0.5 秒改成你想要的节奏
这个程序最让人舒服的地方就是调速非常方便。调速度不需要改梯形图结构,只修改网络1 TON 定时器的 PT 参数就行。
我试过几种不同的时间:
| 定时时间 | 效果 |
|---|---|
| 100ms | 快速跑动,频繁跳变 |
| 500ms | 清晰可见的逐位点亮 |
| 1000ms | 像老式跑马灯,节奏明显 |
| 2000ms | 适合拍视频演示 |
建议新手先用 500ms 或 1000ms,看得清楚逻辑是否正常。等你确认逻辑没问题了,再改成 200ms 体验高速流水效果,顺便感受一下扫描周期和定时精度的关系。
5. 常见问题与排查技巧实录
5.1 灯不亮,或者只有一个灯常亮
这个情况大概率不是输出比较写错,而是定时器没有正常产生脉冲。去监控表里看 %M1.0 有没有变化。
如果 %M1.0 一直是 0,检查网络1的自复位定时器回路:T1.Q 的常闭触点有没有接对?IN 之前是不是漏掉了启动条件?如果你在自复位回路前还加了一个 Start 常开触点,记得要在监控表里强制 Start 为 TRUE,否则定时器永远不会开始工作。
如果 %M1.0 有脉冲但灯不亮,再查计数器 %MW10 是否变化。如果 %MW10 一直在 0 不动,那就是 CTU 的 CU 端没有接上 %M1.0,或者 R 端被某个常量置 1 了,导致计数器一直处于复位状态。
5.2 计数到 7 之后不回到 0
这问题十有八九出在网络3的比较指令上。可能是你比较条件写成了“大于 7”,也可能是比较结果没有接到 CTU 的 R 端。
我个人踩过的坑是:CTU 的 Q 输出直接接自己的 R 端,结果仿真时出现逻辑竞争,计数器复位不稳定。后来改成独立比较指令输出到中间变量 %M4.0,再用 %M4.0 去复位计数器,问题就消失了。建议你也按这个方式写,作为中间标志位的课程,顺便就练了。
5.3 下载程序后运行状态自动变回 STOP
S7-1200 在程序异常时可能会进入 STOP 状态,常见原因是数组越界、访问了不存在的地址。如果你用的是我上面的变量表,基本不会触发。但如果你自己扩展时把 %MW10 改成了不连续的数据区,就要检查一下地址是否有重叠。
另外,PLCSIM 里默认的 CPU 属性可能会检查某些安全设置,如果你下载时勾选了“下载前复位”,程序下载成功后会先把 CPU 停一下再启动,这时候你手动切到 RUN 即可。
5.4 为什么我把定时器时间改成 10ms,灯反而不正常了
这里要明白一个概念:S7-1200 的扫描周期通常是毫秒级,极短。如果你把定时器时间设得比扫描周期还短,或者非常接近,输出变化的节奏就不稳定,看起来像卡顿、跳变。
流水灯这种演示程序,建议用 100ms 以上的时间。低于 50ms 用人眼已经很难分辨了,而且容易让人误以为程序有 bug。仿真不是为了把速度做到极限,而是把逻辑验证准确。
6. 这个程序还能怎么玩出花
6.1 改成双向流水灯
把 CTU 替换成加/减计数器(CTUD),再用一个方向开关控制加计数还是减计数,就能实现从左往右、从右往左的双向流动。
方向控制的思路是:当方向位为 TRUE 时允许加计数,为 FALSE 时允许减计数。减到 0 之后要跳回 7 继续反向流动,这里需要在比较逻辑上多写两个分支。
6.2 用变量调节速度
现在 PT 是固定值 T#500ms,你可以把 PT 改成数据块里的一个 Time 变量,然后用监控表或者 HMI 画面在线修改变量的值。这样就能在没有实体按钮的情况下,实现“速度随便调”。
比如建一个全局 DB,里面放一个“Speed”变量,类型为 Time,然后网络1的 PT 直接引用 DB.Speed。仿真时用监控表往里写 T#300ms,流水速度立刻变化,比改一次程序下载一次方便多了。
6.3 组合成花样跑马灯
八位流水灯只是起点。你可以用两个计数器交替工作,或者用多个定时器分段点亮,做出“先亮一半再亮一半”“从两边往中间聚拢”“波浪式闪烁”这些效果。
我最推荐练的进阶方向是:把输出映射从“比较器一个输出”改成“表格映射”,在数据块里放 8 个数值代表 8 个输出状态,然后循环读取表格。这种做法稍微复杂,但已经是小型分时控制程序的雏形了。
这个流水灯程序,我前前后后在仿真环境里跑了很多遍。从一开始照着别人的梯形图抄都抄不对,到后来闭着眼睛能画出自复位定时器,中间最大的体会就是:不要嫌程序啰嗦,直接写最简单的版本,先把每个网络的执行顺序搞清楚,再想着精简。计数器 + 比较器的方式看起来笨,但它最能让你看到扫描周期是怎么把一条条梯形图串起来的。等哪天你能不看别人例子、自己从头到尾写出来并一次运行成功,S7-1200 基础这块就算真的过了。
本文还有配套的精品资源,点击获取