3、函数(FC)与数据块(DB):FC与FB的区别、全局数据块与背景数据块的使用场景、案例:风速滤波函数FC

3.1 FC与FB:两个老伙计,性格完全不同

做风电PLC编程,FC和FB是绕不开的两个基本单元。很多新手问我:「这两个到底有啥区别?我随便用行不行?」

我的回答是:可以混着用,但想写出高质量的风电程序,必须分清楚。

FC(函数),说白了就是一个「纯计算器」。你给它输入,它给你输出,不保留任何中间状态。每次调用,它都像失忆了一样,从头开始算。

FB(功能块),则像一个「有记忆的小助手」。它有自己的数据空间,上次算到哪、中间值是多少,它都记得清清楚楚。

我举个例子你就明白了。风速滤波这个功能,如果用FC实现,每次调用都要把上次的滤波值作为输入传进去。如果用FB实现,它自己内部就存着上次的值,你只管调用就行。

核心区别一句话:FC没有自己的「记忆」,FB有自己的「记忆」(背景数据块)。

特性 FC(函数) FB(功能块)
数据存储 无独立存储区 有背景数据块
多次调用 每次独立,不共享数据 共享背景数据块
典型场景 数学计算、逻辑判断 状态机、PID控制、滤波
资源占用 较少 较多(需分配DB)

我的个人习惯:纯算法用FC,带状态的逻辑用FB。比如风速滤波,我早期用FB做,后来发现其实用FC更灵活,因为滤波参数可以随时调整。

3.2 全局数据块 vs 背景数据块:谁该住「集体宿舍」?

数据块(DB)在风电程序里,就像仓库。但仓库有两种:一种是「公共仓库」,谁都能存取;另一种是「私人仓库」,只有特定的FB能用。

全局数据块(Global DB):全程序可见。我一般用它来存放:

  • 风机运行参数(额定功率、切入风速、切出风速)
  • 系统状态字(故障码、运行模式)
  • 需要HMI显示的实时数据

背景数据块(Instance DB):只属于某个FB。比如每个变桨控制器都有自己的背景DB,里面存着当前桨角、速度、力矩等私有数据。

我曾经踩过的坑:有个项目,我把所有数据都塞进全局DB,结果程序越写越乱。不同功能块互相读写同一个变量,查故障时根本不知道是谁改的。后来我强制规定:每个FB必须用独立的背景DB,全局DB只放「公共信息」。

你想想看,如果每个功能块都往全局DB里写数据,调试时就像在菜市场找人,乱得很。用背景DB,每个功能块的数据井水不犯河水,出了问题直接定位到对应的FB。

3.3 案例:风速滤波函数FC

好,咱们来点干货。风速信号在风电里是最关键的输入之一,但也是最「脏」的信号。传感器抖动、塔影效应、湍流……都会让风速数据像心电图一样跳来跳去。

我常用的是一阶低通滤波,公式很简单:

当前滤波值 = 上次滤波值 + 滤波系数 × (当前采样值 - 上次滤波值)

用FC实现的话,代码长这样:

FUNCTION WindSpeedFilter : REAL
// 输入参数
InValue     : REAL;      // 当前风速采样值
LastFilter  : REAL;      // 上次滤波值(必须由外部保存)
FilterCoeff : REAL;      // 滤波系数(0~1,越小越平滑)

// 输出
WindSpeedFilter := LastFilter + FilterCoeff * (InValue - LastFilter);
END_FUNCTION

注意看,这个FC没有自己的记忆。调用它的程序块,必须自己维护一个变量来保存LastFilter。比如在主循环里:

// 主程序调用
"FilteredWind" := WindSpeedFilter(
    InValue     := "RawWind",
    LastFilter  := "FilteredWind",  // 把上次输出当输入
    FilterCoeff := 0.1
);

嗯,这里要注意:FilteredWind必须是一个全局变量或者静态变量,否则下次调用时LastFilter就丢了。

避坑指南:我曾经在一个项目中,把LastFilter定义成了临时变量。结果每次调用都重新初始化为0,滤波效果等于没有。查了两天才发现这个低级错误。所以记住:FC的「记忆」必须由调用者负责。

那为什么不用FB呢?因为风速滤波这个功能太简单了,用FB反而浪费资源。而且用FC更灵活——你可以把滤波系数做成可调参数,甚至可以在线切换不同的滤波算法。

3.4 知识体系图:FC与DB的关系

下面这张图,是我自己画的一个关系图,帮你理清FC、FB、全局DB、背景DB之间的逻辑关系:

FC与DB关系图 FC(函数) 无记忆,纯计算 FB(功能块) 有记忆,带状态 全局DB 公共数据仓库 背景DB FB私有数据 读写公共数据 自动关联 不同设计思路 FC依赖调用者保存状态,FB自带背景DB保存状态

从这张图可以看得很清楚:FC像是一个「流浪汉」,每次干活都得别人给它带工具(上次的值)。FB则像个「有房一族」,自己的东西自己存着。

在实际的风电项目中,我建议这样分配:

  • FC + 全局DB:适合做风速滤波、功率计算、角度转换等纯数学运算
  • FB + 背景DB:适合做变桨控制、偏航控制、状态机等需要保持状态的逻辑

最后说一句:没有绝对的对错。我见过有人用FB做风速滤波,也见过用FC做状态机。但遵循「FC无状态、FB有状态」这个原则,你的程序会更容易维护,也更容易让别人看懂。


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