S7-1200流水灯移位循环程序设计:梯形图实现上电延时与循环移位
2026/9/19 5:59:57 网站建设 项目流程

前些日子在设备现场调试一台小设备,客户提了个很典型的需求:一上电先别急着动作,等个三秒钟,然后指示灯依次点亮,像流水一样循环走起来。我下意识就想到了S7-1200的移位循环。这种需求在工控圈里太常见了,说白了就是流水灯效果,用PLC来做毫无难度,但真要写得漂亮、稳定、好扩展,还是有点门道。这篇文章就把我当时用梯形图实现的完整思路拆给大家看,核心就两个词:上电延时触发、移位循环。

无论你是刚摸PLC的新手,还是在用自复位定时器硬堆的老手,这篇内容都能给你点新东西。我会从方案选型一直讲到TIA Portal里的实操步骤,再附上几个我在现场真实踩过的坑。废话不多说,直接进入正题。

1. 项目整体拆解与方案选型

1.1 需求解析:龙师傅要的流水灯到底是什么效果

先把这个需求翻译成PLC能听懂的"人话"。所谓流水灯效果,就是多个指示灯按固定顺序依次点亮和熄灭,形成一种光带流动的视觉感受。常见的工业场景包括设备运行状态指示、故障报警光带、生产线工序进度显示等。这次客户的具体要求是:设备上电后先保持全灭状态,延时约3秒,然后从第1个灯开始点亮,每隔固定时间间隔(比如1秒)向后移动一位,走到最后一个灯后折返或循环,周而复始。

拆解成PLC的控制逻辑,就是三件事:一是上电延时,用定时器实现;二是产生固定频率的移位脉冲,让数据移动有节奏;三是数据本身的移动方式,也就是移位循环。很多人一上来就想着搞一堆定时器串联,比如T1延时1秒置位Q0.0,T2延时2秒置位Q0.1……这思路没错,但只适用于灯数少且逻辑永远不变的场合。一旦要改速度、改顺序、加灯数,代码改到你怀疑人生。我这次直接选择了移位寄存器方案,用一个"1"数据位在寄存器里不断移动,灯的亮灭状态完全由这一位数据的位置决定,逻辑和硬件绑定关系降到最低。

这种设计的好处在于:状态集中、扫描周期一致、扩展性好。8个灯和16个灯的区别,只是数据宽度不同,程序框架几乎不用动。你想想,这要是用一堆定时器堆,16个灯就得16套定时器加16套互锁逻辑,哪个方案省事,不言而喻。

1.2 方案对比:移位循环为什么比"定时器堆叠"更靠谱

我遇到过不少电工师傅,做流水灯第一反应就是定时器堆叠。我承认,对于三五组灯的小型控制,堆定时器确实直观,一个定时器Q端触发一个灯,后面再串联下一个定时器。但这里有几个硬伤:第一,定时器本身有数量限制,S7-1200虽然定时器资源比老款S7-200充裕,但也不能无限用下去;第二,每个定时器的PT值都是独立设置的,想整体调速就得一个个改,不小心漏改一个,流水节奏就乱了;第三,定时器堆叠本质上是"链式触发",一个环节的定时器复位逻辑稍有瑕疵,整条链就断了,排查起来非常痛苦。

移位循环的逻辑完全绕开了这些麻烦。它的核心思路是:准备一个数据容器(寄存器),让一个"1"在里面按固定节拍移动。数据每次移动一拍,灯就跟着跳一位。为什么这个方案优雅?因为"亮哪个灯"完全由数据位置决定,修改灯序只是改数据移动方向或输出映射,修改速度只改节拍脉冲的周期。而且,这种思路的工程化价值远不止流水灯:顺序启动多台电机、多工位装配线的流转、信号灯的相序切换,本质都是移位循环。

从扫描周期的角度看,移位循环是"并行"的状态刷新,所有输出在同一个扫描周期内统一更新;定时器堆叠则是"串行"触发,容易出现一个周期内多个灯同时闪烁的鬼影。做控制的人都知道,状态切换不一致是现场调试的大忌,尤其是带接触器、带变频器的场合,前后几个周期输出不一致,轻则指示灯乱跳,重则设备误动作。

2. 核心指令与梯形图设计原理

2.1 上电延时触发的实现:TON定时器的正确用法

S7-1200的定时器是IEC风格的"实例化"定时器,和S7-200那种"定时器编号"的写法完全两个思路。你在编程过程中使用TON指令时,系统会提示创建一个定时器实例,这个实例可以放在数据块(DB)中,也可以放在函数块(FB)的背景数据块中。很多刚接触TIA Portal的人会被这个特性和以前写三菱的习惯搞混——别慌,道理其实一样。

TON的全称是On-Delay Timer,接通延时定时器。它的逻辑很简单:IN端从0变成1后,定时器开始计时,当前时间ET从0往PT方向累加;当ET累计到PT设定值,Q端输出置1。关键点在于:只要IN端还维持1,Q端就一直保持1;只有IN端断开,ET才会清零,Q端才会复位。这意味着TON本身不是"脉冲发生器",它只是一个"可复位的延时开关"。

实现"上电延时触发"有两种常见接法。第一种是把一个常真信号(比如系统常量TRUE或一个启动位)接到TON的IN端,这样程序一运行,定时器就开始计时,3秒后Q端置1。第二种是接一个启动按钮信号,比如I0.0按下才开始计时,适合需要人为介入的场合。我这次用第一种,因为客户要的就是"上电自动延时启动"。

这里要提醒一点:TON的Q端置1后不能直接用来触发移位,否则PLC每个扫描周期都会执行一次移位,程序一运行数据瞬间就移完了,根本看不出流水效果。正确的做法是把TON的Q端当作"总使能",再配合一个节拍脉冲信号去做"边沿触发"。这个组合是整套程序的关键环节,理解了它,后面的移位逻辑就顺理成章了。

2.2 移位循环的核心:S7-1200的移位指令与循环控制

S7-1200在TIA Portal里提供的移位指令主要分两类:逻辑移位(SHL/SHR)和循环移位(ROL/ROR)。逻辑移位是"挤出去就扔了",数据移出最高位或最低位后直接丢弃,另一端补0;循环移位则是"从一端挤出去又从另一端塞回来",像一个环形跑道,数据永远在寄存器里打转。

流水灯用哪种?答案是循环移位,也就是ROL或ROR。原因很简单:流水灯要求最后一个灯亮完以后,下一步回到第一个灯重新开始,正好对应循环移位的"环形"特性。用逻辑移位反而麻烦,你还得额外写补位逻辑,把溢出的位手动加到另一端,多此一举。

具体到指令操作数,S7-1200支持对整数、双整数和位序列执行移位。对于8个灯的情况,一个BYTE(8位)刚刚好;16个灯就用WORD(16位);32个灯用DWORD。以8路流水灯为例,我定义一个BYTE类型的变量ShiftValue,初始值设为B#16#01,也就是二进制0000_0001,代表第1个灯先亮。每次执行ROL(循环左移)1位,数据就变成0000_0010,第2个灯亮,以此类推。移到1000_0000后,再左移一位就变回0000_0001,循环闭合。

如果你手头恰好没有ROL指令,或者习惯用逻辑移位,也能实现循环效果,就是多两条补位逻辑:先把最高位(或最低位)保存到一个临时变量,执行SHL(或SHR),再把临时变量补到另一端。我早年用S7-200做类似功能时就是这么干的,因为S7-200没有现成的8位循环左移指令,只能靠SHB指令加手工补位。现在S7-1200直接提供ROL/ROR,省事多了。

3. 实操过程:TIA Portal中的完整编程步骤

3.1 建立项目与变量表:先把"场地"码好

这次演示我用的软件是TIA Portal V16,CPU型号选的是CPU 1214C DC/DC/DC,订货号6ES7214-1AG40-0XB0,这个型号在中小型设备里很常用。建项目的步骤我就不啰嗦了,重点说变量和存储区的规划。

S7-1200没有三菱那种"字元件"和"位元件"完全分开的概念,它强调数据类型。建议把流水灯相关的核心变量放在一个独立的全局数据块里,我习惯命名为DB_FlowWater。这个数据块里至少要有这几个变量:ShiftValue(BYTE),存放当前的灯状态数据;ShiftEnable(BOOL),上电延时完成的使能信号;PulseEdge(BOOL),节拍脉冲的边沿存储位;SecondsFlag(BOOL),循环过程中用到的标志位。变量建好以后,每个变量都有一个绝对地址,比如DB_FlowWater.ShiftValue,在梯形图里可以直接引用。

还有一个关键配置:时钟存储字节。这是S7-1200很方便的一个功能,说白了就是系统自动生成一组固定频率的脉冲信号,你可以直接拿来用,不用自己写定时器产生方波。在CPU属性里找到"系统和时钟存储器",勾选"启用时钟存储器字节",然后指定一个字节地址,比如MB1。这样M1.0到M1.7就分别对应不同的频率:0.5Hz、1Hz、2Hz、5Hz、10Hz等等。我做1秒一步的流水灯,就用M1.5(1Hz脉冲)。这个配置经常被人忽略,但你一旦用上,就会发现很多需要"闪烁"的场景都可以靠它解决,连定时器都省了。

3.2 梯形图逐行拆解:从首扫描到循环脉冲

程序结构我用四个网络(Network)搞定,逻辑非常清爽。

第一个网络做上电延时。Network 1里放一个常真触点(在TIA里可以用"TRUE"系统常量),接到TON定时器的IN端。定时器实例我命名为"DelayTimer",PT设为T#3S。TON的Q端输出到DB_FlowWater.ShiftEnable。这样PLC运行后,3秒内ShiftEnable为0,所有输出保持熄灭;3秒后ShiftEnable变为1,流水逻辑开始工作。

第二个网络做节拍脉冲边沿检测。这里的关键是:虽然时钟存储字节M1.5本身已经是1Hz方波,但我们不能直接用它的电平状态去触发移位,否则在方波高电平的这段时间里,每个扫描周期都会移一次。必须把方波通过一个上升沿检测(R_TRIG)转换成一个"瞬间脉冲"。我在网络2里串联三个触点:ShiftEnable、M1.5,然后接R_TRIG。R_TRIG的CLK端接M1.5,Q端输出到PulseEdge。这样当ShiftEnable为1、且M1.5出现上升沿的那一刻,PulseEdge只会导通一个扫描周期,正好作为移位的触发信号。

第三个网络执行移位。ROL指令要设置三个参数:EN使能端接PulseEdge,IN端接ShiftValue,N端设1(每次移动1位),OUT端还是接到ShiftValue。这里有个知识点:ROL的输出不能直接接到输入上,需要用一个MOVE或者通过中间变量回写。实际上TIA里用指令的INOUT接线方式也可以,但为了新手看得清楚,我在IN端接ShiftValue,OUT端输出到一个同等类型的中间变量,再用MOVE把它赋值回ShiftValue。虽然多了一步,但数据流转一目了然,排查问题也方便。

第四个网络做输出映射。我用MOVE指令,把ShiftValue传送到QB0。这里有个细节:如果ShiftValue是BYTE类型,QB0也是字节地址,两者类型匹配,直接传就行。如果用的是WORD类型,想输出到QB0就需要取低字节或高字节,我建议不要搞这么麻烦,8路流水灯直接用BYTE。接线的时候,Q0.0到Q0.7分别接8个指示灯,注意晶体管输出和继电器输出的区别,详见后面的硬件注意事项。

3.3 扩展技巧:速度可调流水灯与方向切换

程序跑通以后,客户往往会提两个额外的要求:速度能不能调?方向能不能反过来?我在这次项目里也遇到了,一并说下我的做法。

调速最简单的方式是修改TON的PT值。但如果你不想改程序,想在触摸屏或面板上直接调,可以把PT改成变量,比如DB_FlowWater.DelayTime,类型为TIME。面板上输入1.5,延时就是1.5秒。需要注意的是,如果PT值在运行中被改成小于ET当前值的数,定时器Q会立即置位,这可能引起跳变,所以实际应用中我会限制可调范围,比如限到3秒到10秒之间。

方向切换也很直观。用ROL指令是左移,灯从Q0.0往Q0.7方向跑;换成ROR指令就是右移,方向反过来了。如果你想实现"碰壁反弹",就是走到头再折返回去,那就不能单纯用循环移位了,得换成逻辑移位,同时判断最高位和最低位的状态,切换移位方向。我在另一个设备上做过类似"来回扫描"的效果,原理就是在移位的瞬间检查ShiftValue等于128还是1,然后动态修改IN方向的指令。说白了,移位指令本身没有记忆能力,方向要靠程序逻辑去维持。

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

4.1 现象一:上电后灯全亮,没有流水效果

这个故障我见得太多了,十有八九是移位使能逻辑出了问题。最典型的情况是:TON的Q端直接接到了ROL的EN端,而不是通过边沿触发。这样一来,上电延时完成后,每个扫描周期ROL都在执行,数据哗哗地移,CPU一眨眼完成了几百上千次移位,最终停在某个状态上。因为移位速度远快于视觉分辨,你看到的要么是全亮,要么是某个灯常亮,完全没有流动感。

解决办法是把ROL的EN端接在"边沿脉冲"后面,而不是接在TON的Q上。另外还要检查一下ShiftValue的初始值。如果初始值是0,那哪怕移位一万次,数据还是0,灯自然是全灭;如果初始值被写成255(全1),那移位时每个位都是1,灯就会表现出全亮或奇怪的跳变。合理的初始值就是B#16#01,代表第一个灯先亮。

4.2 现象二:移位一次后不再动作

这个现象通常是R_TRIG的边沿检测没有持续触发。R_TRIG这个指令的特性是:它内部会记住CLK端上一次的"旧状态",只有当前状态为1且上一次状态为0(也就是存在上升沿)时,Q才输出一个扫描周期的1。如果CLK端一直是1,或者一直是0,它都不会输出。

我遇到过的实际情况是:有人把M1.5(时钟脉冲)接到了R_TRIG的CLK端,但忘了勾选"启用时钟存储器字节",导致M1.5永远是0,边沿检测永远不触发。第一种表现就是上电后第一次延时完成,TON的Q置1的那一刻,可能因为某些巧合让R_TRIG误触发了一次,于是只亮了第一个灯,之后就彻底卡住。排查方法很直接:在监控表里强制监控M1.5,看它是否有规律地跳变;再监控PulseEdge,看它是否每个周期都闪一次。如果M1.5不动,就去CPU属性里勾选时钟存储器字节;如果M1.5在跳但PulseEdge不动,检查R_TRIG的实例变量是否重复使用或未正确关联。

4.3 现象三:脉冲时间不准确,灯走得忽快忽慢

流水灯的速度取决于移位脉冲的频率。用时钟存储字节时,不同地址对应的频率是固定的,但很多人会记错。我常用的几个:M1.0是0.5Hz(2秒周期),M1.1是1Hz(1秒周期),M1.2是2Hz(0.5秒周期),M1.3是4Hz,M1.4是8Hz,M1.5是16Hz?不对,这里得说清楚。

实际上S7-1200时钟存储字节的频率分配是这样的:字节地址的最后一位(如M1.0)是0.5Hz,往上是1Hz、2Hz、4Hz、8Hz、16Hz、32Hz、64Hz?不同固件版本可能有微调,必须在软件里看提示。我在V16里勾选后,系统会弹出一个小窗口,显示每一位对应的频率,照着选就行,千万别凭记忆硬背。如果你需要不标准的频率,比如0.8Hz,那时钟存储字节满足不了,就得自己写一个周期脉冲发生器,用TON或TP定时器组合。

还有一种"忽快忽慢"的错觉,其实是扫描周期和输出刷新周期叠加造成的。如果程序段里有大量其他逻辑,CPU扫描周期可能出现波动,导致定时器精度受影响。S7-1200的扫描周期一般在毫秒级,对流水灯这种秒级应用影响不大,但如果追求极致的稳定,建议把流水灯逻辑单独放到一个循环中断OB里,比如OB30,设定固定的中断周期(如100ms),在中断块里做移位处理。这样无论主程序扫描周期怎么波动,移位节奏始终稳定。

4.4 排错思路总结与硬件接线要点

排错这件事,我一贯的做法是"先软后硬、先内后外"。软件上,用TIA Portal的监控功能,在梯形图里实时看TON的ET有没有累加、ROL的IN和OUT数据对不对、QB0的值和实际灯状态是否一致。只要把这几个点的状态捋清楚,问题基本能定位到具体某一行。如果监控表里看到QB0的值在按1、2、4、8、16、32、64、128的顺序变化,但灯没有亮,那问题十有八九出在硬件。

硬件方面有几点容易踩雷。第一,确认CPU型号是晶体管输出还是继电器输出,这会直接影响外部接线方式。S7-1200晶体管输出一般是源型输出(高电平有效),公共端接电源负极,负载一端接输出端子、另一端通过限流电阻接24V;而继电器输出的公共端相当于一个开关触点,极性相对灵活,但带载能力较弱。第二,LED指示灯必须串接限流电阻,S7-1200输出点允许的电流虽然够带小功率指示灯,但LED本身的伏安特性决定了它需要限流,否则一上去就烧。一般24V电源串一个2.2kΩ左右的电阻,具体看LED额定电流计算。第三,检查输出通道的公共端是否接线牢固,很多"某一路灯不亮"的怪故障,其实就是公共端端子松了。

如果你暂时没有实物硬件,可以用TIA Portal自带的PLCSIM仿真软件在电脑上跑这个程序。仿真状态下,QB0的值变化一样能看得清清楚楚,唯一注意PLCSIM对时钟存储字节的支持需要勾选对应选件,否则M1.5不会翻转。我在仿真环境里调试通过以后,再下载到实物PLC,整个流程顺畅很多。

5. 从流水灯到工程应用:我的几点体会

5.1 移位循环在顺序控制中的真实价值

流水灯看似是个练手小项目,但移位循环的思想在工业控制里随处可见。举个我做过的事:一条生产线有5台风机,要求按顺序间隔5秒启动,停机时反过来按顺序停。用移位循环做,就是把风机启动信号依次排列在一个寄存器里,一个定时脉冲触发一次移位,每移到哪一位就启动对应的风机;停机时换个方向移位,顺起逆停一次到位,程序清爽、逻辑直观。热搜词里那些"多台变频器通讯控制""星三角降压启动"之类的内容,本质上也是顺序控制的一种变形,只是把"灯"换成了"接触器"或"变频器启动命令"。

所以我的建议是:别把流水灯当成一个玩具,它其实是"状态机"和"步进控制"的最简模型。你把它吃透了,再去接触顺序功能图(SFC/GRRAPH)、状态机编程甚至复杂运动控制里的"循环移位找原点",会有一种融会贯通的感觉。

5.2 梯形图还是SCL:按场景选,别迷信

这次程序我用梯形图写,原因是客户阵营里有人后续要维护梯形图,直观易读。但如果是我自己写新项目,这种纯数据处理逻辑用SCL其实更短:用一行"ShiftValue := ROL(IN := ShiftValue, N := 1)"就完成了移位,配合IF语句判断使能和边沿,代码量比梯形图少一半。这不代表梯形图不如SCL,而是两者擅长领域不同。梯形图更适合"触点-线圈"逻辑、硬件联锁控制,SCL更适合算法、数据处理和复杂数学运算。真正的高手不会纠结哪个语言"高级",而是看哪个语言能把问题描述得最简洁、最不容易出错。

我个人现在的做法是:主程序负责顺序控制和联锁,用梯形图;数据运算和通讯解析丢给SCL函数块;顺控流程如果步骤多,直接用GRRAPH。这次流水灯只是个小例子,但它让我又复习了一遍R_TRIG、TON、ROL这几个高频指令的配合方式,也再次验证了"先想清楚数据结构,再动手写程序"这句话的价值。你把这个程序在电脑上敲一遍、仿真一遍,再用实物跑一遍,相信我,你对S7-1200的定时器、脉冲边沿和数据移位的理解会往上走一个台阶。

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

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

立即咨询