news 2026/9/19 13:59:51

S7-1200流水灯PLC程序拆解:移位循环与上电延时原理

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
S7-1200流水灯PLC程序拆解:移位循环与上电延时原理

干电气维修和调试这行十几年,天天跟各种设备打交道,PLC程序看过的没有一千也有八百。前阵子车间里有个小活,老板说新来的电工想练练手,让我拆个S7-1200的流水灯程序讲讲原理。我想着这玩意儿确实是个好的教学案例,逻辑简单、效果直观,但里面涉及到的小知识点一点都不少:上电延时、移位循环、定时器配合、字节位映射这些,够新手琢磨一阵子了。

今天就把这个“上电延时触发移位循环流水灯”的梯形图程序从头到尾拆一遍,把每一步的逻辑、指令选择的原因、调试时踩过的坑都写清楚。不管你是刚摸PLC的电气小白,还是在车间搞设备维护想补补基本功的老师傅,这篇都能给你点实在东西。即使手头没有S7-1200实物,照着思路用博途仿真也一样能跑起来。

1. 项目思路拆解:流水灯为什么用“移位循环”

1.1 先搞清楚流水灯到底要实现什么效果

所谓的“流水灯”,说通俗点就是一个一个灯依次点亮,像水流一样过去。最常见的效果有几种:单灯从左往右扫过去、单灯从两端往中间聚拢、多灯跑马灯式循环,以及全亮全灭的呼吸效果。这次龙师傅拆的这个程序是最基础的“单灯循环右移”或者“单灯循环左移”——起始只有第一个灯亮,每隔一段时间,亮灯的位置往旁边挪一位,走到最边上了再跳回起点,周而复始。

这里有个容易搞混的概念:移位循环里的“循环”两个字,指的是位数据从寄存器一头溢出后,从另一头再补进来。这不同于普通的左移或右移,普通移位空出来的是补0,而循环移位是“头尾相接”的。比如一个字节8个bit,第7位(最高位)移出去之后,这个1被送到第0位(最低位),这样就形成了一个闭环,灯永远不会灭,只会转圈。

1.2 为什么不用一堆置位复位,而是用移位指令

很多刚学梯形图的朋友,第一反应是:我有8个灯,那我就写8个输出,用一个定时器轮流触发置位和复位不就行了吗?理论上可以,但是程序会非常啰嗦。比如说8个灯,每个灯至少需要一段置位逻辑、一段复位逻辑,加上定时、切换,程序会膨胀到几十行。如果以后改成16个灯、32个灯,这种写法几乎是灾难,改起来恨不得把整个程序重写。

移位循环方案就优雅得多。核心思想是用一个字节(Byte)或一个字(Word)作为“数据容器”,每个bit代表一个灯,0是灭、1是亮。通过移位指令让这个“1”在容器里移动位置,再把容器的bit直接映射到输出Q点。程序只需要一个移位指令加一个边界判断,不管你接8个灯还是16个灯,核心逻辑几乎不用变,只需要改数据类型和输出映射而已。这就是“数据驱动逻辑”的思路,跟那种一条指令写一个灯的“点动思维”完全不在一个层级上。

1.3 上电延时触发是什么意思、有什么用

上电延时触发,字面理解就是系统上电之后,不立刻开始跑流水灯,而是等一段时间再启动。为什么要加这个延时?两个原因:一是设备上电瞬间,PLC内部的输出模块、外部继电器、接触器都处于不稳定状态,电压还没稳定,这时候如果输出直接动作,容易误触发外部设备,可能引起机械冲击或者安全事故;二是很多设备有“自检”流程,上电后需要先让系统初始化完成,确认外部条件OK了再进入运行逻辑。比如你接的是一个传送带的示意灯,上电后让操作员有时间离开危险区域,再开始跑灯,这个延时就能起到缓冲作用。

在这个程序里,延时一般用TON(接通延时定时器)来实现。按下启动按钮后,先让M0.0运行标志置位,但此时输出还不动作,TON开始计时,计时结束的瞬间产生一个完成标志,这个标志才去激活移位循环的“使能”端。为什么不用定时器直接用?因为TON的Q端在延时结束后会一直保持为1,如果你把这个Q端直接当使能信号,那没什么问题,但如果你想控制“延时不重新开始”,就需要处理得精细一点,否则每次按下启动都会重新计时。具体代码里怎么处理,后面第三节会详细说。

2. 软硬件准备与工程搭建:跑通程序需要什么

2.1 S7-1200的硬件选型与博途软件版本

先聊硬件。S7-1200是西门子的小型PLC,常见型号有1211C、1214C、1215C,本体自带一部分数字量IO。做流水灯这种纯演示项目,用CPU 1214C DC/DC/DC最合适,自带14个数字量输入和10个数字量输出,Q0.0到Q0.7正好8个点,全都能用来接指示灯。如果你是自学的,手头没有实物也没关系,博途软件自带PLCSIM仿真功能,仿真器里可以监控程序运行状态,唯一区别是没有真实IO输出,得靠变量表或者强制表来看字节数据的变化。

软件方面,TIA Portal(博途)从V13开始就支持S7-1200,现在V15、V16、V17都是主流。版本不用纠结,代码逻辑基本一样,我用V16演示。如果你用的是V13或V11,创建项目和指令位置略有差异,但梯形图指令名称是通用的。

2.2 新建博途项目并完成基础配置

打开博途,在“启动”界面点“创建新项目”,输入项目名称,比如“S7-1200流水灯演示”,点确定。然后在项目树里双击“添加新设备”,选择一个S7-1200 CPU型号。这里注意一点:选CPU时一定要选对订货号和固件版本,否则下载程序的时候会报固件不匹配。常见1214C的订货号是6ES7 214-1AG40-0XB0,对应固件V4.0。选完CPU后,系统会提示是否调用OB1,默认是有的,这个OB1就是主程序块,我们绝大部分逻辑都写在OB1里。

设备添加完成后,还有两个设置建议提前做。第一个是CPU属性里的“启动”方式,默认是“暖启动-重新启动”,保持默认即可,这意味着CPU上电后会执行一次OB100启动组织块再扫描OB1,正好可以利用OB100做初始化。第二个是数字量输出的“对CPU STOP的响应”,默认是“关闭输出”,这个保持默认,安全。如果你用的是实际PLC而不是仿真,别忘了在“设备和网络”视图里给CPU分配IP地址,IP地址要和电脑在同一网段,比如PLC设192.168.0.1,电脑设192.168.0.2。

2.3 变量规划:用符号表理清每个地址的含义

我见过很多新手写程序,直接在梯形图里填I0.0、Q0.0这种绝对地址,这个习惯非常不好。程序短还好说,程序一长,满屏的I0.0、M0.2,你根本分不清哪个是启动哪个是停止,后期维护简直想哭。正确做法是在“PLC变量表”里把用到的地址一个个定义好符号名,然后在梯形图里直接使用符号名。

这个程序的变量表大致如下:

符号名数据类型地址注释
启动按钮BoolI0.0点动启动,上升沿触发
停止按钮BoolI0.1常闭触点,按下停止
运行标志BoolM0.0程序运行总开关
延时完成标志BoolM0.1TON定时器Q端
移位时钟BoolM0.21Hz脉冲,产生移位触发
移位数据ByteMB20当前灯的亮灭状态
初始值ByteMB21流水起始值,默认1
延时设定值DIntMD40上电延时时间,毫秒
LED输出-Q0.0~Q0.7BoolQ0.0~Q0.78路指示灯输出

变量表建好后,梯形图里引用M0.0时会显示“运行标志”这四个字,程序可读性直接上一个台阶。

3. 梯形图程序逐段拆解:延时、移位、输出映射全流程

3.1 启动组织块OB100:给程序一个“干净”的起点

S7-1200跟S7-200/300有个不同点:它有一个OB100启动组织块,CPU每次从STOP切到RUN,或者上电启动,OB100里的程序只执行一次,然后才进入OB1循环扫描。这个特性非常适合做初始化操作。

在OB100里,我们要做的事只有三件:把运行标志M0.0复位成0,把移位数据MB20清零,清掉延时完成标志M0.1。为什么要清零MB20?如果不清零,上一次运行的残留数据还在里面,可能一开机就莫名点亮某个灯。初始化逻辑用梯形图写很简单:用一段常开触点加一个复位线圈就行。比如用“常ON”的M0.3(或者直接用系统常量TRUE)去复位M0.0,再复位MB20,再复位M0.1。

这里有个细节:OB100里复位的M0.1,和OB1里TON定时器的M0.1是同一个地址。这样设计的目的是CPU启动瞬间,延时是肯定不会立即完成的,必须先处于“未完成”状态。如果不做这个复位,万一M0.1在断电前刚好是1,那下次上电,即使运行标志还没置位,输出逻辑里的某些使能条件可能在不该满足的时候满足了。虽然不一定造成事故,但程序不严谨,隐患早晚出事。

3.2 启停控制与上电延时:像给程序装一道闸门

主程序OB1里,第一段要处理启停逻辑。启动按钮I0.0的上升沿用来置位运行标志M0.0,停止按钮I0.1作为复位条件去复位M0.0、MB20和M0.1。很多老师傅习惯把停止按钮接成常闭触点接到输入端,梯形图里用常开指令读取,也就是“急停优先,断开优先”的逻辑。如果接常开,线掉了停不下来,这是安全大忌。

启停做完了,然后是延时部分。当运行标志M0.0为1时,接通一个TON定时器。TON的输入IN接M0.0,PT端接延时设定值MD40,Q端输出到M0.1,ET是当前计时值,可以用变量表监控。这里关键点是:当M0.0从0变1时,TON开始从0计时;计时到设定值后,M0.1被置为1并保持;只要M0.0一直为1,M0.1就一直为1。如果M0.0断开,TON复位,M0.1立即变0,下次启动重新计时。这就实现了“每次按下启动后,都先等5秒再开始跑灯”的效果。延时时间我习惯在程序里写死为5000ms,如果你想通过触摸屏调节,把这个地址换成触摸屏连接的DB块变量即可。

3.3 移位循环核心:时钟上升沿驱动“1”往前走

灯要“走”起来,必须有一个节拍,就像音乐需要有拍子一样。这个节拍我习惯用M0.2移位时钟来表示。生成1Hz脉冲的常用方法是用另一个TON定时器做自复位振荡器,也叫“闪烁电路”:当M0.1延时完成标志为1时,TON2开始计时,计时500ms后Q端振一下,同时用它的常闭触点或者常开触点让TON2复位,然后再重新开始计时,循环往复,产生0.5秒周期的方波信号。取这个方波的上升沿,就得到了每500ms一次的移位触发脉冲。

注意,梯形图里“上升沿”用的是边沿检测指令。我喜欢用“R_TRIG”触发块,因为它比普通的“触点上升沿”更清晰,尤其是在S7-1200的梯形图里,R_TRIG是一个功能块,需要配一个背景DB或者在全局DB里调用。用R_TRIG的CLK端接M0.2,Q端接M0.4。这样M0.4就变成了一个“脉宽为一个扫描周期”的脉冲信号,只在M0.2从0变1的那一瞬间为1,其他时间都是0。

移位操作就是在这个M0.4的脉冲驱动下执行。S7-1200的移位指令在梯形图里叫“SHL”(左移),全称Shift Left。具体用法:EN使能端接M0.4,IN端接MB20(要移动的数据),N端接1(每次移动1位),OUT端接MB20(结果存回原地址)。这样一来,每来一个脉冲,MB20就往高位方向挪一位,里面的那个“1”就从bit0跑到bit1,再跑到bit2,依次点亮Q0.0到Q0.7。

3.4 循环边界处理:让灯绕回起点的关键技巧

移位指令本身只负责移动,它不管数据会不会越界。当MB20里的“1”到达bit7(最高位)后,再执行一次左移,这个1就会从最高位移出去,MB20全部变成0,灯全灭,这不叫循环。

所以我们必须自己写边界判断。思路很简单:在每次移位之后,扫描MB20的最高位M20.7(也就是bit7)的上升沿,如果它变成1了,说明“1”已经走到头了,那么在下一个扫描周期,把MB20重新赋值为1,让“1”回到最低位,重新开始走。用梯形图写就是:M20.7的上升沿作为条件,执行一条“MOVE”指令,把常数1传送到MB20里去。

有人可能会问:为什么不直接用循环左移指令ROR/ROL?这样硬件上就不需要边界判断了。这个想法是对的,S7-1200确实有ROR(循环右移)和ROL(循环左移)指令,直接就是循环移位。但这里有个坑:S7-1200基础指令库里,ROL和ROR的操作数类型是双字(DWord),不是字节或字。你如果想把MB20这个字节做循环左移,得先把数据转换成双字再左移再截取低位,操作反而更繁琐。所以这个项目里用“普通左移+边界重装初值”的组合,反而更简单直观,也更容易让初学者理解循环的本质——所谓循环,就是到头的重新开始。等以后做32位流水灯时,直接用双字的ROL指令会更高效,但初学者先把这种思路吃透,受用无穷。

3.5 输出映射:把数据变成真实的灯

数据在MB20里已经跑了,但是MB20是个内部存储字节,它不会直接驱动物理输出。最后一步是把MB20的每一位映射到Q0.0到Q0.7。最简单的方法是直接用8条赋值语句:Q0.0 := MB20的bit0,Q0.1 := MB20的bit1,依次类推。梯形图里可以写成常开触点引用M20.0去驱动Q0.0的线圈,引用M20.1驱动Q0.1,以此类推。

还有一种更简洁的方法是利用西门子的I/O直接映射特性:把Q0.0到Q0.7所在的字节QB0直接赋值给MB20。也就是执行一条MOVE指令,把MB20传送到QB0。这样一条指令搞定8个输出,程序非常紧凑。但用这个方法有个前提:QB0的低8位(Q0.0~Q0.7)不能同时被其他逻辑使用,否则会覆盖。在流水灯演示项目里,QB0专门留给指示灯,所以可以放心用MOVE直接输出。

输出映射放到移位的后面,顺序别搞反。如果先映射再移位,那灯会“慢半拍”,每次总是显示上一次的移位结果。正确顺序是:检测移位脉冲→执行移位→边界判断重装初值→把新值映射到输出。扫描周期是毫秒级的,人眼感觉不到延迟,但逻辑上必须对。

3.6 完整程序段顺序总结

把上面所有逻辑整理成梯形图程序段,顺序至关重要:

  1. 程序段1:启动停止逻辑,置位复位运行标志M0.0
  2. 程序段2:上电延时TON,M0.0驱动TON,Q端输出到M0.1
  3. 程序段3:1Hz时钟发生器,用M0.1作为使能,TON2自复位振荡产生M0.2
  4. 程序段4:上升沿检测,R_TRIG检测M0.2上升沿,输出到M0.4
  5. 程序段5:移位执行,M0.4驱动SHL指令,把MB20左移1位
  6. 程序段6:边界重装,M20.7上升沿触发MOVE,把1写入MB20
  7. 程序段7:输出映射,MOVE指令把MB20传送到QB0

这7段程序全部用梯形图写,逻辑清晰,从上往下一条线,任何人拿到手都能顺着检查。

4. 实操调试与常见问题:仿真运行和现场排障

4.1 用PLCSIM仿真运行,没有PLC也能学

没有实物的时候,博途的PLCSIM是学习神器。把程序写好、编译通过后,点仿真按钮,PLCSIM会自动启动,然后点下载,把程序下载到虚拟PLC里。在PLCSIM界面里,点“启动”按钮让CPU进入RUN状态,就能看到程序开始执行了。

但PLCSIM有个麻烦:它不模拟真实的物理输入输出点。你想按下启动按钮I0.0,得在程序监控界面里,右键I0.0的线圈位置,选“修改为1”或者“强制为1”,强制输入后,程序逻辑立刻就会作出响应。同理,停止按钮I0.1也要手动强制。这里要提醒一下:仿真器里强制IO很方便,但实际PLC上做强制操作一定要非常谨慎,强制错一个点,设备可能直接就动作了,轻则停机,重则伤人。

用仿真调试时,最有用的窗口是“监控表”。把MB20、QB0、M0.0、M0.1、M0.4这些关键变量拉到监控表里,点击“观察”图标,就能实时看到数据变化。特别是MB20,你会在屏幕上亲眼看到它从1变成2、4、8、16、32、64、128,然后跳回1,循环往复。那种感觉非常直观,程序到底有没有按逻辑跑,一目了然。

4.2 现场调试LED接线:注意源型漏型和公共端

如果你是在真实设备上跑这个程序,接LED灯时有一个很容易踩的坑:S7-1200直流输出点的接线方式。S7-1200大多数晶体管输出是源型输出,也就是输出端接通时,电流从模块流出到负载,所以负载要有公共端接到24V电源负极。具体到一套LED指示灯,你可以把LED的公共端接到PLC输出点的1L+和2L+上,输出点的0.0到0.7分别接LED的负极。通电后,Q点有输出时,Q点和M(电源负极)之间导通,LED点亮。

接线前一定要先确认PLC输出模块的类型。如果是继电器输出型,那公共端和接法跟晶体管型又有区别,通常是一个COM端接220V电源的火线,Q点出线到负载,负载另一头回零线。继电器输出可以直接驱动220V的指示灯,但如果是24V的LED,就要注意别把电压接错,烧了LED是小事,把PLC输出触点打坏了就得换模块了。

4.3 常见报错和异常现象速查表

在调试这个流水灯程序的过程中,有几种高频问题,我把现象和原因、解决办法整理成了一张表,方便对照:

异常现象可能原因排查与解决
按下启动灯完全不亮运行标志M0.0没置位检查I0.0接线或强制值,看监控表里M0.0是否为1
延时结束后灯不流动移位触发脉冲没生成监控M0.2,确认TON2是否在振荡;检查R_TRIG是否正常工作
灯亮了但跑着跑着全灭边界重装逻辑失效检查M20.7的上升沿检测是否写在了移位之后且重装值正确
灯从最高位后不回到起点重装初值被后续扫描覆盖确认MOVE指令把1写入MB20后,本周期不再执行SHL
两个灯同时亮移位指令的N参数不是1确认SHL的N端是常数1,不是2或更多
上电后延时没生效延时时间PT数值过小检查MD40的数值,默认5000ms,别误写成5
程序下载后CPU报错固件版本不匹配在项目树CPU上右键属性,更新固件版本或者换匹配固件
死活连不上PLCIP地址不在同网段确认PLC网线接到电脑网口,Ping通PLC IP,必要时恢复出厂设置

4.4 调通之后,几个值得做的扩展玩法

程序跑通之后,别急着收工。同一个核心逻辑,稍微改一改就有很多变种,我经常拿这个程序当“母版”给新人练手:

第一种:改方向。把SHL改成SHR(右移),灯就变成从右往左跑,注意边界判断要改成扫描M20.0(最低位),当它变1时把128写入MB20,这样8个灯就倒着循环了。

第二种:改速度。把TON2的PT时间从500ms改成200ms,灯就跑得快一些;改成2000ms,就跑得像乌龟爬。把这个PT参数接到一个模拟量输入的AIW值上,你还能用外部电位器无级调速,做成一个“速度感应流水灯”,也挺有意思的。

第三种:加花样。不只有一个1在跑,而是初始值设为3(二进制00000011),两个灯同时跑,产生“双灯流动”的效果;或者初始值设为129(10000001),变成两头灯往中间聚拢的效果。这一下就从“流水灯”进化到“跑马灯plus”了,逼格直接拉满。

第四种:扩展输出数量。S7-1200如果是16个灯,把数据容器从字节换成字(Word),变量类型改成MW20,移位指令换成SHL_W(字左移),边界判断改到M21.7(MW20最高位),输出映射改成MW20传送到QB0和QB1两个字节。核心逻辑一点不用变,熟悉这套操作后,以后做32路输出、64路输出,原理完全通用。

5. 经验总结与设计心得

程序拆解完了,回头聊点实在的心得。这个流水灯项目看似简单,但它几乎涵盖了PLC编程中最核心的几个概念:位变量与字节变量的关系、定时器的工作机制、边沿检测的应用、移位指令的边界处理、以及输出映射的思路。这几样东西,单独拎出来任何一个,都够新手琢磨好一阵。把它们串在一起做成一个能看、能摸、能跑的实际项目,学习效率远高于对着书本看概念。

我个人在实际调试中最大的体会是:写PLC程序,第一优先级永远是“可读性”和“可维护性”,其次才是“功能”。功能跑不通可以查、可以改,但如果变量名全是I0.0、M0.2这种“天书”,程序段堆在一起没有注释,那这个程序过三个月连你自己都看不懂,更别说后面接手的同事了。所以我在上面花了很大篇幅讲变量规划和程序段顺序,就是希望大家能养成一个好习惯:程序是给人看的,顺带让机器执行而已。

另外,调试这种带移位和边沿检测的程序,我最推荐的工具就是“监控表”。每次跑完一个循环,看一眼MB20和QB0的数据变化,如果和预期不符,立刻就能定位是哪一段逻辑出了问题。比拿万用表一支笔一支笔量输出点要高效得多。如果做仿真调试,强制IO前也要想清楚:强制的输入值不会被外部实际信号覆盖,忘了取消强制,后续程序可能一直保持在一个错误的状态,排查起来非常容易被误导。

最后再说一个小技巧:如果你是在真实设备上跑这个程序,记得给QB0的MOVE指令加上EN条件,只在“运行标志M0.0为真”且“延时完成标志M0.1为真”时才执行输出映射。否则会发生什么?上电瞬间,MB20虽然被OB100清零了,但QB0还是在MOVE指令的驱动下持续被写入0,虽然输出是灭的,但如果你外接的是继电器,继电器线圈相当于一直被吸合再释放,寿命会受影响。加一个EN使能,保证程序启动之前不碰输出,既安全又延长设备寿命。这一点,是很多教科书里不会写,但现场老师傅一定会叮嘱你的细节。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/19 13:58:28

计算机体系结构课后题解题核心:流水线与Cache性能分析

简介:计算机体系结构是计算机专业的核心课程,课后习题常涉及概念辨析、设计与计算,不少初学者苦于缺少可靠的答案参考。这份按章节整理的习题答案文档从第1章系统结构基本概念延伸到第9章机群,覆盖指令集结构分类、流水线技术、指…

作者头像 李华
网站建设 2026/9/19 13:57:26

从沟通自动采集到客户画像:DeskcommCRM系统设计与落地实践

1. 从"客户在微信里聊过什么"说起:为什么会有DeskcommCRM先说个真实场景。做B2B销售的人应该都有过这种经历——客户上午在IM上问了你一句报价,下午电话里又聊了另一个需求,第二天你觉得有些细节记不清了,只能回去翻聊天…

作者头像 李华
网站建设 2026/9/19 13:55:05

跨模态融合与增量预训练:油气储层参数解读的工程实践

简介:面向油气田勘探开发智能化转型的DeepSeek大模型应用资料,系统阐述基于跨模态融合、增量预训练实现储层参数高效解读的技术方案,适合算法工程师、地质数据研究人员及油田信息化建设人员阅读。压缩包共1个PDF文档,大小15MB&…

作者头像 李华
网站建设 2026/9/19 13:54:52

Win11Debloat 完整指南:一次勾选,精简 Windows 11 并关闭遥测

Win11Debloat 完整指南:一次勾选,精简 Windows 11 并关闭遥测 【免费下载链接】Win11Debloat A simple, lightweight PowerShell script that allows you to remove pre-installed apps, disable telemetry, as well as perform various other changes t…

作者头像 李华