发表于:2019/1/18 15:05:12
#0楼
标题:博途SCL编程之移位处理及封装库文件
作者:橘子猫
来源:中华工控网
转载请注明:中华工控网工控论坛
当我们需要做移位处理时,西门子博途的指令库提供了4个移位功能可以使用
我们查看循环右移指令ROR的相关说明如下:
通过指令详情我们可以看出,这4个指令在使用时支持字节(Byte),字(Word),双字(Dword)的移位循环,移位处理最大只能做到32位的移位,但是当我们需要进行大于32个的移位处理该怎么办呢?
最先想到的是多次利用移位处理指令,这里需要注意了,由于西门子的字节排列顺序是低字节在前,如下图,所以通过多次移位处理指令时要特别注意点位的移入移除否则就容易出现纰漏,而且使用梯形图做这种多点位的移位时,编写程序也比较麻烦,因此便想到使用SCL语言来编写FB块进行自定义移位处理指令块的封装。
本文主要介绍循环移位处理块怎么编写及封装
打开博途软件→新建项目→添加PLC,随意添加了一个CPU即可
这里添加了个S7-1215c的Cpu
添加新FB块→选择SCL语言→编号建议选择手动,然后设置的大一些,这里选110
生成移位处理块FB110
选中移位处理块→右键→属性,然后去掉优化的块访问
双击打开移位处理块→打开块接口
顾名思义,input,output,inout,static,temp,constant分别代表5种接口,
Input---------变量是外部输入的,只能被本程序块读,不能被本程序块写;
Out-------是本程序块输出的,他可以被本程序块读写,其他程序通过引脚只能读值不能写;
In_Out-- 输入输出变量?本程序块和其他程序都可以读写这个引脚的值。
Temp -----临时变量,顾名思义是暂时存储数据的变量。这些临时的数据存储在CPU工作存储区的局部数据堆栈(L堆栈)中。一般建议少使用temp,如果程序块比较多且都使用temp容易造成数据冲刷掉
Statc-------在PLC运行期间始终被存储。静态变量定义在背景数据块中(仅对FB而言,FC和OB无静态变量),当被调用块运行时,能读出或修改静态变量;被调用块结束后,静态变量保留在数据块中
Constant-------代表常量定值
接下来需要新建变量,都有哪些变量呢,对于移位处理块,使用Bool数组来存放点位,于是建立如下变量 :
Mode是选择采用哪种算法;
OffestCounts是指移多少位;
OffesDirection指移位方向;
ArrayBool[]指需要做移位处理的bool数组,在高级语言如C#里可以用List集合定义变长的集合,在博途中,PLC固件版本V4.2及以上且FC/FB块使用优化访问,便可以创建在FB里Inout接口定义变长数组,举例:变长数组 Array[*] of Bool(注:FC可以在Int和InOut接口建立变长数组),这里为了化繁为简所以不采用变长数组,直接使用定长数组,数组长度为60,也就是Array[0..59] of Bool,为了拓展建议把59用常量length代替,即Array[0..#length] of Bool,这样程序里的59都用length代替了,这样的好处就是有一天复用该移位块时,当移位数组的数组长度发生变化时就仅改动length的值即可,Static接口里的变量是为了进行数据运算做辅助处理的。
变量建立好了开始写移位算法:这里用右移举例
算法一:首先最容易想到的就是将数组移动1位,然后循环K次即可实现移动K位
这样的算法思路简单,但是程序耗时较大,会严重影响plc的扫描周期
为了减少plc的扫描耗时,于是想到了利用空间换时间的做法。
算法二:借助于辅助空间MidArrayBool[]对移出数组的元素进行暂存,待移位完成后再利用辅助数组进行拼接,这里有个细节要注意,因为循环移位K次,如果K > N,则其效果与移动K MOD N次是一样的(K MOD N表示K对N取余数,比如K=5,N=3,取余后为2)
算法二虽然耗时大大减少,但是空间占用变大,有没有更好的算法既能节约空间又能节约时间呢,答案是有的。
算法三:我们要借助数学公式里的求逆函数,利用求逆公式(arbr)r=ba,把原数组按偏移数分成两组,通过三次求逆实现元素的移位
举例:
假如原数组: 1 2 3 4 5 6 7 需要右移3次,那么我们想要的结果是: 5 6 7 1 2 3 4。
1.将1234逆置 变成 4321
2.将567逆置 变成 765
3.将两个逆置数组拼接: 4321765
4.将这个已拼接的数组逆置: 5671234 就成了我们想要的结果了。
最后相同数组长度下计算下耗时(单位ms):
这里可以将三种算法都封装到一个块里,通过调用块时,具体通过选择Mode来指定使用哪种算法即可。
那么块写好了我们如何使用呢?
打开主函数MainOB1块,选中移位操作块后拖拽到OB1的程序段1里面,系统会自动分配一个背景数据DB块,该DB块时用于存放移位操作块的数据的,可以看到拖动生成的FB110块左侧出现了一些输入参数,使用时可以按需填写参数即可。
这里便完成了移位操作块的功能和调用了。
块封装成全局库文件
如果其他项目也要用到移位处理怎么办呢?难道每次都要写一次吗?复制粘贴?有没有什么好的办法可以一劳永逸呢?答案是肯定有呀!我们可以将它封装到库,博途提高项目库和全局库,项目库是指该项目里不同plc都可以调用,全局库是指可以将块封装成库文件,发送给其他开发者使用,这样任何项目都可以调用,这也是为什么要将他定义成FB110就是为了避免和项目里其他FB块冲突。
我们如何将他封装到全局库文件呢?
在博途软件右侧打开库→建立新库→写库名字,将写好的移位操作块拖拽到新建库的主模板里,然后将新建的库保存,这样的我们在其他任何项目都能调用该函数块了。
我们在其他项目里只需要在全局库里打开该库文件即可拖拽到我们左侧项目树PLC程序块下面。
最后,放上变量表和算法抛砖引玉,该算法均使用右移,请自行完成左移处理即可:
如果本文对您有一丝帮助,请点个赞,支持一下工控论坛,您的支持是我们更新的动力,如果文中有不妥之处或有更好的见解,望不吝赐教,欢迎前辈拍砖!
———————————————————————
中华工控网,感谢作者供稿!
作者:橘子猫
来源:中华工控网
转载请注明:中华工控网工控论坛
当我们需要做移位处理时,西门子博途的指令库提供了4个移位功能可以使用
我们查看循环右移指令ROR的相关说明如下:
通过指令详情我们可以看出,这4个指令在使用时支持字节(Byte),字(Word),双字(Dword)的移位循环,移位处理最大只能做到32位的移位,但是当我们需要进行大于32个的移位处理该怎么办呢?
最先想到的是多次利用移位处理指令,这里需要注意了,由于西门子的字节排列顺序是低字节在前,如下图,所以通过多次移位处理指令时要特别注意点位的移入移除否则就容易出现纰漏,而且使用梯形图做这种多点位的移位时,编写程序也比较麻烦,因此便想到使用SCL语言来编写FB块进行自定义移位处理指令块的封装。
本文主要介绍循环移位处理块怎么编写及封装
打开博途软件→新建项目→添加PLC,随意添加了一个CPU即可
这里添加了个S7-1215c的Cpu
添加新FB块→选择SCL语言→编号建议选择手动,然后设置的大一些,这里选110
生成移位处理块FB110
选中移位处理块→右键→属性,然后去掉优化的块访问
双击打开移位处理块→打开块接口
顾名思义,input,output,inout,static,temp,constant分别代表5种接口,
Input---------变量是外部输入的,只能被本程序块读,不能被本程序块写;
Out-------是本程序块输出的,他可以被本程序块读写,其他程序通过引脚只能读值不能写;
In_Out-- 输入输出变量?本程序块和其他程序都可以读写这个引脚的值。
Temp -----临时变量,顾名思义是暂时存储数据的变量。这些临时的数据存储在CPU工作存储区的局部数据堆栈(L堆栈)中。一般建议少使用temp,如果程序块比较多且都使用temp容易造成数据冲刷掉
Statc-------在PLC运行期间始终被存储。静态变量定义在背景数据块中(仅对FB而言,FC和OB无静态变量),当被调用块运行时,能读出或修改静态变量;被调用块结束后,静态变量保留在数据块中
Constant-------代表常量定值
接下来需要新建变量,都有哪些变量呢,对于移位处理块,使用Bool数组来存放点位,于是建立如下变量 :
Mode是选择采用哪种算法;
OffestCounts是指移多少位;
OffesDirection指移位方向;
ArrayBool[]指需要做移位处理的bool数组,在高级语言如C#里可以用List集合定义变长的集合,在博途中,PLC固件版本V4.2及以上且FC/FB块使用优化访问,便可以创建在FB里Inout接口定义变长数组,举例:变长数组 Array[*] of Bool(注:FC可以在Int和InOut接口建立变长数组),这里为了化繁为简所以不采用变长数组,直接使用定长数组,数组长度为60,也就是Array[0..59] of Bool,为了拓展建议把59用常量length代替,即Array[0..#length] of Bool,这样程序里的59都用length代替了,这样的好处就是有一天复用该移位块时,当移位数组的数组长度发生变化时就仅改动length的值即可,Static接口里的变量是为了进行数据运算做辅助处理的。
变量建立好了开始写移位算法:这里用右移举例
算法一:首先最容易想到的就是将数组移动1位,然后循环K次即可实现移动K位
这样的算法思路简单,但是程序耗时较大,会严重影响plc的扫描周期
为了减少plc的扫描耗时,于是想到了利用空间换时间的做法。
算法二:借助于辅助空间MidArrayBool[]对移出数组的元素进行暂存,待移位完成后再利用辅助数组进行拼接,这里有个细节要注意,因为循环移位K次,如果K > N,则其效果与移动K MOD N次是一样的(K MOD N表示K对N取余数,比如K=5,N=3,取余后为2)
算法二虽然耗时大大减少,但是空间占用变大,有没有更好的算法既能节约空间又能节约时间呢,答案是有的。
算法三:我们要借助数学公式里的求逆函数,利用求逆公式(arbr)r=ba,把原数组按偏移数分成两组,通过三次求逆实现元素的移位
举例:
假如原数组: 1 2 3 4 5 6 7 需要右移3次,那么我们想要的结果是: 5 6 7 1 2 3 4。
1.将1234逆置 变成 4321
2.将567逆置 变成 765
3.将两个逆置数组拼接: 4321765
4.将这个已拼接的数组逆置: 5671234 就成了我们想要的结果了。
最后相同数组长度下计算下耗时(单位ms):
这里可以将三种算法都封装到一个块里,通过调用块时,具体通过选择Mode来指定使用哪种算法即可。
那么块写好了我们如何使用呢?
打开主函数MainOB1块,选中移位操作块后拖拽到OB1的程序段1里面,系统会自动分配一个背景数据DB块,该DB块时用于存放移位操作块的数据的,可以看到拖动生成的FB110块左侧出现了一些输入参数,使用时可以按需填写参数即可。
这里便完成了移位操作块的功能和调用了。
块封装成全局库文件
如果其他项目也要用到移位处理怎么办呢?难道每次都要写一次吗?复制粘贴?有没有什么好的办法可以一劳永逸呢?答案是肯定有呀!我们可以将它封装到库,博途提高项目库和全局库,项目库是指该项目里不同plc都可以调用,全局库是指可以将块封装成库文件,发送给其他开发者使用,这样任何项目都可以调用,这也是为什么要将他定义成FB110就是为了避免和项目里其他FB块冲突。
我们如何将他封装到全局库文件呢?
在博途软件右侧打开库→建立新库→写库名字,将写好的移位操作块拖拽到新建库的主模板里,然后将新建的库保存,这样的我们在其他任何项目都能调用该函数块了。
我们在其他项目里只需要在全局库里打开该库文件即可拖拽到我们左侧项目树PLC程序块下面。
最后,放上变量表和算法抛砖引玉,该算法均使用右移,请自行完成左移处理即可:
如果本文对您有一丝帮助,请点个赞,支持一下工控论坛,您的支持是我们更新的动力,如果文中有不妥之处或有更好的见解,望不吝赐教,欢迎前辈拍砖!
———————————————————————
中华工控网,感谢作者供稿!