虽说ADS协议公开,但是我查了一番也只找到零星的资料,虽说项目完成了,但是在这里想要把自己积累的所有ADS协议的资料写出来,以供大家查阅。
目录
1.AMS Target Net ld和port 以及 AMS Sender Net ld和port
1.协议简介
ADS协议是倍福PLC的公开协议,基于TCP/IP进行收发。
ADS协议分为client 和 server端,client负责请求,server负责答复
2.ADS协议解析
注意:ADS 协议是大端在前。
1.ADS数据包格式如下
数据包 | 大小(bytes) | 描述 |
AMS/TCP Header | 6 | 包含了ADS Data的长度。 |
AMS Header | 32 | 此处包含了通讯的发送方和接收方地址,以及ADS错误代码、ADS命令代码和其他一些信息 |
ADS Data | N | 此处包含了一个ADS命令的参数。参数的数据结构由ADS命令所决定,一些ADS品令也可以没有附加的数据。 |
2.AMS/TCP Header
名称 | 大小(bytes) | 描述 |
起始 | 2 | 0x00 0x00 |
指令长度(4bytes) | 4 | 为整个ADS协议中减去AMS/TCP Header的指令的字节长度即32 + N |
3.AMS Header主体包格式
名称 | 大小(bytes) | 描述 |
AMS Target Net ld | 6 | 目标ID |
AMS Target port | 2 | 目标端口 |
AMS Sender Net ld | 6 | 发送者ID |
AMS Sender port | 2 | 发送者端口 |
CMD ID | 2 | 控制字 |
StateFlags | 2 | 状态字 |
Lenth | 4 | 数据域长度 |
ErrorCode | 4 | 错误代码 |
InvokeID | 4 | 通信计数,每次完成一次读写即加1 |
1.AMS Target Net ld和port 以及 AMS Sender Net ld和port
注意这里需要分清,设备的实际IP和端口并不是AMS Net ld和port。
ADS会给每个设备分配一个虚拟Id,假设目标实际IP和端口是10.100.173.2:48863
那么此时ADS会给设备分配虚拟ID AMS Net 为10.100.173.2.1.1
注意,这里不是直接在实际IP后加1.1就可以进行通讯,而是在TwinCAT路由中加入IP后才可以。
作为client端我们的AMS Net port可以随便写1-65535都可以,而若是作为server端我们的AMS Target Net port是固定的。
主要如下
端口号 | 设备描述 |
100 | 日志记录 |
110 | Eventlogger |
300 | IO |
301,302 | addtional Task1,2....(TC2) |
351,352 | addtional Task1,2....(TC3) |
500 | NC |
801,811,821,831 | PLC runtimeSystem1,2,3,4(TC2) |
851 | PLC runtimeSystem1,2,3,4(TC3) |
900 | Camshaft controller |
10000 | System Service |
1400 | Scope |
而协议中AMS Target Net ld是如何表现的呢?例如10.100.173.2.1.1
即将10,100,173,2,1,1转换为十六进制即0A 64 AD 02 01 01
假设AMS Target Net port是851,转换为十六进制即0x0353,转换为大端在前即0x5303
故可以知道AMS Header主体包格式中
AMS Target Net ld以及port即为
0A 64 AD 02 01 01 53 03
同理AMS Sender Net ld也是一样。
2.CMD ID
控制字,主要具有以下内容
Commnd | 描述 |
0x0000 | 无效 |
0x0001 | 读取ADS设备名称和版本号 |
0x0002 | 可以对ADS设备读取数据 |
0x0003 | 可以对ADS设备写入数据 |
0x0004 | 读取ADS设备的ADS状态和设备状态 |
0x0005 | 改变ADS设备的ADS状态和设备状态 |
0x0006 | 在ADS设备中创建一个通知 |
0x0007 | 在ADS设备中删除一个通知 |
0x0008 | 数据将独立的从ADS设备发送到ADS客户端 |
0x0009 | 可以对ADS设备写入数据,同时也能从ADS设备中读取数据 |
同样的,本部分也是大端在前,比如0x0001,实际写入的时候要转换成0x0100。
3.StateFlags
4.Lenth
数据域的长度,即ADS Data部分的字节长度,大端在前。
5.ErrorCode
这里的错误码内容非常多,建议大家可以直接看这些文章
倍福TwinCAT(贝福Beckhoff)常见问题(FAQ)-如何查看错误代码_0x4225倍福-CSDN博客
倍福TwinCAT3 Ads错误快查_twincat.ads.adsinitializeexception:鈥淎ds could not -CSDN博客
一般大家知道0x00000000代表无错误就可以。
同样大端在前
6.InvokeID
通信计数,每次完成一个数据读写后由数据请求方进行自增,回应方则直接在回应报文中将该字节返回。
4.ADS Data
数据域,在请求与回应帧中不相同,这里简单介绍。
1.请求
名称 | 描述 | 长度(bytes) |
IndexGroup | 寄存器 | 4 |
IndexOffset | 地址偏移 | 4 |
CbLength | 读取字节长度 | 4 |
IndexGroup主要有以下内容
IndexGroup | 描述 |
0x00004020 | M寄存器(用%M声明) |
0x00004021 | MX寄存器(用MX声明) |
0x0000F020 | I寄存器(用%I声明) |
0x0000F01 | IX寄存器(用IX声明) |
0x0000F030 | Q寄存器(用%Q声明) |
0x0000F031 | QX寄存器(用QX声明) |
0x0000F003 | 取变量句柄 |
0x0000F005 | 通过变量句柄访问变量值 |
0x0000F006 | 释放句柄 |
这里IndexGroup、IndexOffset、CbLength全都是大端在前。
2.回应
名称 | 描述 | 大小(bytes) |
Result | 即错误码 | 4 |
cblenth | data部分的字节长度 | 4 |
data | 数据 | n |
3.C语言读写库
这里写了一个C语言的ADS协议读写库,大家可以直接在文章开头链接下载使用。
4.类型读写
其实大家可以看到ADS协议中没有规定按照类型读取,实际上我们可以直接读取该类型的字节长度即可。
变量类型 | C++ | C# | 长度 |
INT | short | short,INT16 | 2 |
UINT | unsigned short | unsigned short,UINT16 | 2 |
DINT | int | int, UINT32 | 4 |
UDINT | unsigned int | UINT32 | 4 |
real | float | float | 4 |
LREAL | double | double | 8 |
string | char[81] | char[81] | 81 |
bool | bool | bool | 1 |