4、扫描周期详解:输入采样、程序执行、输出刷新三个阶段的时间模型与硬件实现

说实话,很多PLC工程师干了好几年,对扫描周期的理解还停留在“从左到右、从上到下”这个层面。这其实不够。

你想想看,一个扫描周期里,CPU到底在忙什么?三个阶段——输入采样、程序执行、输出刷新——它们的时间是怎么分配的?硬件上又是怎么实现的?

我个人习惯把这三个阶段拆开来看,每个阶段都有它的脾气。搞懂了,你写出来的程序才叫“硬核”。

4.1 三个阶段的“时间账本”

先给个总览。一个完整的扫描周期,说白了就是CPU在三个任务之间来回切换:

  • 输入采样阶段:CPU把物理输入点的状态,一股脑儿复制到内存里的“输入映像区”。
  • 程序执行阶段:CPU只读“输入映像区”,然后按梯形图逻辑一顿运算,结果写到“输出映像区”。
  • 输出刷新阶段:CPU把“输出映像区”的数据,一次性推给物理输出点。

这三个阶段加起来,就是一个扫描周期。我见过不少新手,以为程序执行占大头。其实不一定。

关键点:扫描周期的长短,取决于程序量、I/O点数,以及CPU的“硬实力”。

举个例子。一个只有100步的简单程序,扫描周期可能只有0.5ms。但如果你写了10万步,还用了大量浮点运算,那周期可能飙到50ms以上。嗯,这里要注意,有些老款PLC,扫描周期超过100ms,你连急停按钮都得掂量掂量。

4.2 输入采样阶段:那一刻的“快照”

输入采样,说白了就是拍一张“快照”。

CPU在进入这个阶段时,会瞬间锁存所有输入点的电平状态。注意,是瞬间锁存。硬件上,这通常靠一个并行总线或者DMA(直接内存访问)来完成。

我曾经在一个项目中遇到过一个问题:一个传感器信号抖动特别快,周期只有2ms。而我的PLC扫描周期是10ms。结果呢?CPU采样时,有时候采到高电平,有时候采到低电平,程序逻辑乱得一塌糊涂。

为什么会这样?因为输入采样只在每个周期的开始做一次。之后程序执行阶段,哪怕输入点状态变了,CPU也“视而不见”。它只认那张“快照”。

避坑指南:我曾经建议一个同事,对于高速脉冲信号,别指望靠普通I/O点去采样。要么用高速计数器模块,要么在输入点加硬件滤波。否则,你就是在赌运气。

硬件实现上,现代PLC的输入采样电路通常包含:

  • 输入隔离:光耦或磁耦,把外部信号和内部电路隔开。
  • 采样保持器:在采样瞬间锁存电平,防止抖动。
  • 总线接口:把数据并行写入输入映像区。

时间模型上,输入采样阶段的时间 ≈ 输入点数 × 单点采样时间 + 总线传输开销。一般来说,这个阶段耗时很短,可能只占整个周期的5%~10%。

4.3 程序执行阶段:CPU的“脑力劳动”

这个阶段是CPU最忙的时候。它要逐条执行用户程序,从输入映像区读数据,运算,然后往输出映像区写结果。

我个人习惯把程序执行阶段比作“流水线”。CPU就像个工人,一条指令一条指令地处理。但这里有个坑:指令的执行时间不是固定的

比如,一条简单的“常开触点”指令,可能只需要0.1μs。但一条“浮点数乘法”指令,可能要2μs。如果你在程序里用了大量数学运算、字符串处理,那执行时间会成倍增加。

注意:程序执行阶段的时间,是扫描周期中最不可控的部分。它完全取决于你的代码质量。

硬件上,CPU在这个阶段主要依赖:

  • 指令流水线:现代PLC芯片(比如基于ARM Cortex-R系列)都有多级流水线,可以并行处理取指、译码、执行。
  • 高速缓存:程序代码和系统固件通常放在Flash里,但CPU会把常用指令缓存到SRAM里,减少等待时间。
  • 中断系统:如果程序里用了中断,CPU会暂停当前任务,先去处理中断服务程序。这会影响扫描周期的稳定性。

时间模型上,程序执行阶段的时间 ≈ 程序步数 × 平均指令执行时间 + 中断开销。我建议你写程序时,尽量用逻辑运算代替数学运算,用查表法代替实时计算。这样能省下不少时间。

4.4 输出刷新阶段:最后的“集体亮相”

输出刷新,是CPU把输出映像区的数据,一次性推给物理输出点。这个过程和输入采样有点像,但方向相反。

硬件上,输出刷新通常也是通过并行总线完成的。CPU把数据写到输出锁存器,然后锁存器驱动功率管,控制继电器或晶体管通断。

我记得有一次,一个客户抱怨说他的PLC输出点反应慢。我一看,他程序里在输出刷新阶段之前,反复修改同一个输出点的状态。这其实没用。因为CPU只在输出刷新阶段才把最终结果推出去。你中间改一万次,也只认最后一次。

小技巧:我建议你在程序末尾,用一个“中间变量”来暂存输出状态。等所有逻辑算完了,再一次性赋值给输出点。这样能避免输出抖动。

时间模型上,输出刷新阶段的时间 ≈ 输出点数 × 单点刷新时间 + 驱动电路响应时间。对于继电器输出,响应时间可能长达10ms。对于晶体管输出,可能只有0.1ms。选型时要注意。

4.5 硬件实现:一张图看懂扫描周期

下面这张图,是我自己画的扫描周期硬件实现流程图。你可以看到,三个阶段在时间上是严格串行的,但硬件模块是并行的。

PLC扫描周期硬件实现流程图 输入采样阶段 物理输入点 → 光耦隔离 → 采样保持器 → 总线 → 输入映像区 (SRAM) 时间轴 程序执行阶段 CPU读取输入映像区 → 逐条执行用户程序 → 写入输出映像区 时间轴 输出刷新阶段 输出映像区 → 总线 → 输出锁存器 → 驱动电路 → 物理输出 关键硬件模块说明: • 输入映像区/输出映像区:位于CPU内部SRAM,用于隔离物理I/O与程序逻辑 • 采样保持器:在输入采样瞬间锁存电平,防止信号抖动影响 • 输出锁存器:在输出刷新阶段一次性锁存数据,驱动功率管 • 总线:并行数据通道,用于CPU与I/O模块之间的高速数据交换

4.6 时间模型:一个简单的计算公式

如果你想知道自己的PLC扫描周期大概是多少,可以用这个公式估算:

T_scan = T_input + T_program + T_output

其中:
T_input  = N_in × t_in + t_bus_in
T_program = N_step × t_avg + t_interrupt
T_output = N_out × t_out + t_bus_out

参数说明:
N_in  = 输入点数
t_in  = 单点采样时间(通常0.1~1μs)
N_step = 程序步数
t_avg = 平均指令执行时间(取决于CPU架构)
N_out = 输出点数
t_out = 单点刷新时间(继电器约10ms,晶体管约0.1ms)

举个例子。一个系统有64个输入点、64个输出点,程序有5000步,CPU平均指令执行时间0.2μs,输出用晶体管。

T_input = 64 × 0.5μs + 2μs = 34μs
T_program = 5000 × 0.2μs = 1000μs = 1ms
T_output = 64 × 0.1μs + 2μs = 8.4μs
T_scan ≈ 1.04ms

你看,程序执行占了绝大部分时间。所以优化程序,是缩短扫描周期最有效的手段。

警告:如果你的PLC扫描周期超过10ms,对于高速控制场景(比如伺服电机、高速计数器),必须考虑使用硬件中断或专用模块。否则,控制精度会大打折扣。

4.7 我的经验总结

做了这么多年PLC,我总结了几条关于扫描周期的“铁律”:

  1. 输入采样是“一次性快照”:程序执行期间,输入变化无效。所以,对于快速变化的信号,要么用硬件中断,要么用高速模块。
  2. 程序执行是“时间黑洞”:大部分扫描周期都耗在这里。优化代码、减少浮点运算、多用位逻辑,能立竿见影。
  3. 输出刷新是“最后亮相”:中间改输出没用,只在刷新那一刻生效。用中间变量暂存,能避免很多奇怪的问题。
  4. 硬件决定下限,软件决定上限:CPU主频、总线宽度、缓存大小,这些是硬指标。但你的代码质量,决定了实际能达到的性能。

嗯,扫描周期这东西,说复杂也复杂,说简单也简单。你只要记住:输入采样看硬件,程序执行看代码,输出刷新看负载。搞懂了这三句话,你就能把PLC的“脾气”摸得透透的。

最后一个小建议:我建议你在调试时,用PLC自带的“扫描周期监视”功能,看看实际周期是多少。如果发现周期波动很大,那多半是程序里有条件分支或者中断处理不当。别偷懒,一个个排查。


公众号:蓝海资料掘金营,微信deep3321