首先简单了解一下AG_SEND/AG_LSEND,AG_RECV/AG_LRECV(AG_SSEND我没用过,不做解释)
首先AG_SEND****和TSEND不一样,这是一个硬限制。
AG_SEND用于CP组态,而TSEND/TRCV适用于局域网内通讯(同网段)本次主要介绍CP组态的方式。
AG_SEND/AG_LSEND/AG_SSEND用于发送消息,一般发送指针,如下图:
上图中,ACT检测到上升沿后,会调用AG_SEND发送SEND管脚所指定的区域起,LEN管脚58个BYTE。
发送完成后DONE管脚会置1一个扫描周期,ERROR管脚与STATUS管脚显示块的状态信息。
其中ID与LADDR来源于组态中的地址,如下图:
AG_RECV\AG_LRECV\AG_SRECV用于接收数据,用法如下:
我们发现AG_LRECV没有ACT管脚,所以,只要EN使能来,此块每个扫描周期都会接收数据。
接收完成后LEN管脚会持续显示一个扫描周期的长度。
接收的数据将按顺序放到RECV管脚所指向的区域。
ID与LADDR管脚来源于组态。
一个表格解释功能:
以下图片介绍了在S7-300/400中CP通讯块的可用性。(帮助中说S7400无法使用AG_RECV,不知为何我却使用正常。)
以下图片介绍了在S7-300/400中CP通讯块所能通讯的字节数
好了,大概能了解,我们先说怎么用!
此系列块共包含三个基本块。AG_CNTEX、AG_SEND、AG_RECV。
根据不同情况可以延伸出AG_LSEND\AG_LRECV\AG_SSEND\AG_SRECV……
先说AG_CNTEX:
用于进行连接诊断的指令 |
下面是官方给的一个指令,这里我最多用到的就是重连,重连的方式就是
ACT置位,CMD管脚写6,断开连接后,等待一秒钟写7,然后CMD写0,复位ACT
更多指令请查看编程器帮助。
我的设备信息如下:
Ps1:关于字节发送长度的问题。
通过表格可以看到AG_SEND在S7-400中可以发送最长240个BYTE。所以,超过240个BYTE时我们就要使用AG_LSEND,在使用的过程中,当使用AG_LSEND发送数据时,字节长度小于241时无法发送成功,后来交流可能是因为CP版本问题,所以将所有的字节长度最小长度为241BYTE,可以正常发送。
上图中,我通过上升沿制定了LEN管脚,发送的区域为2900BYTE,只取LEN来发送时,必须设置大于241BYTE及以上。
由于我发送的字节数长且多变,其中长字节为周期性发送,所以需要通过时钟或者计数器将发送时机间隔开来(AG_SSEND可以大大提高发送效率,但是我正好是1453个字节,白搭了。)
或者,使用DONE信号来复位,如果报文触发条件多,写起来也会比较复杂,暂时没有想到更好的写法,只能通过联锁来保证数据不冲突。
如果不间隔,可能会导致重发或者粘包,会很麻烦,我发送的字节长度在2000BYTE左右,仍然建议时间间隔在4秒左右。
比如下图
Ps2:关于接收的问题。
官方帮助文档说S7400无法在TCP连接上使用AG_RECV接收数据,不知为何我可以正常使用的,但以后尽量避开使用,有一个特别难受的问题我也是踩坑得出。
譬如:使用AG_RECV接收的数据接收到一个DB区域,譬如我接收到
P#DB2050.DBX3540.0 BYTE 58
如果我收到的数据是60位,怎么办?当然这得提前做好,不能够接收区域比字节长度短吧!
如果我收到的数据是1位呢,那你整个数据区域全都是这一位。
如果是两位,会自然填充,直到填满。所以,有两种解决方案:
一、接收到数据立刻转移并清空该区域数据。
二、保证数据长度一致。
AG_SEND/AG_RECV系列指令使用至此算是完成。更多坑仍需摸索。
如有错误欢迎指正。