
本章将阐述多种特殊函数、常用程序结构以及更复杂的程序范例。

我们在前面12章基本把语法、语句及数据类型等介绍完了,那么这期重点给出一些直接可以用的特殊函数、常用结构及程序案例供大家参考。

简单队列
本示例描述了队列的最简实现方式。队列的典型应用场景包括:当大量包裹在传送带上等待大型工厂设备处理时,这些包裹通常需要记录重量、收件人、尺寸或内容等信息。以重量信息为例,此类数据必须存入队列,才能确保信息随包裹在工厂内流转。若包裹携带可读条码,则无需实现队列结构,因为包裹信息可直接从共享数据库(即企业生产控制系统,通常称为:
实现队列时,队列中的对象原则上不应改变其位置。但当包裹携带条码或其他ID标识时,则允许其在队列中的位置发生变动。
构建队列需创建一个预估最大长度的ARRAY。若ARRAY长度设置过大,将导致内存浪费并增加程序执行时间。
以下给出基础示例:
创建一个包含6个INT数据类型位置的ARRAY。首先将所有数组位置初始化为-1,该值可用于检测位置是否为空:

数据填充过程 当前 ARRAY 已存入三个值(23、35、71)。数据按从左到右的顺序插入:

取出数据时的操作 当最旧值 23 被取出后,所有剩余值需向左移动一位,此时 35 成为新的首元素。
FOR 循环移位实现 通过左移避免数据覆盖,循环次数为 数组长度减1(6位数组需移动5次):

该数组包含6个存储位,数值需进行5次移位操作。因此,FOR循环将执行5次,具体过程如下:
Que[0] := Que[1] // 将位置1的值前移至位置0Que[1] := Que[2] // 将位置2的值前移至位置1Que[2] := Que[3] // 将位置3的值前移至位置2Que[3] := Que[4] // 将位置4的值前移至位置3Que[4] := Que[5] // 将位置5的值前移至位置4为准确追踪下一个插入位置,需要使用索引变量(通常称为index或pointer):
这种简单队列结构存在显著效率问题:每次取出数据时,都需要对整个队列执行耗时的移位操作(即"移动/推送"所有剩余元素)。
采用循环缓冲区技术可有效解决该问题:
所以,我们针对这种情况,有种常见的处理方式:FIFO(First IN First OUT)
前一章节所述的简单队列在每次取出数据时需移动所有元素,本章将介绍通过双指针实现的静态队列,其核心特征在于:
高效FIFO队列由两大要素构成:
pOut指针:指向待取出元素(队首)pIn指针:指向下一个可插入位置(队尾后一位)操作类型 | 指针动作 | 边界处理 |
|---|---|---|
元素取出 | pOut右移 | 到达数组末端时跳转至起始位 |
元素插入 | pIn右移 | 到达数组末端时跳转至起始位 |



本节介绍如何使用少量代码生成随机数,这些随机数可用于PLC程序的测试场景。例如模拟需要装箱的零件重量或尺寸等参数,使开发者能在办公室环境中通过多样化的数值对程序进行全面测试,这种测试方式非常接近实际生产环境的验证效果。
测试方式 | 测试覆盖率 | 成本 | 实施难度 |
|---|---|---|---|
真实生产测试 | 高 | 极高 | 高 |
随机数模拟测试 | 中高 | 极低 | 低 |
(注:随机数测试可在保证85%以上代码覆盖率的同时,节省90%的早期测试成本)


低通滤波器(LP-Filter)
本节详细说明数字低通滤波器的实现原理。该滤波器基于由电子线圈与电容串联构成的模拟RC低通滤波器,其核心功能是允许低频信号通过同时抑制高频噪声。
在模拟量输入模块中,通常内置了低通滤波器,可用于消除传感器及测量设备信号中的噪声和异常波动。然而,模拟量输入模块的滤波频率通常无法在线调整。对于某些工业设备和机械系统,需要实时调整滤波频率,这就必须通过在PLC程序中实现数字滤波器来完成。
下文示例展示的是一阶数字滤波器,也称为指数滤波器。通过傅里叶变换(一种高等数学方法)可将模拟滤波器转换为数字滤波器。
目前市场上有多种用于数字信号处理(DSP)的滤波器类型,其中FIR(有限脉冲响应)滤波器是最知名的之一。与“移动平均”等基于数据平均的滤波方法相比,数字滤波器的优势在于:“移动平均”需要包含所有历史数据并通过长数组存储,而数字滤波器能够自动剔除异常值,且PLC处理速度更快。本实现采用函数块形式,因为滤波器需要使用上一个程序扫描周期的值,该值保存在变量ValueOld中。

其中,k的值可以调整滤波的效果。

4.对于快速变化信号(如转速检测),可采用自适应k值策略:
k := ABS(ValueNew - ValueOld) * 0.5 + 0.01; 
程序框架
程序示例1:输送带
例程框架:

基本保护我们之前所说的:利用子程序、函数功能块FB以及ACTION等将代码分层分段,并且注释清晰。
程序代码:

程序示例2:基于EN60848顺序控制标准的程序结构优化
在设计顺序控制器的程序结构时,理解控制方案的工作原理至关重要。在本控制方案中,储罐内的液位是最关键的因素。液位变化会触发浮球开关,从而决定泵的运行逻辑:
浮球开关决定了程序的状态变化,其状态转换关系如下图所示:
当储罐液位触发LS1时,程序状态从0切换至10。在状态10下,两台泵均停止运行。
当程序处于状态10且液位触发LS2时,状态将切换至20,此时两台泵中必须有一台投入运行。

原文代码这样写,非常难读,所以建议用好空格,该缩进就缩进。并且,当程序行数比较多的时候,建议使用ACTION分块进行编写,最终的代码:
例程框架:

程序代码:

整个框架简洁,总共就两行。


如果是有手动和自动流程的,可以使用这种框架:

程序示例3:计算罐体的容积
本章展示了大型储罐的容积计算方法实现方案。该储罐由圆柱体与底部半球体组合构成。
主要的计算放在FC里面,方便调用:


程序示例4:六泵排水站PLC控制系统实施方案
本示例展示了一个六泵排水站的程序控制结构。系统运行泵的数量取决于集水井内的液位高度:当液位达到满量程时,所有六台水泵必须同时运行,以确保最大排水能力。
本控制方案同样适用于:
采用面向对象编程(OOP)原则和ISA-S88标准:
具体实施框架:

结构体:



FC函数代码:




其他的函数代码可以参考原文,这里不做表述。
主程序代码:

程序示例5:双向切换开关功能块
本示例展示了一个可配置为双向切换开关的功能块(FC Toggle Switch)。该开关在每次触发时改变输出状态,适用于电机、风机或照明设备等电气元件的启停控制。
程序代码:

主程序:

程序示例6:立体车库内车辆存取流程的PLC控制系统
本案例展示用于管理立体车库内车辆存取流程的PLC控制系统。系统通过工业机器人实现全自动车辆搬运,主要包含两大核心功能:
主要核心代码:

应用主程序代码:

程序示例7:可配置式洗车控制系统
本案例展示了一种可通过人机界面(HMI)自主配置洗涤程序的洗车机PLC控制方案。该系统允许洗车场业主根据季节变化自行调整洗涤程序,无需依赖PLC编程人员修改代码。
首先把整体的动作流程规划如下:

更多洗涤序列可以轻松添加,并且可以执行 同一洗涤程序重复使用,或将其用于其他洗涤程序。 在设计程序时,有几种方法可以确保良好的程序结构。
以下融合了我们所说的各种解决方案:
其中包含Program子程序+ Fuction函数 + FuctionBlock功能块 + ACTION动作 + STRUCT等等。
原文里面的代码经过验证,还缺一部分才能模拟,例如所有的ACTION:

我这里加上后:


下载运行后:

测试成功!好了,这是我们第13章节的内容,欢迎分享、收藏和讨论!