很多初学者容易将 FC 及FB 相混淆,认为 FB 仅仅是比 FC 多了一个背景数据块,这种认识是非常危险的。在 STEP7 的关于 FC 的描述是这样的:
FC 是一个没有存储空间的逻辑块。FC 的临时变量存储在本地数据堆栈中,这些数据在 FC 执行完毕后将会丢失。为了永久的保存数据,FC 可以使用共享数据块。
由于 FC 没有自己的存储空间,所以必须指定实参给它的参数(这就是为什么 FC 的输入输出管脚必须填写参数的原因)。FC 的临时变量(位于本地数据堆栈中)是无法指定初始值的(由于本地数据堆栈是由系统自动动态使用的)。为了更形象的说明这一点,我们来看下面的例子,此例子对 L 堆栈在程序调用时的分配进行了详细的讲解:
L 堆栈永远以地址“0”开始。在 L 堆栈中,会为每个 FC 提供一定地址空间,作为存放每个块所拥有的固有数据或局部数据。当某个块终止时,那么它的空间随之也被重新释放出来。指针总是指向当前打开块的第一个字节。
运行等级 | L 堆栈中的字节数 | 指针 | |
调用OB1(带有 20 个字节的系统固有数据和局部数据的 10 个附加字节) | 30 | 0 | |
调用 FC1(带有 30 个字节的局部数据) 30 个字节 (OB1) + 30 个字节 (FC1) |
60 | 30 | |
调用 FC20(带有 20 个字节的局部数据) 60 个字节 (OB1 + FC1) +20 个字节 FC10 |
80 | 60 | |
调用 FC21(带有 20 个字节的局部数据) 60 个字节 (OB1 + FC1) +20 个字节 FC11 |
80 | 60 | |
调用 FC2(带有 50 个字节的局部数据) 30 个字节 (OB1) +50 个字节 (FC2) |
80 | 30 | |
调用 FC30(带有 10 个字节的局部数据) 80 个字节 (OB1 + FC2) +10 个字节 FC20 |
90 | 80 |
由上面的例子可以看出:对于FC20 曾经使用过的系统中 L 堆栈 60-80 区间(FC20 中地址范围为 LB0-LB19)在 FC20 调用结束后,被提供给 FC21 使用(FC21 中地址范围同样为 LB0-LB19)。 对于 FC 的临时变量认识不清晰,用户在对临时变量的使用当中,也经常会出现一些错误,下面将使用一个例子非常直观地说明上面的问题
程序原目的:
在 OB1 在程序中调用FC20 后立即调用 FC21
FC20 中将 20 赋值给临时变量 FC20_TEMP1,将 21 赋值给临时变量 FC20_TEMP2FC21 中将 FC21_TEMP1,FC21_TEMP2 相加
程序分析:我们发现 FC20 中的临时变量曾经出现的数值(20,21)被 FC21 中的临时变量FC21_TEMP1, FC21_TEMP2 得到了,如果直接使用这两个临时变量进行加法操作,可以得到结果 41。对于编程人员来说,临时变量必须要在所在程序段中赋值,而后使用。用户对此例中的 FC21_TEMP1, FC21_TEMP2 必须先做清零处理,否则其在使用前即可能拥有数值。
结论:对于 FC 或 FB 中的临时变量,不要希望将本次调用的数值可以存储在里面以供下次程序调用使用,因为这些临时变量所使用的 L 堆栈空间在 FC 或 FB 调用结束就释放给系统了,其它后续程序可以任意使用。所以下列用法都是错误的:
将临时变量用于上升/下降沿指令
将临时变量用于自保持逻辑
临时变量未在所在程序段中赋值,直接使用
审核编辑:郭婷
全部0条评论
快来发表一下你的评论吧 !