文章目录

博途SCL的递归函数实现方法

发布于 2026-03-26 09:22:05 · 浏览 9 次 · 评论 0 条

博途SCL的递归函数实现方法

在博途(TIA Portal)环境中使用SCL语言编写递归函数,可以极大地简化某些特定算法(如遍历树状结构、计算阶乘或斐波那契数列)的代码量。由于PLC的运行机制与通用计算机不同,实现递归时必须严格遵守栈深限制和执行逻辑。以下是在博途中创建并调用递归函数的完整步骤。


1. 创建递归功能块 (FC)

递归通常使用功能块来实现,因为它没有背景数据块(DB),不会因为实例化导致资源占用过大,更适合纯逻辑计算。

打开 TIA Portal 项目树,双击 “程序块” 文件夹以展开。右键单击 “添加新块”。在弹出的窗口中,选择 “Function (FC)”。输入 名称,例如 FC_Recursive_Calc选择 编程语言为 “SCL”。点击 “确定” 创建 块。


2. 定义变量接口

递归函数需要明确的输入参数和返回值。这里以计算阶乘为例,展示如何定义接口。

切换 到新创建的 FC 的“接口”视图。找到 “Return” 区域。点击 类型下拉菜单,选择 DInt(双整数,防止数值溢出)。找到 “Input” 区域。添加 一个变量,命名Number设置 类型为 DInt


3. 编写递归逻辑

阶乘的数学逻辑是:$n! = n \times (n-1)!$,且 $0! = 1$。我们需要在代码中实现这个逻辑,并加上必要的保护措施。

切换 到代码编辑区(代码视图)。输入 以下代码:

// 检查输入合法性:负数无阶乘,返回 0
IF #Number < 0 THEN
    FC_Recursive_Calc := 0;
    RETURN;
END_IF;

// 基础情况(Base Case):0的阶乘和1的阶乘都为1
// 这是递归的终止条件,必须放在最前面
IF #Number <= 1 THEN
    FC_Recursive_Calc := 1;
    RETURN;
END_IF;

// 安全保护:限制递归深度
// PLC的栈空间有限,防止输入过大的数字导致栈溢出停机
IF #Number > 20 THEN
    FC_Recursive_Calc := -1; // 返回 -1 表示溢出错误
    RETURN;
END_IF;

// 递归步骤
// 调用自身:Number * (Number-1)的阶乘
FC_Recursive_Calc := #Number * FC_Recursive_Calc(#Number - 1);

4. 理解递归流程

为了确保逻辑无误,可以通过以下流程理解代码的执行顺序。当输入为 3 时:

graph TD A["开始: 输入 Number = 3"] --> B{"判断: Number <= 1?"} B -- 否 --> C{"判断: Number > 20?"} C -- 否 --> D["计算: 3 * FC_Recursive_Calc(2)"] D --> E["函数调用: 输入 Number = 2"] E --> F{"判断: Number <= 1?"} F -- 否 --> G{"判断: Number > 20?"} G -- 否 --> H["计算: 2 * FC_Recursive_Calc(1)"] H --> I["函数调用: 输入 Number = 1"] I --> J{"判断: Number <= 1?"} J -- 是 --> K["返回: 1"] K --> L["返回: 2 * 1 = 2"] L --> M["返回: 3 * 2 = 6"] M --> N["结束: 最终结果 6"]

5. 在主程序 (OB1) 中调用

编写好递归函数后,需要在主循环组织块(OB1)中进行调用测试。

打开 Main [OB1]选择 一个网络。输入 调用代码。为了观察结果,我们可以定义一个临时变量或直接使用M区。

假设我们定义了一个全局变量 Result_Test (DInt) 来存储结果。

// 调用递归函数计算 5 的阶乘
// 5! = 120
#Result_Test := FC_Recursive_Calc(Number := 5);

编译下载 程序到 PLC。监控 变量 #Result_Test,其数值应变为 120


6. 关键注意事项

在工业控制项目中使用递归需格外谨慎。

限制 递归的最大深度。由于每个 PLC 任务都有固定的栈空间(Local Stack),过深的递归层级会导致 CPU 停机进入 STOP 模式。上述代码中限制 Number <= 20 是基于 DInt 类型的安全范围,同时也限制了递归调用次数。

避免 在循环中断组织块(OB35 等)或高优先级中断中编写复杂的递归逻辑,这可能会导致看门狗超时。

优先 考虑迭代算法。如果可以通过 FORWHILE 循环解决问题,请勿使用递归,因为迭代在 PLC 中的执行效率和资源占用率通常优于递归。

评论 (0)

暂无评论,快来抢沙发吧!

扫一扫,手机查看

扫描上方二维码,在手机上查看本文