登录
首页 PLC论坛 施耐德电气PLC
回帖 发帖
正文

主题:∞光分享∞035:有用分享-关于程序 功能块 函数 的一些理解

点击:2223 回复:16

这两天论坛里和群里有朋友问了 程序 功能块 函数的各自的意思与区别
这里写一下我的理解.
附件 1.jpg
程序好理解,就是程序嘛.要实现的工艺.逻辑关系.计算都可以在程序里面写
功能块..在之前回复的帖子里我写了
功能块  FB   可以看做"子程序"
你自己定义好的.外部输入变量..输出变量.在内部有一定的计算.逻辑关系..
能够反复调用...比如 somachine里面的那些MC_home_atv  mc_pto 什么的.都属于功能块
相比较的话.和西门子200  200smart里面用的那个库 scaling 是一样的..
             STEP里面是FC144  FC145那个吧.具体数我记不住了..就是比例关系..官方做好的库.直接拿来用就可以了
比如你有一个工程里面有20台水泵...
每台水泵的启停条件都一样.你就可以做一个FB
定义输入.启动.停止.高液位.低液位.手动自动.过载.
定义输出,泵启动. 泵故障
然后在FB里写逻辑关系..
然后你每次都调用这个块,把对应的输入输出写上就可以了
就不用每个泵都写一遍了
最后就是函数了
通过论坛里@weicy007 的解答...我了解到
附件 2.jpg
这样我就想起之前给一个客户写过许多个功能块,其实是应该用函数来做的
应该可以节省很多内存
函数功能嘛.顾名思义.就是要用来写函数啊~~~
附件 3.jpg
附件 4.jpg
'****************功能函数部分***************************
'反余弦函数(参数为弧度)
Private Function ArcCos(  bt : real;) : real;
ArcCos = Atn(-bt / Sqr(-bt * bt + 1)) + 2 * Atn(1)
End Function
'已知abc三边长,求a边对角角度,以弧度表示
Public Sub abc2A(  a : real;,   b : real;,   c : real;, ByRef return_A : real;)
Dim tmpData : real;
tmpData = (b * b + c * c - a * a) / (2 * b * c)
return_A = ArcCos(tmpData)
End Sub
'获取与给定点指定距离和与X轴夹角的点
Public Sub PAD2P(  X : real;,   Y : real;,   Angle : real;,   disc : real;, ByRef returnX : real;, ByRef returnY : real;)
returnX = Cos(Angle) * disc + X
returnY = Sin(Angle) * disc + Y
End Sub
'两点间的距离
Public Sub PP2D(  x1 : real;,   y1 : real;,   x2 : real;,   y2 : real;, ByRef return_Disc : real;)
return_Disc = Sqr((x1 - x2) ^ 2 + (y1 - y2) ^ 2)
End Sub
'已知三角形顶点坐标x1,y1,x2,y2,x3,y3,求三角形外接圆半径R
Public Sub PPP2R(  x1 : real;   y1 : real;,   x2 : real;,   y2 : real;,   x3 : real;,   y3 : real;, ByRef Return_R : real;)
Dim a : real;, b : real;, c : real;, angA : real;  '三角形三边abc和a边对角angA
Dim disc : real;
PP2D x1, y1, x2, y2, a  '计算a边长
PP2D x2, y2, x3, y3, b  '计算b边长
PP2D x3, y3, x1, y1, c  '计算c边长
abc2A a, b, c, angA   '计算A角
'计算外接圆半径
Return_R = a / Sin(angA) * 0.5
End Sub
'两点连线与X轴的夹角
Public Sub PP2A(  x1 : real;,   y1 : real;,   x2 : real;,   y2 : real;, ByRef return_Ang : real;)
Dim PI : real;
PI = Atn(1) * 4
If x1 < x2 And y1 < y2 Then '第一象限
  return_Ang = Atn((y2 - y1) / (x2 - x1))
End If
If x1 = x2 And y1 < y2 Then '90度
  return_Ang = 90 / 180 * PI
End If
If x1 > x2 And y1 < y2 Then '第二象限
  return_Ang = Atn((y2 - y1) / (x2 - x1)) + PI
End If
If x1 > x2 And y1 = y2 Then '180度
  return_Ang = Atn((y2 - y1) / (x2 - x1)) + PI
End If
If x1 > x2 And y1 > y2 Then '第三象限
  return_Ang = Atn((y2 - y1) / (x2 - x1)) + PI
End If
If x1 = x2 And y1 > y2 Then '270度
  return_Ang = 270 / 180 * PI
End If
If x1 < x2 And y1 > y2 Then '第四象限
  return_Ang = Atn((y2 - y1) / (x2 - x1)) + PI * 2
End If
If x1 < x2 And Abs(y1 - y2) < 0.000001 Then '0度
  return_Ang = Atn((y2 - y1) / (x2 - x1))
End If
End Sub
'求直线和圆的交点,Order参数为true则取的是逆时第一点坐标,Order参数为false则取的是逆时第二点坐标,以圆心为坐标系原点
Private Sub getCircleLineIntersect(  CX : real;,   CY : real;,   r : real;,   LX1 : real;,   LY1 : real;, _
                         LX2 : real;,   LY2 : real;,   Order As Boolean, ByRef x_return : real;, ByRef y_return : real;)
Dim a : real;, b : real;, c : real;, D : real;, E : real;, F : real;, G : real;, H : real;, x1 : real;, y1 : real;, x2 : real;, y2 : real;
Dim ang1 : real;, ang2 : real;
If Abs(LX2 - LX1) < 0.000001 Then    '直线为竖直时
   x_return = LX1
   y1 = (2 * CY + Sqr(4 * CY * CY - 4 * (CY * CY + (x_return - CX) * (x_return - CX) - r * r))) / 2
   y2 = (2 * CY - Sqr(4 * CY * CY - 4 * (CY * CY + (x_return - CX) * (x_return - CX) - r * r))) / 2
   PP2A CX, CY, x_return, y1, ang1
   PP2A CX, CY, x_return, y2, ang2
   If Order = True Then
       If ang1 < ang2 Then
           y_return = y1
       Else
           y_return = y2
       End If
   Else
       If ang1 < ang2 Then
           y_return = y2
       Else
           y_return = y1
       End If
   End If
Else                        '直线非竖直时
   E = (LY2 - LY1) / (LX2 - LX1)
   D = LY1 - E * LX1
   F = 1 + E * E
   G = 2 * CX - 2 * D * E + 2 * E * CY
   H = CX * CX + D * D - 2 * CY * D + CY * CY - r * r
   x1 = (G + Sqr(G * G - 4 * F * H)) / (2 * F)
   x2 = (G - Sqr(G * G - 4 * F * H)) / (2 * F)
   y1 = D + E * x1
   y2 = D + E * x2
   PP2A CX, CY, x1, y1, ang1
   PP2A CX, CY, x2, y2, ang2
   If Order = True Then
       If ang1 < ang2 Then
           x_return = x1
           y_return = y1
       Else
           x_return = x2
           y_return = y2
       End If
   Else
       If ang1 < ang2 Then
           x_return = x2
           y_return = y2
       Else
           x_return = x1
           y_return = y1
       End If
   End If
End If
上面这些是客户给我的函数..
我都给做到FB里面了..其实是应该做到函数里面去
调用起来更好一些.
最后修改:2019/10/10 23:11:10
19-10-10 23:10
在施耐德中:
函数与功能块的区别主要有以下3条:
1、内存分别:
函数没有指定的内存分配地址,而功能块全部数据都分配内存地址
2、输入输出变量
函数只允许一个输出变量,功能块允许多个输出变量或者没有输出变量。
3、调用关系:
函数可以调用函数,但是不能调用功能块,而功能块既可以调用函数,也可以调用功能块。
程序与功能块/函数的区别:
1、程序在资源中被实例化,程序的实例需要与任务结合,也就是分配给任务的程序才可以被执行。而功能块可以在程序中被实例化,也可以通过其他功能块被实例化。
2、程序可以调用程序,功能块与函数,功能块能调用其他功能块和函数,而函数只能调用函数。
3、不同的程序调用同一个程序时,它们的调用结果是区分的,不会因为被其他程序调用过后就改变了程序的值,而功能块无论被哪个程序调用,都会改变值。
明显的区别大概是以上的内容。
Good Luck~
19-10-11 10:28
受教了
19-10-11 11:11
函数是不能保存数据的,调用一次,返回结果,下次调用和这次没有任何关系,功能块可以保存数据。
19-10-11 12:57
这个厉害了,非常详细,受教了。
19-10-12 16:09
对..是否实例化是不是就是对  能否保存数据的一个说明
实例化了...就有了自己的数据区
函数就相当于 "move""eq""OR"那些指令..
19-10-13 08:19
你这个积分很6啊
附件 1.jpg
19-10-13 08:21
实例化就是程序的调用机制,函数肯定也要分配内存的,只是退出以后就收回了,数据保存不到下次调用。但功能块的内存会一直存在,累计值啥的就会继续。
19-10-17 09:29
是啊..就是会释放掉内存...
19-10-17 13:45
感谢0aguang0老师提供连接。感谢cvlsam老师解惑!
20-02-24 10:06

上一页下一页

工控新闻

更多新闻资讯