在上一篇博客中,我们了解了POU的三大分类,其中函数(FUN)作为无状态、可复用的基础算法单元,在PLC编程中常用于数学运算、数据转换、逻辑判断等场景。本文将从函数的核心属性、自定义方法、标准函数应用三个维度展开,结合实操案例帮大家彻底掌握函数编程。
一、函数(FUN)的核心属性与特征
函数的核心特征的是"无内部状态",这决定了其独特的使用规则,具体属性如下:
1. 无内存分配与无状态性
函数没有指定的内存分配地址,不存储内部变量值,仅通过输入参数运算得到返回值。即相同输入参数调用函数时,必获相同输出,无二义性(如数学函数sin(x),输入30°始终返回0.5)。这与后续要讲的功能块(FB)形成核心区别。
2. 变量规则
函数的变量声明需遵循严格规则,确保其无状态性:
- 支持多个输入变量(VAR_INPUT),但仅允许1个返回值(输出变量),返回值类型无限制(可为基本类型、结构体等);
- 不能声明内部存储变量,无法保存运算过程中的中间值;
- 无需实例化,可直接调用;
- 调用关系限制:函数仅能调用其他函数,不能调用功能块(FB)。
3. 三大核心属性
(1)重载性
若函数输入量为类属数据类型(如ANY_INT,包含INT、DINT、SINT等),则为重载函数,可适配不同数据类型的输入。CoDeSys所有标准函数均支持重载,系统会自动匹配输入参数类型调用对应函数。例如ADD函数,输入INT类型时调用ADD_INT,输入DINT类型时调用ADD_DINT;若函数仅适配单一数据类型,则需在函数名中标注(如ADD_INT),称为类型化函数。
(2)可扩展性
部分函数支持扩展输入变量个数,简化多参数运算程序。例如ADD函数不仅支持两数相加,还可扩展为多个输入变量求和,降低代码冗余与存储空间占用。需注意,并非所有函数都支持扩展(如DIV除法函数支持,部分专用函数不支持),扩展限度受PLC硬件、编程语言格式及函数功能定义限制。
(3)EN与ENO使能属性
仅在梯形图(LD)和功能块图(FBD)中有效,分别为输入使能(EN)和输出使能(ENO),可按需启用或禁用:
- EN=False时,函数体不执行,ENO=False;
- EN=True时,函数体执行,ENO=True。
该属性常用于逻辑链路的条件触发,确保函数仅在满足前提条件时执行。
二、标准函数分类与应用
CoDeSys V3.x支持IEC 61131-3标准的8类函数,同时扩展了3类非标准函数,共11类,覆盖绝大多数基础场景:
- 标准函数:数学运算(ADD、SUB、MUL、DIV、sin、sqrt等)、逻辑运算(AND、OR、XOR等)、数据转换(INT_TO_REAL、REAL_TO_INT等);
- 扩展函数:ANDN(与非)、ORN(或非)、XORN(异或非)、INDEXOF(索引查找)、SIZEOF(数据长度)、ADR(地址获取)、BITADR(位地址获取)等。
标准函数无需自定义,直接从标准库调用即可,大幅提升编程效率。
三、实操步骤:自定义函数(以模数转换为例)

下面结合实际场景,自定义一个"模拟量转数字量"函数(F_iScaleOutput),实现0~20mA、4~20mA等模拟量信号到INT类型数字量的转换,步骤如下:
1. 新建函数并配置基础信息
- 右键项目→"添加对象"→"程序组织单元",选择"函数",编程语言设为ST,名称设为"F_iScaleOutput",点击确定;


- 双击函数进入编辑界面,先定义返回值类型:函数名即返回值,在函数声明行修改类型为INT(默认可能为BOOL),即"FUNCTION F_iScaleOutput : INT"。


2. 声明变量(声明区)
根据功能需求,声明输入变量与本地变量(本地变量仅函数内部使用,不对外暴露),代码如下:

注:E_Ctrl_TerminalType为枚举类型,需提前自定义,包含模拟量类型(0~20mA、4~20mA、0~10V、-10~10V),代码如下:


3. 编写逻辑代码(代码区)
通过条件判断区分端子类型,计算数字量转换值,核心逻辑为"线性缩放",代码如下:
|----------------------------------------------------------------------------|
|
|
4. 函数调用与测试
函数编写完成后,可在其他POU(程序/功能块)中直接调用,示例如下(在主程序中调用):
|----------------------------------------------------------------------------|
|
|
下载程序到PLC或仿真器,修改rPhyVal的值,观察iDigitalVal是否按预期线性转换,验证函数逻辑正确性。
四、函数编程注意事项
- 输入参数可传入空值、常数、变量或函数调用结果,但需确保类型匹配;
- 避免在函数中使用硬件地址变量(如%IX1.1),确保函数与硬件无关,提升可移植性;
- 重载函数需保证输入参数类型不同,避免命名冲突;
- 复杂逻辑优先使用ST语言编写函数,简洁高效且易调试。
本文详细讲解了函数的核心属性、自定义流程与实操案例,下一篇博客将聚焦功能块(FB),对比函数与功能块的差异,讲解FB的实例化、扩展性与自定义方法,助力大家掌握更复杂的PLC逻辑编程。