一、背景
我们做电机起保停控制逻辑的时候,会有两种逻辑方式,一种是利用自锁方式,另外一种是利用SR触发器。
如果我们仅仅是在一个FB/FC里面做这个一般的做法应该很简单。会如下图所示:


二、问题的提出
昨天在论坛里面,看到一位朋友说自己在FC里面做的SR触发器不能保持,他是这样做的:

他问为什么这样不能保持。
三、论坛的回答
论坛里面很多人,给出了答案。分为以下几个方面:
因为 tmp 变量用的是栈里面的内容,在调用完FC后,就被释放,因此不能保存状态。
建立FB,需要用FB里面的static变量, 这样就可以保存
在FC里面使用INOUT接口的变量
利用FC里面的IN接口, OUT接口,或者INOUT接口
四、我的反思
当时我看到这个问题后的第一反映就是,采用上面的第二种方案,利用FB块里面的静态变量。函数应该具有自包含功能的, 是不应该改变外部区域的.
我一直认为的是必须对OUT引脚的变量必须先写值,而不能先引用其对应的值,然后再给OUT引脚进行赋值.
但是我又对其他的答案和方法产生了兴趣。于是做了如下的实验, 写了一个简单的FC
并且在OB1里面调用它.


仿真的执行结果如下所示



在OB1中的调用如下所示:

五 总结
从上面的执行请我们可以看到, 对于西门子FC/FB的接口
IN接口是 传值调用
OUT接口时传址调用
INOUT是传址调用
FB的Static接口是传址引用
同时如果在程序里面对OUT接口的引脚进行了访问的话, 他会通过指针引用去读取引脚指向的地址的值.
INOUT则会具有OUT一样的效果.
六 扩展知识
实际上Step 7的编译器可以看成一个 GNU的 C语言编译器(这个是我个人的猜测,不是很确定, 到底是不是一个C语言的编译器, 这个需要西门子Step7的研发中心来说明了, 但是从我知道的情况来看, Step7其实还有一个C语言扩展包的). 细心的朋友可能会发现在Step7的项目文件夹里面有时候会出现一个 ES_LOC 的文件夹, 这个文件是编译出来的是目标文件和step7 的C语言文件.

我仅仅摘录一段代码给大家看:

可以看到,这里面把对应的地址定义为了 (VOID * ) 的地址指针,因此我们也可以这样看,
FB/FC的 OUT/INOUT和Static的采用了C语言里面的指针参数, 而temp变量则是C语言
函数的内部变量, 调用完成后即释放.
不知道有没有人注意这个问题. 就是编译出来会有一些C语言代码和 *.O的目标文件.