本篇是PTP系列的第四篇。前三篇是本篇的基础。我把我相关的帖链接复制如下。
https://www.ad.siemens.com.cn/club/bbs/post_1972159_66_0_0.html#anch
https://www.ad.siemens.com.cn/club/bbs/PostStory_1963674_80.html#anch
https://www.ad.siemens.com.cn/club/bbs/PostStory_1963999_80.html#anch
https://www.ad.siemens.com.cn/club/bbs/PostStory_1964253_80.html#anch
我们知道,通讯是需要分层次的,最知名的分层是通讯的ISO的7层协议。我们普通给PLC的PTP编程也需要分层,不过无需严格按照7层协议来分。以我的经验,只要是稍微复杂的 通讯,就需要给程序分层,这样有利于各个层级之间划分责任,有利于bug查找,有利于简化编程。
第一篇讨论的是发送接收这个层次的问题。第二篇讨论的是AA,AA用于管理发送和接收的问题。AA比收发又高了一个层次。第三篇讨论的是轮询,也就是如何让多个AA不冲突的完成工作,显然轮询的层次高于AA。
分层后,要考虑每一层的连锁信号。
第一层的连锁已经在第一篇中讲清楚了,这里不再赘述。
第二层AA要考虑对话的打开和关闭。
第三层轮询或者事件触发就要考虑各个AA之间关系。
如果是轮询,那么要考虑通过轮询号码的方式使得在某一个特定时刻,只能有一个AA处于OPEN的状态。
如果是事件触发,那么程序要兼容轮询触发和事件触发。这就衍生出了一种轮询和事件混合触发。比如一AA的触发条件是当变量b有上升沿时触发。这很常见。但是完全有可能当b处于上升沿时刻,其他的AA在OPEN,所以暂时不能让触发的AA打开。这怎么办呢?我们可以给这个触发的AA也编一个轮询号码,比如是280。当轮询到280时,如果触发条件有效,那么本AA才进入OPEN状态。也就是说,这个AA进入OPEN状态有2个条件,一个是轮询号码与本AA的轮询号码一致;另一个条件是有触发条件。那么还有一种情况,就是如果轮询号码是本AA,但是没有触发条件怎么办?那么就在这个AA中把下一个轮询号码赋值给轮询号码。这就意味着本AA不会OPEN,下一个轮询号码的AA就具备OPEN的条件之一了。我们举个例子,这个例子是一种射频电源的通讯。

上图network 5到13共有9个AA。因为射频电源的通讯能力有限,每次只能处理一个通讯任务。所以程序的设想是这9个AA在任何一个时点只能有一个AA处于OPEN状态。其中有些是读取指令,有些是写入指令。读取指令每个轮询周期都需要执行,写入指令只有在上升沿时才触发。面对这种需求,采用的就是上文所述的混合指令。拿出2个AA举例说明。

Network6是普通的轮询。因为是查询指令,查询射频电源的偏压。这属于读取。读取永远都要执行,所以这个AA属于轮询触发型。Network 9的AA的功能是给电源运行指令。一旦运行后,无需再次给出指令,所以这个AA属于事件触发型。这2类FB块内部都调用了相同的AA块,所以在这里我们模糊的都称为AA。这2类AA有共同的特点,就是定义了本AA的轮询号码(PollingNo_This),下一个AA的轮询号码(PollingNo_Next)。除此以外,事件触发型AA还有一个Trigger引脚。这个引脚用于更高层的程序或者人机界面来的指令。
下图给出了事件触发型AA内部的程序。

这个FB体现了前文所述的思想:程序要分层、各层内部的连锁。各位有没有注意到。本篇的主题是串口自由通讯,但是通篇没有提及发送和接收的。这也体现了编程的层级,因为发送接收在其他篇已经说了,不是这一层级需要讨论的问题。
写到这里,感觉内容已经不少了。对于没有建立分层及同层内部连锁思想的同行来讲,本篇的内容已经有些复杂了。所以先写到这里吧。如果各位同行对本篇所讲的内容有什么疑问,可以在这里留言。
再补充一点。两层之间的程序靠数据进行联络。比如,触发的例子。上层程序或者人机界面通过标志位置位trigger引脚。通讯层收到信号后复位该信号,并执行该命令。