签到有奖
消息提醒
运维工程师专区
官方商城
点击复制链接
关注该帖后,有多人参加探讨会对您通知与提示!
帖子
精华
被关注
论坛等级:游侠
注册时间:2015-09-04
普通 如何晋级?
12691
43
2022-11-18 16:59:11
出现问题的原理:
当数据块在优化访问模式时,DB变量作为输入输出参数,对其进行访问。在此情况下,数据是用复制模式传送的。运算数据复制后,即使数据未改变,也会在数据块结尾处再次写入回该数据。因此,在数据块过程中HMI系统写入的数据会丢失。
西门子手册:
2.6.5优化和非优化访问的块之间的参数传输
当将结构作为输入/输出参数(InOut)传输到被调用块时,它们默认作为引用传输
但是,如果其中一个块具有“优化访问”属性而另一个块具有“默认访问”属性(我翻译一下,就是FB块和IN/OUT的形参数据一个为优化访问快,一个为非优化访问快),则情况并非如此。在这种情况下,所有参数通常作为副本传输(参见第3.3.1章按值调用)。
在这种情况下,被调用块始终使用复制的值。在块处理期间,这些值可能会更改,并且在处理块调用后将它们复制回原始操作数。
如果原始操作数被异步进程(例如,被HMI或中断OB访问)更改,这可能会出问题。如果在块处理之后将复制的值复制回原始操作数,则原始操作数上异步执行的更改将被覆盖。
实际编程问题:
1513 CPU,
建立一个FB1块(优化访问块),一个IN/OUT接口 ,UDT_AA;
建立一个DB10块(非优化访问快,UDT_AA)DB变量作为输入输出参数
我通过WINCC 或者PLC的监控与强制表,去操作DB块,那么由于调用了FB1, 然后形参使用了DB10。那么会出现操作失败的现象。
比如10bool变量赋值1,赋值0。经常会出现,只能赋值9个,另外有一个无法赋值成功,随机发生。
求助的最终问题:
如果FB和DB 都是优化访问快,或者非优化访问快,则不会出现这个问题。
FB是优化块,INOUT接口参数是非优化块,所以是传值而非传引用
所以问题就是由于一个是优化,一个是非优化,所以IN/OUT变成值传递了。能不能通过VARIANT的什么办法,改成指针传递,然后如何可以解决问题。
资料1:
这个似乎是一个官方的回复,但是有点不理解。
https://support.industry.siemens.com/cs/document/109476062/%E5%BD%93%E4%BD%BF%E7%94%A8-hmi-%E5%8F%98%E9%87%8F%E4%BD%9C%E4%B8%BA%E5%9D%97%E8%BE%93%E5%85%A5%E8%BE%93%E5%87%BA%E5%8F%82%E6%95%B0%E6%97%B6%EF%BC%8C%E4%B8%BA%E4%BB%80%E4%B9%88%E6%9C%89%E6%97%B6%E4%BC%9A%E5%87%BA%E7%8E%B0%E9%80%9A?dti=0&lc=zh-CN
文中提到的补救方法:在共享数据块中定义变量,并且使用共享DB块变量作为块参数。
我理解他的意思是共享数据块也为优化访问快,但是上位机给的命令,怎么给到这个共享的优化访问快呢?
资料2
https://support.industry.siemens.com/cs/document/109478253/%E4%B8%BA%E4%BB%80%E4%B9%88%E5%9C%A8-s7-1500-%E4%B8%AD-hmi-%E7%B3%BB%E7%BB%9F%E6%88%96-web-server-%E7%9A%84%E6%95%B0%E6%8D%AE%E6%9C%89%E6%97%B6%E4%BC%9A%E8%A6%86%E7%9B%96%EF%BC%9F?dti=0&lc=zh-WW
资料3
https://www.ad.siemens.com.cn/club/bbs/PostStory.aspx?a_id=1536064&b_id=84
资料2,和资料3,都是说建立两个平行的相同的数据块,HMI操作一个DB,程序操作一个DB。
但是两者数据的交互是个大问题呀,如果在FB的开始,将HMI的数据传给程序的DB,FB结束将程序DB给到HMI的DB。
这意味着在块运行期间,操作数(或操作数的一部分)的异步改变(通过 HMI 写访问或者更高优先等级的运行系统)将会丢失,因为块被调用后,操作数的值会被覆盖。
解决方案与总结!!!
1.FB和DB块数据,通过优化和非优化之间使用IN/OUT,一定有概率会出现从DB块里面写值,会因为在FB块内部运行被覆盖的现象。
FB的运行机理,
1.传入:值传递:IN,IN/OUT,将数据传递到FB块的一个临时区域。需要使用就拿实例化的数据。
引用传递:IN,IN/OUT,将数据的地址传递到FB块一个临时区域。需要使用的时候直接寻找原始数据,
2.运行:运行FB块内部程序。
3.传出:值传递:Out、N/OUT,在FB块运行结束后,将运算完的数据发送到临时区域,临时区域传出。(问题在这,比如一个数据DB_A数据,在FB运行期间被HMI修改为1,但是由于在第1步之前没有得到数据,临时区域还是0,所以在FB结束,传出的时候,会由临时区域的0进行输出,将DB_A进行写0,从而覆盖了HMI的修改1的操作)
引用传递:Out、N/OUT,在FB运行期间任何时刻实时输出数据。
如何避免
2 .比如一个FB块,里面完成了很复杂的工艺,代码量很大。优化和非优化之间,这种情况一定不能使用IN/OUT。这种大概率会出问题。
但是我想到了一个办法。
1.在FB开始的地方通过Varint的方法,将数据传递进来(此时是引用传递),然后将数据存储到Temp。
2.在输出的地方(FB的末端)拿Temp和指针进行比较,如果两个值相等才进行输出
3.如果是一个阀门库,电机库这种数据,还是可以通过优化和非优化之间使用IN/OUT。因为这个FB块所需要运行的时间相对于整个程序的扫描周期来说,是极短的,概率极低出现这种赋值失败的现象。
2023.07.18
抱歉各位前辈,我以为提供解决方案和总结,就应该结帖了。但是好景不长,现在发现当中断块在执行的时候进行赋值,即便通过Varint引用传递的时候。 依旧出现不成功的现象。我还在找原因,会继续更新。
剩余80%未阅读, 请登录阅读
请填写推广理由:
2026共启We来,驰骋工控路,领跑新征程
助你技有所长,论有所获
首次发帖探讨工控技术话题 立获新人礼包,100中奖哦! (包含周边、书籍、兑奖西币)
共有10698条技术帖
恭喜,你发布的帖子
快扫描右侧二维码晒一晒吧!
再发帖或跟帖交流2条,就能晋升VIP啦!开启更多专属权限!
分享
只看 楼主
欢迎您访问支持中心!
丰富的视频,全方位的文档,大量的网友交流精华……
为了更好的完善这些内容,我们诚邀您在浏览结束后,花20秒左右的时间,完成一个用户在线调查!
感谢您的支持!