1.3 扫描周期:PLC的时间观


1.3 扫描周期:PLC的时间观

本节摘要:扫描周期是PLC的操作系统节拍:每个周期依次完成读取输入、执行程序、刷新输出三个阶段,输入被冻结进过程映像,输出要等周期末才生效。理解它,双线圈冲突、响应延时、看门狗停机这些初学者的"玄学故障"就都有了物理解释;本节用青线的实测数据把时间账算给你看。

前面两节解决了"为什么"与"配什么",这一节进入第1章的心脏:CPU到底怎么执行你写的程序。它是理解后面所有章节的地基——第2章五种语言的差异要放在周期里看,第4章状态机的迁移时机由周期决定,第6章那次著名的超时故障,根因就是周期被撑爆。请把这节当作全书的时间坐标系。

一个周期的三拍动作

CPU上电后进入无穷循环,每一圈固定三拍。第一拍读输入:CPU把所有物理输入端子上的状态一次性读入,快照进"过程映像输入区",此后整个周期里,程序读到的输入都是这份快照——哪怕现场按钮在周期中间弹开,本周期内程序看到的一律是快照时刻的状态。第二拍执行程序:从第一条指令顺序算到最后一条,中间访问的输入全部来自过程映像,算出的输出结果先写进"过程映像输出区",不碰真实端子。第三拍写输出:把输出映像区的内容一次性推到物理端子,驱动继电器、晶体管或通信报文。

三拍走完,周而复始。一圈的耗时就是扫描周期时长,青线空载约一点八毫秒,满载高峰约四点五毫秒,主循环看门狗设十毫秒——超时即停机进故障态。这个"宁可停摆也不失控"的策略,与通用计算机"卡一下没关系"的哲学截然相反,是1.1节确定性承诺的机制兑现。

图 1-3:扫描周期时序——一次按钮按下要等几个拍子

图 1-3:扫描周期时序——一次按钮按下要等几个拍子

把延时算成数字

初学者常以为程序是"事件驱动"的:按钮一按,程序立刻知道。扫描周期的世界不是这样。设想青线操作台上的启动按钮在某个周期的第二拍中间被按下:本周期输入快照已冻结,程序看不到;要到下一个周期的第一拍,按钮状态才进映像区;程序算完、第三拍写输出,指示灯才亮。最坏情况跨两个周期,青线主循环十毫秒上限,也就是操作响应最坏约二十毫秒——人手根本察觉不出,这就是扫描周期敢用批量快照换确定性的底气。

但把同样的算法放到毫秒必争的场合,账就完全不同。青线灌装Star轮的缺瓶检测若放在主循环里,最坏十几毫秒的响应窗口对应瓶体在高速线上移动数十毫米,剔除机构必然扑空。工程解法不是把主循环写快,而是把这类信号交给硬件中断或更快的循环中断任务——任务分层是第4章的核心话题之一,这里先记住结论:时间预算按任务分账,不靠主循环单扛。

再看输入滤波。数字量输入模块通常设几毫秒的滤波时间,滤掉触点弹跳与现场干扰毛刺。滤波时间选太短,继电器触点一次弹跳可能被当成两三次通断;选太长,高速脉冲又被抹平。青线的常规按钮用约三毫秒滤波,高速计数通道则关闭滤波直通,同一家模块两种配置,差别就在这份时间预算表。

双线圈:周期逻辑的经典陷阱

扫描周期的串行执行还带来一条铁律:同一线圈在一个周期内被写多次,只有最后一次有效。看一段真实的错误代码——青线调试初期,输送段曾出现"启动后指示灯闪一下就灭",排查两小时才发现是两个工程师各写了一段灯逻辑:

// 工程师A的段落(流程联锁) IF Auto_Mode AND Section_Ready THEN Light_Green := TRUE; END_IF; // 工程师B的段落(按键提示),写在程序更靠后的位置 IF Blink_CMD THEN Light_Green := NOT Light_Green; // 想做闪烁提示 END_IF;

每个周期里A先把灯置亮,B随后基于已亮的灯做取反,灯每周期翻转一次,人眼看到的就是闪烁。两段逻辑各自单看都没错,错在同一线圈被两个来源驱动。规范的做法是保证一个线圈只有一个写入点,或用中间变量汇总所有条件后统一赋值——多数开发环境提供双线圈检查工具,编译警告别当耳旁风。

把这段案例的排查过程拆开看,价值不亚于结论本身。现象是"灯闪",直觉指向接线松动或灯坏,万用表量了一轮端子一无所获;转机在把程序按扫描周期的眼睛重读一遍——设想每个周期这两段代码各自做什么——十分钟后锁定根因。这正是本节开头说的:把扫描周期内化成思维习惯后,很多故障不用连调试器就能在纸上推出来。变式练习留给读者:如果工程师B的闪烁逻辑写在工程师A之前,现象会变成什么样?答案还是闪,但初相位相反——你可以自己推一遍,推完对周期的理解就扎实了。

为什么不做"事件驱动"

写过上位机程序的读者可能会问:中断加回调的事件驱动模型多优雅,为什么PLC不把主程序也做成事件驱动?答案还是在确定性。事件驱动意味着响应时间取决于"此刻正被哪个事件占着",多个事件同时到时的先后顺序依赖调度策略,最坏延时可分析但不可承诺。扫描周期反其道而行:每一拍把所有输入都看一遍,任何信号都不会被"漏看",任何一段联锁逻辑都以固定频率被复核。对安全联锁来说,"每十毫秒必被检查一次"比"事件来了尽快响应"更可信——前者可以写进验收报告,后者只能写进口头承诺。

这个模型也有代价:CPU大量周期花在"其实什么都没变"的逻辑上。所以现代平台普遍提供任务分层——主循环跑常规逻辑,循环中断跑PID与运动控制,硬件中断抓高速信号,把时间预算切开分配。你会在第4章看到青线怎么把十毫秒的主循环预算切成几份。

三个高频疑问

问:扫描周期越短越好吗? 不是。周期短意味着单位时间耗电与发热更高,也意味着你写的每段低效代码都更早顶到看门狗。合理的目标是"任务需求的三倍余量",青线主循环逻辑约三毫秒、上限十毫秒,就是三倍关系。留余量是为了高峰与改造,不是为了跑分。

问:输出一定要等周期末吗,能不能立刻生效? 标准机制下是的,这是批量刷新换确定性的代价。个别平台提供"立即读写IO"指令绕过映像区,但它破坏一致性——程序前半段读的是旧快照、后半段读的是新端子,联锁分析会变得非常痛苦。青线全项目禁用立即指令,高速需求一律走中断任务,规律可循比快更重要。

问:怎么实测我这套系统的真实周期? 各家开发环境都有周期监控:在线模式下能看当前周期、最长周期与最短周期的统计。验收时要把"最长周期"记进交验文档——它才是看门狗真正的参照物,平均值好看不代表高峰不超时。青线的验收表里这栏数值是四点五毫秒,附在十毫秒看门狗旁边,一眼看清余量。

看门狗:底线生锈的那一天

每类任务都配看门狗:程序超时未跑完,CPU立即停机并写入诊断缓冲。它保护的是系统不会在"算了一半"的状态里驱动现场——半成品逻辑比停机危险得多。第6章的排错实录会完整复盘青线一次真实的超时事故:一段调试代码在循环里轮询通信状态,高峰期把主循环撑过十毫秒,全线停机。这里先立个规矩:任何"等一等再继续"的写法,在扫描周期的世界里都是定时炸弹,等待必须交给任务调度,不能靠程序空转。

一个练习:把周期读进代码里

给读者一个自测题,检验本节是否真正内化。看下面这段看似无害的写法:

// 想做"启动后延时5秒再允许下一段" IF Conv1_Run THEN T_Delay(IN := TRUE, PT := T#5S); IF T_Delay.Q THEN Conv2_Permit := TRUE; END_IF; END_IF;

它有问题吗?有——而且有两个。其一,Conv1_Run 断开时定时器没有复位(IN不再被驱动时多数平台自动复位,但这依赖写法),逻辑依赖了隐式行为,评审就该提问;其二,Conv2_Permit 置真后没有人在别处关它,一旦一段停了二段的允许还挂着,联锁关系名存实亡。把周期时序、定时器复位、输出归属三件事在纸上过一遍,这段代码的正确形态自然浮出来——这正是"时间观内化"的含义。

本节要点回顾

  • 三拍结构:读输入快照、串行执行程序、批量刷新输出,周期往复,节拍即确定性;
  • 延时账本:响应最坏跨两个周期,高速信号走中断任务,不在主循环里硬扛;
  • 双线圈:串行执行决定末次写入生效,一个线圈只留一个写入点;
  • 看门狗:超时即停机是保护而非缺陷,程序里禁止空转等待式写法。

时间观立住了,下一章我们回答表达问题:同一段逻辑,五种语言怎么选笔。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U