来自西门子技术支持热线的故事:关于在FC块中使用--(P )RLO上升沿检测指令的一个小故事

已锁定

西门子Auto

官方工程师

  • 帖子

    132
  • 精华

    16
  • 被关注

    227

论坛等级:侠圣

注册时间:2007-08-03

普通 普通 如何晋级?

来自西门子技术支持热线的故事:关于在FC块中使用--(P )RLO上升沿检测指令的一个小故事

9697

28

2011-04-13 14:02:44

最近在热线上遇到了一个FC 块中使用--(P )RLO 上升沿检测指令导致不能正常计数的编程问题,程序及使用的指令都比较简单,但该问题是大家比较容易忽略的,也比较具有代表性,这里和大家分享一下。
客户:我有一个关于编程的问题百思不得其解,需要你们的帮助。
我:能具体说一下吗?(呃,看来又是一个比较难的问题!)
客户:其实程序比较简单,我把程序放在OB1 中计数没问题,但在FC1中使用形参定义后再在OB1 中调用FC1时计数就不正常,多计了好多数?
我:是否有地址重复使用的情况?
客户:没有。
我:FC1在程序中是否多次调用的情况?是否在FC1 中使用的Temp 变量?
客户:没有,很简单的一个程序,项目中只有OB1, FC1并且只调用一次。
OB 1 中是一个使用时钟存储位M0.5(一秒发一次脉冲),串一个捕捉上升沿指令—(P),再跟一个计数指令。FC1 中是定义 两个in 变量, 再跟一个计数指令。OB1中的程序计数正常, 在FC1 中计数就不正常。已经反复试过多次了,不信你可以试试?
我:(在我的记忆里,如果P 指令的地址有重复使用的或在FC 中使用了Temp 变量又多次调用可能会出现计数不正常的情况,但客户肯定了没有这些情况,只有试试了!)。
我:在step7 中创建 FC3 及在OB1 ( 如下图1),使用S_CU(增计数指令)测试程序,一切正常,没有问题啊!


图1
我:(赶紧联系客户)已经测试,计数值正常啊?向客户描述编程过程。
客户:使用计数器指令S_CU是正常的,但如果使用加法指令(ADD_I),检测上升沿,数值自加1时,在FC 中编程程序就不正常了。
我: (??,不太可能吧!)再次与客户核实编程的步骤,使用的指令及在FC 中定义的变量类型。(客户的编程过程没问题啊?),那我再按您的方法再试试吧!
我:再次测试:在OB1 中直接编写计数程序(见图2)


图2
创建FC1,在FC1 中定义形参编写计数程序,再在 OB1 中调用(见图3)


图3
我: (计数值果然不同,问题到底出现在哪呢?)
忽然想起客户在FC中定义的( P )指令为IN 变量,IN 变量只能接收从外部输入的信号状态,不能再写入,而且FC 中IN 变量占用的是临时变量,无法保存状态,而(P) 指令是边沿存储位(见图4),不但要检测RLO 的状态,而且需要将操作之前的状态存储到该地址中,也就是需要再次写入该地址中。


为了更清楚的发现问题,将FC1程序转换为STL(语句表),可以看到M10.0的状态写入到临时堆栈区L20.1,FC1 也只是读L20.1的状态,并没有把 L20.1的状态写回到M10.0 ( 见图5 )。


于是将程序做如下修改(见图6),将L20.1 的状态写回到M10.0, 测试发现可以正常计数。所以(P)--RLO 上升沿检测指令定义为IN 变量是不行的,应该定义为IN_OUT 变量,既可以读又可以写。


于是创建FC2,在 FC2 中将 --(P)指令的变量声明 为IN_OUT 变量(见图7),再次测试,计数值正常,问题解决。


(其实,到此为止,该问题应该可以解决了,只要告诉客户将 --(P)指令的变量声明由IN 改为IN_OUT 就可以解决问题,但是令我无法想通的是为何使用计数器(S_CU) 时将 --(P)指令定义为IN 变量就可以计数正常呢?如果客户近一步追问该如何解释呢?)为了能够彻底将问题搞清楚,决定继续研究一下。
先看看S_CU 与ADD_I 指令之间的区别:
S_CU :内部有脉冲边沿检测功能,只要输入端有0到1 变化,计数器就加1。所以下面计数器指令中(图8),实际上是不需要加 (P) 指令同样可以进行计数。


图8
ADD_I:内部没有边沿检测指令,EN 端只要为1, IN1与IN2 就会一直进行相加。


图9
根据— ( P) 指令的解释,每个扫描过程中, RLO 位的信号状态都前一周期获得的结果进行比较,看信号状态是否有变化。 前一周期RLO 的信号状态必须保存在边沿标志位( 例如 M10.0 见图5)中,以进行比较。如果当前与先前的RLO”0” 状态之间有变化,则在操作之后, RLO 将为1。当M0.5 由0变为1 时, M10.0 为0,与之前的逻辑结果比较(之前的RLO =0),发生了变化,所以 RLO=1,此时ADD_I 即会执行加1。由于M0.5 是1秒发一个脉冲,占空比是1:1,在M0.5 为1 的期间,由于M10.0 为IN 变量,并没有将上次的逻辑结果RLO=1写入M10.0,仍然保持了M10.0=0 的状态,所以当下个扫描周期时,程序都认为上一次的RLO=0,当前的RLO=1,所以在M0.5 为1时加法指令会一直执行执行,计数值增加 ( ADD_I 加法指令是只要使能端EN=1,就会一直执行执行),S_CU 由于有检测边沿的功能,所以计数正常。

到此,问题全部搞清楚,联系客户告诉客户解决方案,将— (P)变量声明由IN更改为IN_OUT 。( 呵呵,准备了半天,客户居然没有追问为何使用S_CU 时将P 定义为IN 变量为何可以正常计数。但是为了帮客户彻底弄清问题,避免以后再出问题,还是多花了些时间解释了一下。 )
虽然是个很简单的程序,但解答的过程还是颇费周折的,也花了不少时间测试。其问题关键是要正确理解 -- ( P) RLO 上升沿检测指令的含义,而且在编程时还是需要更加关注细节,注意各个指令使用条件的不同,同样-- (N) RLO 下降沿检测指令使用时也需要注意同样的问题,在FC 中定义形参时要定义为IN_OUT 变量,特此与大家共同分享!
来自西门子技术支持热线的故事:关于在FC块中使用--(P )RLO上升沿检测指令的一个小故事 已锁定
编辑推荐: 关闭

请填写推广理由:

本版热门话题

SIMATIC S7-300/400

共有54049条技术帖

相关推荐

热门标签

相关帖子推荐

guzhang

恭喜,你发布的帖子

评为精华帖!

快扫描右侧二维码晒一晒吧!

再发帖或跟帖交流2条,就能晋升VIP啦!开启更多专属权限!

top
您收到0封站内信:
×
×
信息提示
很抱歉!您所访问的页面不存在,或网址发生了变化,请稍后再试。