上一篇文章讲了功能块(FB)的封装与调用,功能块是将一段程序打包成块,设定输入和输出变量,方便重复调用。本篇讲一下与功能块类似的功能(FC,三菱叫做FUN,函数),FC也是一段程序和逻辑的封装,也需要设定输入变量,但是他的输出并不需要设置变量,输出的是它本身,或者说FC本身就是一个带着逻辑的变量,因此使用时也无需将FC声明变量。
FC的使用
三菱也同样提供了很多FC可以直接使用,点击部件选择窗口按钮, 在函数下能看到非常多的FC:
系统函数
如果你不清楚他的功能是什么,可以选中后点击F1查看帮助手册。
这里选择一个随机数RND函数,将它拉倒程序中:
随机数
从引脚名称的字面意思来看,括号内要输入一个布尔量的使能变量和一个16位的任何类型的变量,选中RND按F1看下具体怎么使用:
帮助
可以看到,RND是高电平触发,从0到32767随机生成一个数,并存储在D里面。
使能开关直接赋值,建立个word变量存储生成的数字:
仿真模拟后,可以看到变量RNDnumber里面的值一直在变化(原谅我不会发动图。。。),而且看上去也没什么规律。如果想要能够控制触发时机,可以将使能开关设置一个bit变量,通过控制变量的值来控制随机数的产生。
FC的建立
仍然举例进行说明。
假设我们现在想要写一个扫雷游戏的程序,先看看扫雷的定义:
扫雷游戏
扫雷最高难度定义16*30的格子中存在99个雷,那么程序的其中一个任务就是生成99个雷的坐标,真正扫雷中的雷我不清楚是如何产生的,但我们的程序可以用随机数来产生,通过两个随机数来定义一个雷的XY坐标,循环99次产生99个雷,并将整个功能写进一个FC中。
三菱同样存在建立FC的位置,并且与FB是在相同的地方,仍然是在左侧导航栏FB/FUN右键-新建数据,在弹出的设置窗口中将数据类型选为函数,
建立FC
下面还要设置返回值,我们想要这个功能反回99组XY坐标,显然基本数据类型的变量并不能满足要求,需要建立一个容量合适的结构体和数组的组合:
存储坐标的结构体
在结构体ST_MinesXY中声明了100个iX和100个iY(实际上99个就够),然后将结构体名称填入上图的返回值类型,点击确定后在弹出的窗口中编辑FC内部的程序:
照着RND的方式,我们也建立一个bit变量Enable用来启动这个功能,使用for循环,每个循环使用两个RND生成两个随机数,存放在tempX和tempY中,由于游戏的格子只有30*16,所以需要通过数学运算将tempX控制在0-29之间,tempX控制在1-15之间,99次后99个雷就完成了。
上面说过FC输出的是FC本身,因此我们建立的FC名称就是一个变量,变量类型就是上面输入的返回值的类型,也就是刚刚建立结构体。我们将处理完成的两个随机数写进FC返回值中。
上面的程序有一个问题,生成的坐标有可能是相同的,需要一个查重的功能,每次生成的坐标要与前面生成的坐标依次进行对比,如果存在相同的要重新生成:
查重功能
可以用3个步骤理解这段程序:
1.置位一个bit变量Check,Check触发一个while循环;
2.在这个循环中,将当前生成的随机数与之前生成的所有随机数通过for循环进行遍历和判断;
3.如果存在重复,置位Repetiton变量,重新生成随机数,Check的值不变,这样while循环会重复步骤2和3;如果没有重复的则复位Check,跳出while循环,进行最外面的for循环的下一步,生成下一个雷的坐标。
这个程序存在一个风险,那就是每次生成的随机数都与前面的重复,那么Check一直置位,导致while进入死循环,所以我们在赋值的地方随便增加一点计算,减小重复的概率:
增加计算,减小重复概率
保存后就可以在部件列表中找到这个FC,然后按照上面的方法调用,仿真运行一次看看效果:
运行测试
这里的调用方法跟上面调用RND不同的是,FC返回的值并不在括号内赋值,这是FC的标准用法。通过仿真监看赋值后的结构体变量stMines能够看到已经生成了99个XY坐标,由于触发一直置位true,XY坐标也是一直在变化的。