2026/10/16 1:03:14

S7-1200/1500博途定时器操作详解:IEC与SIMATIC区别及四种类型选型

S7-1200/1500博途定时器操作详解:IEC与SIMATIC区别及四种类型选型 1. 从一次产线停机说起为什么定时器操作值得单独拎出来讲前阵子帮一个做包装机械的朋友处理故障设备在客户现场跑了三个月突然停机触摸屏上报“运行超时”。到现场一看程序里一个用于检测物料到位的延时判断逻辑用的是S7-1200的TON指令设定值写的是T#5S但实际物料偶尔会卡顿到6秒才到位于是每次卡顿都触发报警停机。问题本身不复杂但排查过程中我发现现场维护人员对S7-1200和S7-1500定时器的理解基本停留在“拖一个TON块、填个时间、输出接个线圈”的水平至于定时器实例放在哪儿、时间基准怎么算、不同定时器类型之间到底差在哪几乎没人说得清。这件事让我意识到定时器操作虽然看起来是PLC编程里最基础的东西但恰恰因为太基础很多人从入门到独立做项目都没真正把它吃透。S7-1200和S7-1500作为当前中小型自动化项目里出场率极高的两款控制器它们的定时器指令在博途TIA Portal环境下的用法有相通之处也有不少容易混淆的细节。这篇文章就围绕这两款PLC的定时器操作展开把IEC定时器和SIMATIC定时器的区别、四种定时器类型TON、TOF、TP、TONR的适用场景、实例化方式的选择、时间设定值的写法、以及实际项目中容易踩的坑一条一条讲清楚。不管你是刚接触博途的新手还是已经做过几个项目但定时器用得比较随意的老手下面这些内容应该都能帮你把这块知识补扎实。文章里涉及的操作步骤和参数说明都是基于博途V15及以上版本的常见实践不同版本界面可能略有差异但核心逻辑一致。2. 先搞清楚你用的是哪套定时器体系2.1 IEC定时器与SIMATIC定时器的本质区别在博途里给S7-1200或S7-1500写程序你打开指令树在“基本指令”下面会看到两个跟定时器相关的文件夹一个是“定时器操作”里面放的是TON、TOF、TP、TONR、RTM这些另一个是“扩展指令”里的“日期和时间”里面有一些跟系统时间相关的指令。很多人没注意到的是S7-1200和S7-1500其实支持两套定时器体系一套叫IEC定时器一套叫SIMATIC定时器。IEC定时器是符合国际电工委员会标准的它的特点是定时器实例需要你自己分配一个背景数据块DB或者用多重背景的方式放在某个FB的静态变量里。SIMATIC定时器则是西门子传统的那套在S7-300/400时代用的是S5定时器到了S7-1200/1500时代SIMATIC定时器实际上是通过系统函数块来实现的比如S_PULSE、S_ODT这些。但在博途里S7-1200和S7-1500默认推荐使用的是IEC定时器因为它的行为更可预测移植性更好。这里有个关键点S7-1200的IEC定时器数量是有限的。具体来说S7-1200最多支持16个IEC定时器实例不同固件版本可能有差异但大体在这个量级而S7-1500的IEC定时器数量只受限于CPU的工作内存大小理论上可以创建非常多。这个差异在小型项目里可能感觉不到但如果你在一个S7-1200项目里大量使用定时器就要留意资源上限。2.2 为什么博途里拖出来的定时器都带个DB块第一次在博途里用TON指令的人大概率会遇到这样一个场景从指令树里把TON拖到程序段里系统弹出一个对话框让你填写“背景数据块”的名称比如默认的“IEC_Timer_0_DB”。如果你不手动改它就自动生成一个DB块。很多人图省事直接点确定结果程序里散落着几十个IEC_Timer_x_DB后期维护的时候根本不知道哪个定时器是干什么用的。这个背景数据块的作用是存储定时器的运行状态包括当前计时值、启动信号、输出状态等。IEC定时器不是靠CPU内部的某个固定资源来实现的而是靠这个DB块里的数据来维持状态。所以每个定时器实例必须有一个独立的DB不能两个TON共用一个DB否则状态会互相覆盖。那有没有办法不生成这么多DB块有就是用多重背景。如果你把定时器指令放在一个FB函数块里面并且把这个定时器实例声明为该FB的静态变量那么它就不会生成独立的DB而是作为FB背景DB的一部分存在。这种方式在写标准化程序的时候特别有用比如你写一个电机控制FB里面用到一个延时启动定时器就可以把它做成多重背景实例这样每个电机调用这个FB时定时器状态自动跟着走不会互相干扰。2.3 S7-1200和S7-1500在定时器资源上的实际差异前面提到S7-1200的IEC定时器数量有限这里展开说一下实际影响。S7-1200的CPU型号不同支持的IEC定时器数量也不一样。比如1211C、1212C这些入门型号IEC定时器实例数量比较少具体数字可以在CPU的技术数据里查到。而S7-1500就没有这个硬性限制只要内存够你可以创建大量定时器。这个差异带来的实际问题是如果你在S7-1200项目里用了很多定时器而且每个都生成独立DB很快就会遇到“无法创建更多定时器实例”的报错。解决办法有两个一是尽量用多重背景把定时器塞进FB的静态变量里二是检查是否有冗余的定时器可以合并比如多个地方用到的相同延时逻辑能不能用一个定时器加一些逻辑判断来复用。另外S7-1200和S7-1500的定时器时间基准也不完全一样。IEC定时器的时间基准是1毫秒也就是说定时器的分辨率是1ms。但实际精度受CPU扫描周期影响如果你设一个T#10MS的定时器而扫描周期是15ms那这个定时器实际触发的时间可能会在10ms到25ms之间波动。这一点在做高精度时序控制的时候要特别注意。3. 四种定时器类型到底该怎么选3.1 TON最常用的接通延时但有个细节容易忽略TON是接通延时定时器也是实际项目里用得最多的一种。它的逻辑很简单当IN输入为TRUE时开始计时计时达到PT设定的时间后Q输出变为TRUE当IN变为FALSE时计时器复位Q输出变回FALSE。看起来没什么好说的但有一个细节很多人没注意TON的IN输入如果只接通一个扫描周期定时器会不会开始计时答案是会但只会计时一个扫描周期的时间然后因为IN变回FALSE定时器立刻复位。所以如果你用按钮点动来触发一个延时按钮按下的时间必须长于定时器的设定时间否则定时器永远达不到设定值。实际项目中TON最常见的用法是延时启动。比如一台风机按下启动按钮后先让润滑油泵运行5秒再启动风机主电机。这时候就用一个TONIN接启动按钮PT设T#5SQ输出接风机主电机的启动条件。但要注意如果启动按钮是点动式的按一下松开那TON的IN就断了定时器复位风机永远启动不了。所以这种情况下启动按钮应该先置位一个中间变量用这个中间变量去驱动TON的IN。3.2 TOF断电延时用在什么场景才合理TOF是断开延时定时器逻辑跟TON正好反过来当IN为TRUE时Q输出立即为TRUE当IN变为FALSE时开始计时计时达到PT后Q输出变为FALSE。如果计时过程中IN又变回TRUE计时器复位Q保持TRUE。TOF的典型应用场景是冷却风扇控制。比如一台设备停机后主电机断电但冷却风扇需要继续运行一段时间把热量排出去。这时候就可以用TOFIN接主电机的运行信号PT设T#3MQ输出接冷却风扇。主电机运行时风扇跟着转主电机停后风扇再转3分钟自动停。但TOF有一个容易踩的坑如果设备频繁启停每次IN变FALSE都重新计时风扇就一直停不下来。所以如果你的设备启停很频繁用TOF控制风扇可能不是最佳方案可以考虑用TON加一些逻辑来实现“停机后至少运行3分钟但两次停机间隔小于3分钟时不重复计时”的逻辑。3.3 TP脉冲定时器输出固定宽度的脉冲TP是脉冲定时器它的行为是当IN从FALSE变为TRUE的上升沿Q输出变为TRUE并保持PT设定的时间然后自动变回FALSE。在Q为TRUE期间即使IN再次变为FALSE再变TRUEQ也不会重新触发必须等Q变回FALSE之后新的上升沿才能再次触发。TP的典型用途是给一个固定宽度的脉冲信号。比如某个阀门需要给一个2秒的脉冲信号才能打开就可以用TPPT设T#2SIN接触发按钮Q输出接阀门线圈。这样不管按钮按多久阀门线圈只通电2秒。这里要注意的是TP的IN如果一直保持TRUEQ在脉冲结束后不会再次触发。只有IN先变FALSE再变TRUE产生新的上升沿才会再次输出脉冲。所以如果你用TP做周期性脉冲输出需要配合一个周期性的触发信号比如用一个时钟存储器位来驱动IN。3.4 TONR累积延时适合统计设备运行时间TONR是保持型接通延时定时器跟TON的区别在于当IN变为FALSE时TONR的当前计时值会保留不会复位下次IN再变为TRUE时从上次的值继续累加。只有用RTM复位定时器指令才能把TONR的当前值清零。TONR的典型应用是设备运行时间统计。比如你想统计一台电机累计运行了多少小时就可以用TONRIN接电机运行信号PT设一个很大的值比如T#24HQ输出接一个计数器或者直接用来触发维护提醒。电机每次运行TONR就累加时间停机后时间保留下次运行继续累加。但TONR有一个使用上的限制它的当前值在博途里可以通过指令读取但如果你需要把累计时间显示在触摸屏上需要把当前值转换成合适的数据类型。TONR的ET已过时间输出是Time类型可以直接用但如果要显示成“XX小时XX分钟”的格式就需要自己写转换逻辑。3.5 四种定时器的对比与选型建议为了更直观地对比四种定时器的行为差异下面用一个表格来总结定时器类型触发条件输出行为复位条件典型应用TONIN上升沿开始计时计时到PT后Q为TRUEIN变FALSE延时启动、延时报警TOFIN为TRUE时Q为TRUEIN变FALSE后计时到时Q为FALSEIN变TRUE停机后延时关闭TPIN上升沿触发Q输出固定宽度脉冲脉冲结束自动复位固定脉冲输出TONRIN为TRUE时累加计时计时到PT后Q为TRUE需RTM指令复位累计运行时间统计选型的时候先问自己一个问题我需要的是“延时后做什么”还是“停止后继续做什么”还是“给一个固定脉冲”还是“累计时间”。把这四个需求对应到四种定时器上基本就不会选错。4. 时间设定值的写法与常见错误4.1 T#5S、T#500MS、T#1H30M这些写法到底怎么用博途里定时器的时间设定值PT用的是Time数据类型写法是T#开头后面跟时间值和单位。常见单位有MS毫秒、S秒、M分钟、H小时、D天。可以组合使用比如T#1H30M表示1小时30分钟T#2D10H表示2天10小时。这里有一个新手容易犯的错误把PT的值写成整数比如直接写5000以为代表5000毫秒。实际上PT需要的是Time类型如果你在PT引脚上直接输入一个整数博途会报类型不匹配的错误。正确的做法是写T#5000MS或者T#5S。另外Time类型的取值范围是T#-24D20H31M23S648MS到T#24D20H31M23S647MS超出这个范围会报错。对于大多数应用场景这个范围足够用了但如果你要做超长时间的累计比如统计设备运行几个月的时间TONR的PT设成最大值也只能到24天左右这时候就需要用其他方式来实现比如用计数器累加TONR的Q输出。4.2 用变量作为时间设定值的正确姿势实际项目中定时器的设定值经常需要从触摸屏上修改这时候PT就不能写死一个常量而要用变量。但这里有一个关键点PT引脚需要的是Time类型的变量而触摸屏上输入的通常是整数比如输入5代表5秒。所以你需要做类型转换。常见的做法是在DB块里定义一个Time类型的变量比如“延时设定值”然后在触摸屏上用一个I/O域关联这个变量但I/O域的数据类型要选Time。有些触摸屏软件支持直接输入Time类型格式是“T#5S”或者“5S”。如果触摸屏不支持Time类型输入那就定义一个Int或DInt变量然后在PLC程序里用转换指令把它转成Time。转换的方法是如果触摸屏输入的是秒数整数可以用“Int_to_Time”或者“DInt_to_Time”指令但要注意单位。博途里的Time类型底层是以毫秒为单位的DInt所以如果你输入5代表5秒需要先乘以1000再转成Time。或者用“TIME_TCK”之类的指令来构造Time值。更简单的办法是直接用“T#”加变量的方式但博途不支持这种写法所以还是得走转换这条路。4.3 时间基准与扫描周期的关系前面提到IEC定时器的时间基准是1ms但实际计时精度受扫描周期影响。举个例子你设了一个T#10MS的TON但CPU的扫描周期是15ms。第一个扫描周期IN变为TRUE定时器开始计时第二个扫描周期定时器检查当前时间发现已经过了15ms超过了10ms的设定值于是Q输出变为TRUE。所以这个定时器实际触发的时间是15ms而不是10ms。这个误差在大多数应用里可以忽略但如果你做的是高速计数、精确定位之类的应用就不能依赖定时器来做精确时序控制而应该用硬件中断或者高速计数器来实现。另外S7-1200和S7-1500的定时器在扫描周期中的更新时机也略有不同。S7-1500的定时器更新更及时因为它有更快的处理能力。但不管哪款PLC定时器的精度都不可能超过扫描周期的限制。5. 实例化方式的选择独立DB还是多重背景5.1 独立DB方式的优缺点独立DB方式就是每个定时器指令都生成一个独立的背景数据块。这种方式的优点是简单直接拖出来就能用不需要考虑FB的封装。缺点是DB块数量会随着定时器数量增加而膨胀程序结构看起来比较散。在小型项目里独立DB方式完全够用而且调试的时候比较方便因为每个定时器的状态都在独立的DB里在线监控的时候一眼就能看到。但在中大型项目里如果定时器数量很多独立DB会让程序结构变得混乱而且S7-1200还有定时器数量限制所以这时候就要考虑多重背景。5.2 多重背景的创建步骤与注意事项多重背景的核心思路是把定时器指令放在一个FB里然后把定时器实例声明为该FB的静态变量。具体操作步骤是新建一个FB比如叫“FB_延时控制”。在FB的接口区找到“Static”栏新建一个变量数据类型填“TON”或者“IEC_TIMER”。在FB的程序段里从指令树拖一个TON指令进来当弹出背景数据块对话框时不要新建DB而是点击“多重背景”按钮选择刚才定义的静态变量。这样这个TON就绑定到了FB的静态变量上不会生成独立的DB。用这种方式每个调用FB的地方都会自动分配一份独立的定时器状态互不干扰。而且FB的背景DB里包含了定时器的所有状态程序结构非常清晰。但要注意一点多重背景的定时器在在线监控的时候需要进入FB的背景DB才能看到定时器的状态不像独立DB那样直接就能监控。所以调试的时候可能稍微麻烦一点但习惯之后就好了。5.3 什么时候该用哪种方式我的经验是如果项目规模不大定时器数量在10个以内而且逻辑比较分散用独立DB方式没问题调试方便。如果项目规模较大或者你打算把程序做成标准化模块那就用多重背景方式把定时器封装在FB里。另外如果你用的是S7-1200而且定时器数量接近上限那必须用多重背景来节省资源。S7-1500虽然资源充足但从程序结构清晰的角度考虑也推荐用多重背景。6. 实际项目中容易踩的坑与排查思路6.1 定时器不动作的几种常见原因定时器不动作是实际项目里最常遇到的问题。根据我的经验原因通常有这几种第一种IN条件不满足。比如你写了一个TONIN接的是某个按钮的常开触点但按钮是点动式的按一下松开IN只接通一个扫描周期定时器还没计时到就复位了。解决办法是用按钮的上升沿置位一个中间变量用中间变量驱动IN。第二种PT设定值格式不对。比如PT写成了整数5000而不是T#5000MS博途会报类型错误但有些人忽略了报错强行下载结果定时器行为异常。第三种定时器实例冲突。比如两个TON共用了同一个背景DB导致状态互相覆盖。这种情况在复制粘贴程序段的时候特别容易发生因为复制的时候如果选择了“复制DB”可能会生成重复的DB引用。第四种定时器所在的程序段没有被调用。比如你把定时器放在一个FC里但这个FC在OB1里没有被调用那定时器永远不会执行。6.2 定时器时间不准的排查方法定时器时间不准通常不是定时器本身的问题而是扫描周期或者程序结构的问题。排查的时候可以按这个思路走先看扫描周期。在博途里可以在线查看CPU的扫描周期如果扫描周期接近或超过定时器的设定值那定时精度肯定受影响。这时候要么优化程序减少扫描周期要么改用硬件中断。再看定时器的更新时机。IEC定时器是在每个扫描周期开始时更新的如果你在程序里先读定时器的Q输出再执行定时器指令那读到的Q值是上一个扫描周期的状态。所以定时器指令应该放在使用它的逻辑之前。最后看是否有其他逻辑干扰。比如定时器的IN条件被其他程序段修改了或者定时器的背景DB被其他程序段写入了。这种情况比较隐蔽需要仔细检查交叉引用。6.3 定时器在OB块中的行为差异S7-1200和S7-1500支持多种OB块比如主程序OB1、循环中断OB30、启动OB100等。定时器在不同OB块中的行为是有差异的。如果定时器放在OB1里它的计时精度受OB1扫描周期影响。如果放在循环中断OB里比如OB30设了10ms的循环中断那定时器的计时精度就受这个10ms中断周期影响但比OB1要稳定得多。但要注意循环中断OB里不能放太多逻辑否则会影响中断的响应时间。而且循环中断OB里的定时器如果中断周期和定时器设定值有倍数关系可能会出现计时偏差累积的问题。启动OB100里一般不放定时器因为启动OB只执行一次定时器在里面没有意义。6.4 在线修改定时器设定值的注意事项在设备运行过程中有时候需要在线修改定时器的设定值。博途支持在线修改但有几个注意事项第一如果你修改的是PT引脚的常量值需要重新下载程序块这会导致CPU停机除非是S7-1500的某些型号支持运行中下载。所以更好的做法是把PT设成一个变量通过触摸屏或HMI来修改这样不需要停机。第二如果你修改的是定时器背景DB里的当前值比如强制修改ET值这可能会导致定时器行为异常不建议这么做。第三在线修改后定时器的当前计时值不会自动重置而是从当前值继续计时。如果你希望修改后重新计时需要先复位定时器。7. 几个实战场景的定时器方案拆解7.1 电机星三角启动的定时器逻辑星三角启动是定时器最经典的应用场景之一。逻辑是按下启动按钮主接触器和星形接触器同时吸合电机以星形方式启动延时一段时间后星形接触器断开三角形接触器吸合电机转入三角形运行。这个逻辑里用到一个TONIN接启动信号PT设T#5S根据电机功率和负载情况调整Q输出用来切换星形和三角形接触器。但要注意星形接触器断开和三角形接触器吸合之间需要有一个死区时间防止短路。这个死区时间可以用另一个TON来实现比如设T#100MS。实际编程的时候还要考虑停止逻辑和过载保护。停止按钮按下时所有接触器立即断开定时器复位。过载保护动作时同样立即断开所有接触器。7.2 设备润滑周期的定时器实现有些设备需要定期润滑比如每运行2小时润滑一次每次润滑30秒。这个逻辑可以用两个定时器来实现一个TONR用来累计运行时间PT设T#2H当TONR的Q输出为TRUE时触发一个TPPT设T#30S用来控制润滑泵运行30秒。润滑结束后用RTM指令复位TONR重新开始累计。这个方案的关键点是TONR的累计时间要在润滑期间也继续累计还是润滑期间暂停累计如果润滑期间设备仍在运行那TONR应该继续累计如果润滑期间设备暂停那TONR的IN条件应该去掉。这个要根据实际工艺要求来确定。7.3 报警延时确认的定时器用法有些报警信号会瞬间抖动比如传感器干扰导致的误报。为了过滤这些瞬间抖动可以用一个TON来做延时确认报警信号接TON的INPT设T#3SQ输出接真正的报警。这样只有当报警信号持续3秒以上才会触发真正的报警。但如果报警信号是间歇性的比如每秒抖动一次那TON永远达不到3秒报警就不会触发。这时候可以用TONR让报警信号每次接通都累加时间累计到3秒就触发报警。但TONR需要手动复位所以要在报警确认后加一个RTM指令。7.4 多台设备顺序启动的定时器链在多台设备顺序启动的场景里比如一条输送线有3台电机要求按下启动按钮后电机1先启动5秒后电机2启动再5秒后电机3启动。这个逻辑可以用3个TON来实现每个TON的PT都设T#5S但IN条件不同电机1的TON由启动按钮触发电机2的TON由电机1的Q输出触发电机3的TON由电机2的Q输出触发。这种定时器链的写法很直观但要注意如果中间某台电机故障后面的定时器就不会触发。所以实际项目中通常会在每个定时器的IN条件里加上故障连锁确保故障时后续设备不会启动。8. 关于定时器的一些经验之谈8.1 定时器命名规范的重要性我见过太多项目程序里几十个定时器名字全是IEC_Timer_0_DB、IEC_Timer_1_DB维护的时候根本不知道哪个是干什么的。所以我的习惯是每个定时器的背景DB都改成有意义的名字比如“DB_电机1启动延时”、“DB_报警确认延时”。如果是多重背景那FB的静态变量名也要起得清楚比如“stat_StarDeltaTimer”。命名规范这件事看起来是小事但在项目后期调试和客户维护的时候能省下大量时间。特别是当设备运行几年后出了问题维护人员打开程序看到一堆IEC_Timer_x_DB那种绝望感我是体会过的。8.2 定时器与计数器的配合使用定时器和计数器经常配合使用比如“运行10次后提醒维护”或者“累计运行100小时后报警”。这种逻辑通常是定时器负责计时计数器负责计数两者通过逻辑组合来实现。但要注意计数器的计数信号应该用定时器Q输出的上升沿而不是电平信号。否则定时器Q输出为TRUE期间每个扫描周期计数器都会加1很快就溢出了。所以要用上升沿检测指令比如R_TRIG来提取定时器Q输出的上升沿。8.3 博途版本差异对定时器操作的影响博途的版本更新比较频繁不同版本在定时器操作上有些细微差异。比如早期版本里IEC定时器的背景DB是自动生成的不能手动指定后来版本支持手动指定DB名称。再比如某些版本里TONR的复位指令位置不一样。我的建议是如果你在一个项目里用了定时器尽量保持博途版本一致不要在不同版本之间来回切换。如果必须升级博途版本升级后要仔细检查定时器相关的程序段确认行为没有变化。8.4 仿真环境下定时器的行为验证博途自带仿真功能可以在没有实际PLC的情况下验证程序逻辑。但仿真环境下定时器的行为跟实际PLC有一些差异仿真环境下的扫描周期是固定的不受实际CPU负载影响所以定时器的计时精度在仿真里看起来很好但实际运行时可能不一样。另外仿真环境下某些系统指令的行为可能跟实际PLC不同比如读取系统时间的指令。所以定时器逻辑在仿真里验证通过后最好还是在实际PLC上再验证一遍特别是对时间精度要求高的场景。8.5 一个关于定时器的小技巧最后分享一个我在实际项目里常用的小技巧如果你需要一个周期性的脉冲信号比如每10秒输出一个100ms的脉冲可以用两个定时器来实现。第一个TON设T#10SQ输出触发第二个TON设T#100MS第二个TON的Q输出就是你要的脉冲。同时第二个TON的Q输出经过一个下降沿检测用来复位第一个TON形成循环。这个逻辑比用时钟存储器位更灵活因为周期和脉冲宽度都可以自由设定。但要注意两个定时器的配合要处理好复位时序否则可能会出现脉冲丢失或者周期不准的问题。定时器操作看起来简单但真正用好、用对还是需要对这些细节有清晰的理解。希望上面这些内容能帮你在下一个项目里把定时器用得更加得心应手。