S7-1200/1500定时器操作全解析:IEC定时器指令与避坑指南
发布时间:2026/10/16 1:18:58 锦皓数字建站

1. 为什么定时器操作值得单独拎出来讲在PLC编程这个圈子里摸爬滚打十来年我见过太多项目栽在定时器上。说出来你可能不信一个看似简单的TON指令能让整条产线停摆半天。S7-1200和S7-1500作为当前西门子主流的中小型和高端控制器它们的定时器机制跟老一代S7-300/400有本质区别——IEC定时器不再占用系统存储区而是以DB块的形式存在这个变化直接影响了程序的架构设计和资源管理方式。这篇文章要聊的就是围绕S7-1200和S7-1500的定时器操作把IEC定时器、TP、TON、TOF、TONR、TRES这些指令的底层逻辑、实操配置、常见坑点全部拆开揉碎讲清楚。不管你是刚接触博途的新手还是从S7-300转过来的老手只要你的项目里涉及时间控制——比如电机延时启动、阀门顺序动作、报警滤波、生产节拍统计——这些内容都能直接拿去用。我写这篇东西的出发点很简单网上大部分资料要么只贴指令说明要么只给一个截图真正把“为什么这么用”“参数怎么算”“出问题了怎么查”讲透的很少。下面这些内容一部分来自我自己的项目笔记一部分来自跟同行交流时踩过的坑还有一部分是对西门子官方文档的实践验证。你可以在博途里直接跟着操作也可以先看完再动手。2. S7-1200/1500定时器的底层逻辑与选型思路2.1 IEC定时器与老式定时器的本质区别如果你是从S7-300/400转过来的第一件需要转变的观念就是S7-1200/1500里的定时器不再是CPU系统存储区里的一个“资源”而是一个实实在在的数据块。在S7-300时代你写T1那是一个系统分配的定时器编号数量有限S7-300最多256个。到了S7-1200/1500你调用TON指令博途会自动生成一个背景数据块比如IEC_Timer_0_DB这个DB里存着定时器的所有状态当前值、预设值、输出位等等。这个变化带来的直接影响有三个。第一定时器数量不再受CPU型号限制理论上只要内存够你可以创建成千上万个。第二每个定时器都有独立的DB意味着你可以用符号名去访问它的.ET已过时间和.Q输出位调试的时候可以直接监控不用再猜。第三定时器的行为完全由IEC 61131-3标准定义不同品牌PLC之间的移植性更好但跟老S7定时器的行为有差异比如时间基准统一为1ms不再有10ms、100ms、1s、10s的区分。我个人的经验是如果你维护的是老项目看到SD、SF、SP这些指令那是S7-300/400的遗产在S7-1200/1500里虽然能用通过移植但不建议在新项目里继续用。新项目一律用IEC定时器代码更清晰维护更方便。2.2 四种定时器指令的适用场景对比S7-1200/1500提供了四种基本定时器指令TON接通延时、TOF断开延时、TP脉冲、TONR保持型接通延时。很多人用了好几年还是分不清什么时候该用哪个。我整理了一个对比表你可以在选型的时候直接对照。指令功能描述典型应用场景关键特点TON输入接通后延时一段时间输出才接通电机星三角启动延时、报警确认延时输入断开则输出立即断开当前值清零TOF输入断开后延时一段时间输出才断开冷却风扇延时关闭、照明延时熄灭输入接通则输出立即接通当前值清零TP输入接通后输出固定宽度的脉冲阀门脉冲控制、信号展宽脉冲宽度由PT决定输入再次触发无效TONR输入接通时计时断开时保持当前值设备运行时间累计、维护提醒需要配合TRES指令复位这里要特别说一下TONR。很多新手会把它当成TON用结果发现输入断开后输出还是保持的就以为程序出bug了。其实TONR的设计初衷就是累计计时比如你想统计一台泵总共运行了多少小时用TONR就对了。但记得在维护完成后调用TRES复位否则它会一直累加到最大值然后溢出。2.3 定时器DB块的创建方式与资源管理在博途里创建定时器有两种方式一种是直接在程序里拖拽指令博途会弹出对话框让你新建一个DB另一种是先在项目树里手动新建一个全局DB然后在程序里调用时选择这个DB。这两种方式各有优劣。自动生成的方式适合临时测试或者定时器数量少的场景优点是快缺点是DB名字是自动生成的比如IEC_Timer_0_DB后期维护的时候满屏的IEC_Timer_xx_DB根本分不清哪个是干嘛的。我见过一个项目光自动生成的定时器DB就有两百多个后来设备出问题查程序查了整整一天。手动创建的方式适合正式项目你可以给DB起一个有意义的符号名比如DB_MotorStartDelay、DB_AlarmFilter然后在注释里写清楚用途、预设值、调用位置。这样做的好处是任何人接手你的程序打开交叉引用就能看明白。我的习惯是在项目初期就规划好定时器的命名规范比如T_开头表示定时器后面跟功能描述像T_ConveyorStartDelay、T_ValveCloseDelay。还有一个资源管理的问题。S7-1200的CPU内存相对有限比如1214C只有50KB的工作内存如果你创建了几百个定时器DB每个DB至少占用几十个字节累积起来也是不小的开销。S7-1500的内存就宽裕多了但也不建议无节制地创建。我的做法是对于同一个功能模块里的多个定时器如果它们不会同时使用可以考虑复用同一个DB通过条件判断来切换预设值。当然这增加了程序的复杂度需要权衡。3. 核心指令的实操配置与参数计算3.1 TON指令的完整调用流程与参数设置TON是使用频率最高的定时器指令没有之一。它的逻辑很简单IN端接通后开始计时当前值ET达到预设值PT时输出Q置位。IN端断开ET清零Q复位。在博途里调用TON的步骤是这样的打开OB1或者某个FC从右侧指令树里找到“基本指令”→“定时器操作”→“TON”拖到程序段里。博途会弹出一个“调用选项”对话框让你选择数据块。如果是第一次用点击“确定”会自动生成一个DB。然后你需要给IN端接一个触发条件比如%I0.0启动按钮给PT端设置预设值比如T#5S5秒。这里有一个细节很多人会忽略PT的数据类型是TIME你可以直接输入T#5S也可以输入T#5000MS还可以输入T#1M30S。博途支持多种时间格式但编译后统一转换为毫秒。如果你在HMI上让操作员输入时间通常用DINT或者INT然后乘以一个系数转换成TIME。比如操作员输入50表示5秒你需要写PT : DINT_TO_TIME(50 * 100)这里的100是系数因为50的单位是100ms。我个人的习惯是在定时器的DB里给PT设一个初始值然后在程序里用MOVE指令动态修改。这样做的好处是调试的时候可以直接在监控表里改PT不用重新下载程序。但要注意如果PT在程序里被反复赋值你在监控表里改的值会被覆盖。所以我的做法是只在初始化的时候赋值一次或者用一个标志位控制是否允许修改。3.2 TOF和TP的差异化使用技巧TOF的逻辑跟TON正好相反IN端接通时Q立即接通ET清零IN端断开时开始计时ET达到PT时Q断开。这个指令最典型的应用就是冷却风扇。比如一台设备停机后风扇需要继续运行5分钟散热你就可以用TOFIN端接设备的运行信号PT设T#5MQ端接风扇接触器。TP指令可能很多人没用过它的逻辑是IN端检测到上升沿时Q接通并开始计时计时达到PT后Q断开。在计时期间即使IN端再次触发Q也不会重新计时。这个特性适合做“单次脉冲输出”比如某个阀门只需要给一个2秒的脉冲信号就能打开用TP就比用TON加一堆逻辑要简洁得多。这里有一个坑要提醒TP指令的IN端必须用上升沿触发如果你直接接一个常ON的信号Q只会输出一次脉冲然后就不再动作了。如果你需要周期性脉冲得用时钟存储器或者自己写一个振荡电路。3.3 定时器预设值的计算与动态修改预设值PT的计算是很多新手容易出错的地方。博途里的TIME类型底层是DINT单位是毫秒。所以T#1S实际上就是1000。如果你从HMI输入一个整数比如10想表示10秒那就要写成PT : DINT_TO_TIME(10 * 1000)。如果你忘了乘1000那实际就是10毫秒设备动作会快得你反应不过来。动态修改PT的场景很常见比如不同产品型号需要不同的延时时间。我的做法是在DB里建一个DINT类型的变量SetTime_ms然后在HMI上让操作员输入毫秒值程序里用PT : DINT_TO_TIME(SetTime_ms)。这样操作员输入5000就是5秒直观明了。如果操作员习惯用秒那就输入秒程序里乘1000。还有一个高级技巧用TIME_TO_DINT把当前值ET转换成整数然后在HMI上显示进度条。比如Progress : TIME_TO_DINT(Timer_DB.ET) * 100 / TIME_TO_DINT(Timer_DB.PT)这样操作员就能看到延时进度了。这个功能在调试阶段特别有用能帮你快速判断定时器是否在正常工作。4. 完整实操流程从零搭建一个延时启动控制4.1 项目创建与硬件组态假设我们要实现一个功能按下启动按钮后电机等待5秒再启动运行10秒后自动停止。这个场景虽然简单但涵盖了TON和TOF的典型用法。第一步新建项目。打开博途创建新项目命名为TimerDemo。添加一个新设备选择S7-1200 CPU 1214C DC/DC/DC版本根据你实际硬件选择。如果你手头没有实物可以用PLCSIM仿真S7-1200支持PLCSIMS7-1500支持PLCSIM Advanced。第二步硬件组态。在设备视图里确认CPU的输入输出地址。默认情况下集成输入从%I0.0开始输出从%Q0.0开始。我们假设启动按钮接在%I0.0停止按钮接在%I0.1电机接触器接在%Q0.0。第三步定义变量。在PLC变量表里定义以下符号StartBtn%I0.0Bool、StopBtn%I0.1Bool、Motor%Q0.0Bool、Timer_DelayStartDBTON、Timer_RunTimeDBTON。注意定时器的DB不需要在变量表里定义调用指令时自动生成即可。4.2 梯形图程序编写与定时器调用在OB1里我们写三个程序段。第一段启动延时。用StartBtn的上升沿触发一个TON预设值T#5S。当TON的Q输出为1时置位Motor。这里要注意StartBtn要用上升沿否则按钮按住不放定时器会一直计时但这不是我们想要的。上升沿用P_TRIG指令或者直接在TON的IN端接一个上升沿触点。第二段运行计时。当Motor为1时启动另一个TON预设值T#10S。当这个TON的Q输出为1时复位Motor。这样就实现了运行10秒后自动停止。第三段停止控制。用StopBtn复位Motor同时复位两个定时器。复位定时器用R指令或者直接给TON的IN端接0。但要注意TON的IN端断开后ET会自动清零Q也会复位所以不需要额外复位。这里有一个细节如果你用StartBtn的上升沿触发TON那么当StartBtn松开后TON的IN端变为0ET清零Q复位。这意味着电机永远不会启动。正确的做法是用一个中间变量StartFlag来保持启动信号。具体逻辑是StartBtn上升沿置位StartFlagStopBtn或者定时器Q复位StartFlag。然后StartFlag接TON的IN端。4.3 仿真验证与在线调试程序写完后点击“编译”按钮检查是否有错误。然后点击“下载到设备”选择PLCSIM作为目标。下载完成后点击“转到在线”打开监控表。在监控表里添加StartBtn、StopBtn、Motor、Timer_DelayStart.ET、Timer_DelayStart.Q、Timer_RunTime.ET、Timer_RunTime.Q。然后手动修改StartBtn为TRUE观察定时器的ET是否开始增加5秒后Motor是否变为TRUE再过10秒Motor是否变为FALSE。如果发现定时器不动作先检查IN端是否有信号。如果IN端有信号但ET不增加检查PT是否设置为0或者负数。如果ET增加但Q不动作检查PT是否设置得太大。如果Q动作了但电机不启动检查Motor变量是否被其他地方复位了。仿真通过后下载到实际PLC。在线调试的时候可以用“监控与强制”功能强制StartBtn为TRUE观察实际输出。但要注意强制功能有风险操作前确认设备处于安全状态。5. 常见问题排查与避坑经验实录5.1 定时器不动作或动作异常的排查思路这是被问得最多的问题。我总结了一个排查流程你可以按顺序检查。现象可能原因排查方法解决方案ET不增加IN端无信号监控IN端状态检查触发条件确保IN端为TRUEET不增加PT为0监控PT值设置合理的预设值ET增加但Q不动作PT设置过大对比ET和PT减小PT或等待足够时间Q动作但输出不变化输出被其他逻辑覆盖交叉引用检查排查是否有双线圈或复位指令定时器反复重启IN端信号抖动监控IN端变化加滤波或使用上升沿触发定时器DB丢失程序下载不完整检查下载记录重新下载整个程序我遇到过一个典型案例某项目的输送带延时启动功能时好时坏。到现场监控发现StartBtn的信号有抖动导致TON的IN端反复通断ET不断清零。后来在输入模块里加了10ms的输入滤波问题解决。所以如果你的定时器行为不稳定先检查输入信号的质量。5.2 定时器背景DB冲突与多重背景应用在FC里调用定时器时如果你用的是自动生成的DB每次调用都会生成一个新的DB。如果你在同一个FC里多次调用同一个定时器指令博途会提示“多重背景”或者“背景DB冲突”。这是因为每个定时器实例都需要独立的存储空间。解决方法是使用多重背景。具体操作是先创建一个FB功能块在FB的接口区定义一个TON类型的静态变量比如MyTimer。然后在FB的程序里调用MyTimer博途会自动使用这个静态变量作为背景DB。这样当你多次调用这个FB时每个实例都会有自己的定时器数据互不干扰。这个技巧在写标准化功能块的时候特别有用。比如你写一个电机控制FB里面包含启动延时、停止延时、故障滤波等多个定时器全部用多重背景实现。然后你在主程序里调用这个FB十次每个电机都有独立的定时器代码简洁维护方便。5.3 定时器精度与扫描周期的影响S7-1200/1500的定时器精度受扫描周期影响。TON的计时是在每次扫描时更新的所以实际延时时间 预设值 一个扫描周期。对于扫描周期在10ms左右的项目这个误差可以忽略。但如果你的扫描周期很长比如50ms以上那定时器的精度就会明显下降。我见过一个项目扫描周期达到了80ms结果5秒的延时实际变成了5.08秒。对于大多数应用来说这个误差可以接受。但如果你的应用对时间精度要求很高比如高速包装机那就需要考虑用硬件中断或者循环中断来调用定时器。在循环中断OB里扫描周期是固定的定时器的精度会高很多。另外S7-1500的定时器精度比S7-1200更高因为它的处理速度更快。如果你对时间控制要求苛刻优先选S7-1500。当然价格也更高。5.4 定时器在中断程序中的使用禁忌这是一个很少人提到但很重要的点不要在硬件中断OB里调用TON指令。硬件中断的触发是异步的如果中断频率很高TON的IN端可能会在两次中断之间发生变化导致计时不准确。更严重的是如果中断程序执行时间过长会影响主程序的扫描周期。正确的做法是在硬件中断里只做信号采集和标志位置位然后在主程序或者循环中断里处理定时逻辑。比如你在硬件中断里检测到一个上升沿置位一个Flag然后在OB1里用Flag触发TON。这样定时器的行为就是确定的。循环中断OB比如OB30是可以用定时器的因为它的执行周期是固定的。但要注意循环中断的优先级高于主程序如果定时器的逻辑太复杂可能会影响主程序的实时性。我的建议是循环中断里只放对时间精度要求高的定时器其他定时器还是放在主程序里。6. 进阶技巧定时器与计数器、移位寄存器的组合应用6.1 用定时器实现闪烁电路与周期脉冲闪烁电路是定时器的经典应用。用两个TON互相触发就能实现周期性的脉冲输出。具体逻辑是第一个TON的Q输出为1时触发第二个TON开始计时第二个TON计时到达后复位第一个TON。这样两个TON交替工作输出端就会产生周期性的方波。这个电路在报警指示灯、测试信号源等场景很常用。你可以通过调整两个TON的PT值来控制闪烁的频率和占空比。比如第一个TON的PT设为T#500MS第二个设为T#500MS那就是1Hz的方波亮500ms灭500ms。如果第一个设为T#200MS第二个设为T#800MS那就是亮200ms灭800ms占空比20%。博途里其实有现成的时钟存储器可以在CPU属性里启用然后选择存储字节比如MB0。启用后MB0的各个位会输出不同频率的方波从0.5Hz到10Hz。但时钟存储器的频率是固定的如果你需要自定义频率还是得自己用定时器搭。6.2 定时器与计数器配合实现设备运行时间统计设备运行时间统计是维护管理的重要功能。用TONR指令可以累计计时但TONR的最大计时范围有限TIME类型最大约24天。如果设备需要运行几个月甚至几年TONR就不够用了。我的做法是用TONR统计秒级时间当TONR的ET达到T#1H时复位TONR同时给一个计数器加1。这样计数器的值就是运行小时数。计数器用CTU指令最大值可以设得很大。然后在HMI上显示“运行时间XX小时”。这个方案的好处是即使PLC断电计数器的值也可以保持如果DB设置为保持性。TONR的当前值在断电后不会保持但计数器会。所以重新上电后从上次的小时数继续累计最多丢失1小时以内的数据。对于大多数设备维护来说这个精度足够了。6.3 定时器在顺序控制中的典型用法顺序控制是PLC编程的核心场景之一。比如一个简单的三步顺序第一步阀门A打开等待3秒第二步阀门B打开等待5秒第三步阀门A和B同时关闭。用定时器实现这个逻辑可以用一个步进计数器比如SCL里的CASE语句配合多个TON。每一步激活时启动对应的TONTON到达后步进计数器加1进入下一步。这里要注意每一步的TON要用独立的DB不能复用否则上一步的计时会干扰下一步。在SCL里写顺序控制比梯形图更简洁。比如CASE Step OF 0: IF Start THEN Step : 1; END_IF; 1: ValveA : TRUE; Timer1(IN : TRUE, PT : T#3S); IF Timer1.Q THEN Step : 2; Timer1(IN : FALSE); END_IF; 2: ValveB : TRUE; Timer2(IN : TRUE, PT : T#5S); IF Timer2.Q THEN Step : 3; Timer2(IN : FALSE); END_IF; 3: ValveA : FALSE; ValveB : FALSE; Step : 0; END_CASE;这段代码里Timer1和Timer2是多重背景变量定义在FB的静态区。每一步的定时器独立工作逻辑清晰调试方便。7. 我个人的实操心得与建议说了这么多最后分享几个我在实际项目里总结出来的经验都是踩过坑之后才明白的。第一个经验定时器的预设值不要写死在程序里。我早期做项目PT直接写T#5S结果客户现场要求改成8秒我只能重新下载程序。后来学乖了所有PT都通过HMI或者DB变量来设置现场调试的时候直接改不用动程序。这个习惯让我在后续项目里省了大量时间。第二个经验给每个定时器DB写注释。博途的DB块支持注释你可以在DB的属性里写清楚这个定时器的用途、预设值、调用位置。我见过太多项目程序写完三个月后自己都看不懂了更别说交接给别人。注释花不了几分钟但能省下几小时的排查时间。第三个经验调试阶段用ET值做进度显示。在HMI上做一个进度条绑定定时器的ET值操作员和调试人员都能直观看到延时进度。这个功能在调试阶段特别有用能快速判断定时器是否在正常工作也能给操作员更好的体验。第四个经验不要滥用定时器。有些逻辑其实用计数器或者移位寄存器更合适但新手往往习惯用定时器解决一切问题。比如检测一个信号是否持续了10个扫描周期用计数器比用定时器更准确因为定时器受扫描周期影响而计数器是精确的扫描次数。第五个经验S7-1200和S7-1500的定时器指令虽然兼容但性能有差异。S7-1500的定时器精度更高支持的最小预设值更小。如果你从S7-1200移植程序到S7-1500定时器的行为基本一致但如果你从S7-1500移植到S7-1200要注意S7-1200可能不支持某些高级功能比如超短时间的定时。这些经验没有什么高深的理论都是实际干活的时候一点点积累的。你如果在项目里遇到类似的问题可以试试我的做法。当然每个人的习惯不同找到适合自己的方式最重要。
锦
锦皓数字建站
深耕本土企业品牌数字化升级,专注原创端正雅致商务官网,从视觉设计到稳定运维全程保驾护航。