首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >PLC Control with ST,V3版本学习笔记10—巧用子程序、功能块FB及函数FC!

PLC Control with ST,V3版本学习笔记10—巧用子程序、功能块FB及函数FC!

作者头像
Hello工控
发布2025-12-23 14:09:28
发布2025-12-23 14:09:28
1020
举报
文章被收录于专栏:Hello工控Hello工控

我们之前说到文本化编程,最重要的是结构化,跟我们写文章一样,需要分章节分篇分段落,那么对于ST编程而言,也需要我们恰如其分的应用子程序、功能块FB以及函数FC等等来拆分,使得程序更加层次分明,简洁明了!

原书第10章,标题是《Splitting up the PLC program》,翻译过来即程序的拆分!我们这期好好和大家分享下程序的结构化重要的方法!

子程序

原书称之为Program modules,我们这里按照常规的理解:子程序。

对于我们刚入门的工程师来说:最基本的结构,那就是整个程序里面只有一个Main主程序。

其他的程序,作为子程序放在Main里面进行调用!对于上图的程序说明如下:

主程序(Main)的执行流程

在每个程序扫描周期(Program-scan)中,主程序(Main)会被执行一次,其执行顺序如下:

  1. 首先执行 HandlingInput 程序模块中的代码(处理输入信号);
  2. 接着执行 CalculateData 程序模块中的代码(数据计算与处理);
  3. 最后执行 HandlingOutput 程序模块中的代码(控制输出设备)。

当一个扫描周期结束时,PLC会重新启动新一轮扫描,再次调用主程序。例如:

  • 扫描周期设定为50ms,则主程序每50ms执行一次
  • 关键要求所有程序模块的总执行时间必须小于50ms,否则可能导致部分代码无法在周期内完成。
扫描周期超时的解决方案

如果程序模块包含大型数组复杂计算,可能会导致执行时间超出扫描周期。此时可采取以下措施:

  1. 增加扫描周期时间(如从50ms调整至100ms);
  2. 优化代码,检查是否可以减少计算量或重构逻辑。
影响扫描时间的因素
  • 条件判断语句(IF/CASE)的数量会影响执行时间,因此必须按最坏情况(最长可能扫描时间)进行设计,并额外预留缓冲时间。
  • 通常,PLC会在扫描时间不足时发出警告,提示程序员调整设置。
程序模块的独立扫描时间配置
不同模块可设定不同的扫描时间,适用于执行耗时差异较大的情况。例如:
  • 高速IO处理(如传感器信号)可采用较短周期(10ms)
  • 低速任务(如通信或复杂计算)可采用较长周期(100ms)

函数Function

函数的基本概念

函数是PLC程序中的重要构建模块,包含少量可重复调用(执行)的代码。特别是一些常用的数据计算(数学公式),数据转换,或者经常使用的代码。

函数的调用方式

  • 无参数调用
  • 带参数的调用
  • 带表达式的调用
函数的变量作用域与传递方式

调用函数时,变量的传递方向通过符号明确区分:

例如:

函数的优势

特殊调用:数组索引传参

Fuction函数也可以创建成数组ARRAY类型,对于这类特殊的调用,例如上图就是No.4的数组元素的传参调用方式。

图片
图片

函数(FC)与功能块(FB)

1. 核心区别
2. 语法结构对比

函数(FC)语法

功能块(FB)语法:

3. 关键特性解析
  1. 参数传递方式
    • VAR_INPUT (:=):值传递(函数内修改不影响外部变量)
    • VAR_OUTPUT (=>):地址传递(用于输出结果)
    • VAR_IN_OUT (:=):双向传递(直接修改外部变量,适用于数组/结构体)
  2. 变量生命周期
    • FC的局部变量(VAR)每次调用时重新初始化,适合无状态操作。
    • FB的局部变量(VAR)会持久化,适合计数器、定时器等需记忆的场景。
  3. 返回值规则
    • FC必须通过<函数名>:=值显式返回,且只能返回单一值。
    • FB通过VAR_OUTPUT返回多个值,无需函数名赋值。
4. 典型应用场景
  • 使用FC的场合
  • 使用FB的场合
5. 设计注意事项
  1. 变量初始化
    • FC的局部变量必须显式初始化(如Counter := 0;),避免残留值问题。
  2. IN_OUT参数风险
    • 直接操作外部变量可能引发意外副作用,建议添加保护逻辑。
  3. 性能优化
    • 频繁调用的简单逻辑优先使用FC,减少内存占用。
  4. 命名规范
    • 采用动词+名词格式(如CalculateAverageCountMotorStarts

函数实现设计指南

一、函数设计核心目标
  1. 减少程序错误
  2. 提高代码复用率
  3. 构建结构化程序
二、可复用函数的6大设计原则

原则

具体要求

违反后果

变量隔离

禁止直接访问全局变量或I/O模块,必须通过VAR_IN/OUT/IN_OUT传递参数

代码耦合度高,难以移植

通用命名

避免使用PLC型号、公司名等特定标识,采用功能描述性命名(如CalcMotorEfficiency)

可读性差,复用困难

跨平台兼容

确保函数可在不同PLC型号和编程语言中使用

硬件依赖性强

调用灵活性

支持被程序模块和其他函数调用

应用场景受限

参数精简

输入输出参数总数≤8个,超限时改用STRUCT封装(需在VAR_IN_OUT中声明)

维护困难,易出错

鲁棒性校验

必须验证输入参数有效性,返回错误标志(如Error: BOOL),避免运行时错误(RTE)

程序崩溃风险

三、函数实现最佳实践
  1. 代码规模控制
    • 单函数代码行数 ≤ 25行(一屏可见)
    • 超限时拆分为子函数或优化逻辑
  2. 编程语言选择
    • 不强制使用ST(结构化文本),但需保持一致性
  3. 特殊组件注意事项
    • 若含定时器/计数器,必须定义为功能块(FB)
    • 严禁递归调用(函数自调用)
四、两种设计方法论
方法A:自上而下设计法

优势:结构清晰,适合复杂功能 数据转换建议:内部处理类型转换(如TIMEWORD以简化接口)

方法B:自底向上设计法

优势:适合新手,降低出错概率

关键提示:当出现重复代码(Copy-Paste)时,应立即抽象为函数!

五、标准函数执行流程
  1. 创建局部变量(内存分配)
  2. 校验输入参数有效性
  3. 初始化局部变量(赋默认值)
  4. 执行核心逻辑(计算/数据处理)
  5. 设置返回值(FC)或更新状态(FB)
  6. 释放局部变量(FC)
六、函数化编程的5大优势

结构清晰代码复用率提升便于扩展维护支持模块化测试调试时可快速禁用

七、典型函数应用场景
  • 传感器单位转换(如℃→℉)
  • 设备维保时间预测
  • 传送带速度计算
  • OEE(设备综合效率)统计
  • 报警监控逻辑
  • 通用算法封装(如PID调节)

原书上有四个函数相关的例子,有兴趣的朋友可以自行翻阅哦!

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-07-31,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Hello工控 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 子程序
    • 扫描周期超时的解决方案
    • 影响扫描时间的因素
    • 程序模块的独立扫描时间配置
    • 不同模块可设定不同的扫描时间,适用于执行耗时差异较大的情况。例如:
    • 函数的基本概念
    • 函数的变量作用域与传递方式
    • 特殊调用:数组索引传参
  • 函数(FC)与功能块(FB)
    • 1. 核心区别
    • 2. 语法结构对比
    • 3. 关键特性解析
    • 4. 典型应用场景
    • 5. 设计注意事项
    • 一、函数设计核心目标
    • 二、可复用函数的6大设计原则
    • 三、函数实现最佳实践
    • 四、两种设计方法论
    • 方法A:自上而下设计法
    • 五、标准函数执行流程
    • 六、函数化编程的5大优势
    • 七、典型函数应用场景
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档