S7-SCL学习笔记:(1)功能块多重背景数据的调用举例
前段时间因工作需要,被安排进行西门子PLC的维护。以前在单位是做计算机网络维护和软件开发的,跟这个自动控制完全是两码事,可领导不这样认为,说计算机搞得好,这PLC肯定不在话下,这比你以前的那些还不简单的多,一定能搞的好。
没办法只能重头开始学呗。接触一段时间后,感觉这PLC编程跟这个应用软件编程完全不同,思路都不一样,而且还要懂电气知识、现场的工艺流程等。现场的PLC程序全是什么T型图编的,一段一段没有一点逻辑性,看的云里雾里的。后来在网上查资料的时候发现这西门子的PLC还有个SCL的高级编程语言,类PASCAL的语法,正好我以前也是用的DELPHI,是PASCAL的面向对象的编程语言,同根同源,学起来也应该轻松点。
在网上找了几个S7-SCL的中文教程和手册,看了一周后也是一知半解的,这些资料太不系统、太不详细了,举例也只是支言片语的。没办法只能慢慢的调试、慢慢的体会了。现在总算把功能模块的多重背景自认为搞懂了,反正也没人问,先记下来放在网上再说,如果有哪位朋友发现有理解错误的地方一定告诉一声,也想多结识一些S7-SCL方面的朋友一起学习。下面就说说现在的体会吧,可能还会有更多的功能,以后再说:
FB功能模块定义(Definition)
功能块是逻辑块,包含程序部分,并且有一个内存区域援引派给它。无论何时FB被调用,必须给它指定一个实例数据块。当定义FB的声明部分时,就说明了实例数据块的结构。
这个功能块可以理解成高级语言中的函数吧,但与高级语言中的函数又有一定的区别。在高级语言中的函数中定义的内部变量的值,需要在函数内进行初始化或赋值,随着函数执行完后是不会保留到下一次调用的。而在SCL的功能模块中定义的VAR型变量的值会一直存在,这些变量(除VAR_TEMP型变量外的所有变量)会在编译后自动出现在该功能块背景数据块(DB块)中,而且还可以显式的在SCL源代码中声明这个DB块并初始化这些变量的值。当为这个FB块定义多个DB1、DB2……DBn时,这时这个FB块就有了多重背景数据了。FB块的调动也很有意思,刚开始学习的时候还在纳闷怎么FB块的调用后还跟着个DBn,都不知道是哪来的,现在知道了是自动生成的。对不同DB块中的变量赋不同的值,可以实现不同的计算功能。具体的应用请看下面的S7-SCL源代码:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
ORGANIZATION_BLOCK OB1 TITLE = '功能块多重背景数据的调用举例' // // Block Comment... // VERSION: '1.0' AUTHOR: www.tansoo.cn NAME: BG6RSH FAMILY: Family VAR_TEMP // Reserved info : ARRAY[0..19] OF BYTE; // Temporary Variables i_IN : INT; END_VAR // Statement i_IN := WORD_TO_INT(MW100); // 0-100% 阀门开度 IF i_IN>50 THEN // 通过阀门开度的不同,调用不同的背景数据实现不同的控制功能 FB1.DB1(SET_KAIDU := i_IN // INOUT: WORD ); ELSE FB1.DB2(SET_KAIDU := i_IN // INOUT: WORD ); END_IF; MW102 := INT_TO_WORD(DB2.REL_KAIDU); // OUT: WORD 阀门开度返回值DB1.REL_KAIDU或DB2.REL_KAIDU都可以 END_ORGANIZATION_BLOCK FUNCTION_BLOCK FB1 TITLE = '设置阀门开度,并获得实时返回值' // Block Parameters VAR_INPUT // Input Parameters END_VAR VAR_IN_OUT // I/O Parameters SET_KAIDU: INT := 0; //"设置开度" 0-100% END_VAR VAR_OUTPUT // Output Parameters REL_KAIDU: INT := 0; //"实际开度返回值" 0-100% END_VAR VAR_TEMP // Temporary Variables END_VAR VAR // Static Variables ZXQ_MAX : BYTE; END_VAR // Statement Section PQW272 := DINT_TO_WORD(trunc(SET_KAIDU*276.48)); //将阀门开度百分比换算为4-20mA的AO值 REL_KAIDU := DINT_TO_INT(trunc(WORD_TO_INT(PIW296)/276.48)); //将4-20mA的AI值换算为阀门开度百分比 QB12 := ZXQ_MAX; // 调用不同的背景数据,ZXQ_MAX值会根据背景数据的初始值而变化 END_FUNCTION_BLOCK DATA_BLOCK DB1 FB1 // 功能块FB1的背景数据1 // // Block Comment... // BEGIN ZXQ_MAX := B#16#0F; // 初始化 END_DATA_BLOCK DATA_BLOCK DB2 FB1 // 功能块FB1的背景数据2 // // Block Comment... // BEGIN ZXQ_MAX := B#16#F0; // 初始化 END_DATA_BLOCK |
今天看了一下教材,感觉我对多重背景的理解还是有点问题,我测试用的例子恰恰与教材说的相反,唉。
更正一下:在FC函数中定义的静态变量,其值是会保留到下一次调用的,原文章中有理解错误。
好啊 大师方便留下qq吗
转化的时候 你居然 手动写了个公式,,其实 有FC 105 106 供你使用的,程序员·名不虚传,不过delphi 前景 很好嘛?现在该转型了吧 大师