本篇是PTP系列的第四篇。前三篇是本篇的基础。
我们知道,任何通讯协议都是有层次的,最知名的是ISO的7层协议。我们给PLC的通讯编程也需要分层,不过无需严格按照7层协议来分。以我的经验,只要是稍微复杂的通讯,就需要给程序分层,这样有利于各个层级之间划分责任,有利于bug查找,有利于简化编程。一个好的例子是PTP的2吃,在本站的另一篇文档中讨论了1个PTP模块同时完成232与485的实时通讯。
在本系列文档的第一篇讨论的是发送接收这个层次的问题。第二篇讨论的是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体现了前文所述的思想:程序要分层以及各层内部的连锁。
上文我们讨论过,调度AA代码的层级要高于AA。体现在上图中,就是层级高的代码往往会调用层级低的代码。高层代码和低层代码之间还有一种联系方式:高层的代码通过数据触发低层代码执行。无论是这2种中的哪一种,效果就是高层的代码通过手段触发低层的代码。
各位有没有注意到。本系列的主题是通讯,但是本文档通篇没有提及发送和接收。这也体现了编程的层级,因为发送接收在其他篇已经说了,不是这一层级需要讨论的问题。
写到这里,感觉内容已经不少了。所以先写到这里吧。如果各位同行对本篇所讲的内容有什么疑问,可以在这里留言。