最近在做的项目就是使用如下协议对200PLC进行数据读写的,基本上可以完成读写功能(T、C这两种类型暂时还没有成功,正在查找原因)。
上位机按如下的格式发读写指令,PLC作出接收正确的响应(返回应答数据E5H或F9H见下文分析),上位机接到此响应则发出确认命令(10 02 5C 5E 16),PLC再返回给上位机相应数据。
SD LE LEr SD DA SA FC DSAP SSAP DU FCS EDSD:开始符(68H) LE、Ler:长度(从DA到DU)
DA:目的地址 SA:源地址
FC:功能码 (6CH) DSAP:目的服务存取点
SSAP:源服务存取点 DU:数据单元
FCS:校验和 ED:结束符(16H)
3.1 读命令分析
一次读一条数据
对于一次读取一个数据,读命令都是33个字节。前面的0—21字节是相同的,为 :
68 1B 1B 68 02 00 6C 32 01 00 00 00 00 00 0E 00 00 04 01 12 0A 10
因为是单片机上发的读PLC数据的命令,SA=00,DA=02,如果有多个站,DA要改成相应的站号。读命令中从DA到DU的长度为1B即27个字节。从22字节开始根据读取数据的类型、位置不同而不同。表一是读不同存储器命令的Byte22—32。
字节 22 23 24 25 26 27 28 29 30 31 32
功能 读取长度 数据个数* 存储器类型 偏移量 校验 结束
读q0.0 01 00 01 00 00 82 00 00 00 64 16
读m0.0 01 00 01 00 00 83 00 00 00 65 16
读M0.1 01 00 01 00 00 83 00 00 01 66 16
读SMB34 02 00 01 00 00 05 00 01 10 F9 16
读VB100 02 00 01 00 01 84 00 03 20 8B 16
读VW100 04 00 01 00 01 84 00 03 20 8D 16
读vd100 06 00 01 00 01 84 00 03 20 8F 16
读i0.5 01 00 01 00 00 81 00 00 05 68 16"
读i0.7 01 00 01 00 00 81 00 00 07 6A 16"
表 一 读命令的Byte22-32
从表中我们可以得出以下结果:
Byte 22 读取数据的长度
01:1 Bit 02:1 Byte
04:1 Word 06:Double Word
Byte 24数据个数,这里是01 ,一次读多个数据时见下面的说明。
Byte 26 存储器类型,01:V存储器 00:其它
Byte 27 存储器类型
04:S 05:SM 06:AI 07:AQ 1E: C
81:I 82:Q 83:M 84:V 1F: T
Byte 28,29,30存储器偏移量指针(存储器地址*8),如:VB100,存储器地址为100,偏移量指针为800,转换成16进制就是320H,则Byte 28—29这三个字节就是:00 03 20。
Byte 31 校验和,前面已说到这是从(DA+SA+DSAP+SSAP+DU) Mod 256 。
一次读多条数据
对于一次读多个数据的情况,前21Byte与上面相似只是长度LD,LDr及Byte 14不同:
Byte 14 数据块占位字节,它指明数据块占用的字节数。与数据块数量有关,长度=4+数据块数*10,如:一条数据时为4+10=0E(H);同时读M,V,Q三个不同的数据块时为4+3*10=22(H)。
Byte 22 总是02 即以Byte为单位。
Byte 24 以字节为单位,连续读取的字节数。如读2个VD则Byte24=8
Byte 19---30 按上述一次读一个数据的格式依次列出,
Byte 31---42 另一类型的数据,也是按上述格式给出。
以此类推,一次最多读取222个字节的数据。
3.2 写命令分析
一次写一个Double Word类型的数据,写命令是40个字节,其余为38个字节。
写一个Double Word类型的数据,前面的0—21字节为 :
68 23 23 68 02 00 6C 32 01 00 00 00 00 00 0E 00 00 04 01 12 0A 10
写一个其它类型的数据,前面的0—21字节为 :(与上面比较,只是长度字节发生变化)
68 21 21 68 02 00 6C 32 01 00 00 00 00 00 0E 00 00 04 01 12 0A 10
从22字节开始根据写入数据的值和位置不同而变化。表二是几个写命令的Byte22—40。
字 节 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
写入位置及值 长度 个数 类型 偏移量 位数 值、校验码、结束符
M0.0=1 01 00 01 00 00 83 00 00 00 00 03 00 01 01 00 71 16
M0.0=0 01 00 01 00 00 83 00 00 00 00 03 00 01 00 00 70 16
M0.1=1 01 00 01 00 00 83 00 00 01 00 03 00 01 01 00 72 16
vb100=10 02 00 01 00 01 84 00 03 20 00 04 00 08 10 00 AE 16
vb100=FF 02 00 01 00 01 84 00 03 20 00 04 00 08 FF 00 9D 16
VW100=FFFF 04 00 01 00 01 84 00 03 20 00 04 00 10 FF FF A6 16
VD100=FFFFFFFF 06 00 01 00 01 84 00 03 20 00 04 00 20 FF FF FF FF B8 16
表二 写命令的Byte22—40
经分析我们可以得出以下结果:
Byte 22-- Byte 30 写入数据的长度、存储器类型、存储器偏移量与读命令相同。T,C等不能用写命令写入。
Byte 32 如果写入的是位数据这一字节为03,其它则为04
Byte 34 写入数据的位数
01: 1 Bit 08: 1 Byte 10H: 1 Word 20H: 1 Double Word
Byte 35--40值、校验码、结束符
如果写入的是位、字节数据,Byte35就是写入的值,Byte36=00,Byte37=检验码,Byte38=16H,结束。如果写个的是字数据(双字节),Byte35,Byte36就是写入的值, Byte37=检验码,Byte38=16H,结束。如果写个的是双字数据(四字节),Byte35—38就是写入的值, Byte39=检验码,Byte40=16H,结束。
3.3 其它命令分析
强制写入
I、Q、S 等不能使用上述的写命令写入数据,只能用强制写入的方式。
前0—35字节值如下(长度字段要根据实际情况而定),需要注意的是Byte8=07,
68 2B 2B 68 02 00 6C 32 07 00 00 00 00 00 0C 00 12 00 01 12 08 12 48 0B 00 00 00 00 00 FF 09 00 0E 00 01 10
后面的内容如下:
Byte 32 占位字节,从下一字节开始到校验和前的字节数。说明同读数据的Byte 14.
Byte 36 强制写入数据的长度
01:1 Bit 02:1 Byte
04:1 Word 06:Double Word
Byte 38 数据个数,这里是01 ,一次强制写多个数据时见下面的说明。
Byte 40 存储器类型
Byte 41 存储器类型,见读命令的说明。
Byte 42、43、44存储器偏移量指针(存储器地址*8)
Byte 45、46、47、48 值、校验码、结束符
取消强制写
强制写入I、Q 等后,这些值就不能被程序改变,除非使用”取消强制命令”。 取消强制命令的格式与强制写入相似,变化的有以下几点:(1)是没有”值”这一段,即没有Byte45—48。这影响到长度字节LE,LEr;占位字节Byte 32.(2)Byte16=10H, (3) Byte32=0CH,也就是第一条,没有”值”这一段,数据块长度变短了。
对于一次强制写入或取消多个数据的情况可以参照写入命令写出相应的报文,这里不再给出。
STOP命令
STOP命令使得S7-200 CPU从RUN状态转换到STOP状态(此时CPU模块上的模式开关开应打在RUN或TERM位置)。PC发出如下命令,PLC返回F9,此时PLC已进入等待状态,PC再发确认报文(10 02 5C 5E 16),完成一个命令过程。
68 1D 1D 68 02 00 6C 32 01 00 00 00 00 00 10 00 00 29 00 00 00 00 00 09 50 5F 50 52 4F 47 52 41 4D AA 16
RUN 命令
RUN命令使得S7-200 CPU从STOP状态转换到RUN状态(此时CPU模块上的模式开关开应打在RUN或TERM位置)。PC发出下命令,PLC返回F9,此时PLC已进入运行状态,PC再发确认报文(10 02 5C 5E 16),完成一个命令过程。
68 21 21 68 02 00 6C 32 01 00 00 00 00 00 14 00 00 28 00 00 00 00 00 00 FD 00 00 09 50 5F 50 52 4F 47 52 41 4D AA 16
3.4 读出数据分析
一次读出一条数据
PLC响应的数据也是用PPI封装的。如果用一次读一条数据命令,响应的报文中就只包含一条数据,此响应报文的Byte16<=8。
Byte 04:DA=00 Byte 05:SA=02 即从02 PLC站发往PC。
Byte 16:数据块占位字节,从Byte21到校验和前的字节数。
一条数据时:Word=06 Double Word=08 其它为 05。
Byte 22:数据类型,位=3,其它=4。
Byte 24:数据宽度,Bit=01,Byte=08,Word=10H,Double Word=20H
Byte 25—28:值。
如果网络上只可能有一个站会发回响应报文,那么可以简单的根据LE长度字节判断返回值的位置:LE=16H,返回值是字节,或位类型的值,响应报文的Byte 25即是返回值;LE=17H,返回值是字(双字节)类型的值,响应报文的Byte 25,26即是返回值;LE=19H,返回值是双字(四字节)类型的值,响应报文的Byte 25—28即是返回值。更准确的方式是要根据返回报文的SA,DA,及存储器位置等信息识别目标地址和源地址,确认是这次申请的返回数据,然后经过校验检查,得到正确的数据。
一次读出多条数据
如果用的是一次读多条数据的命令,响应的报文中就包含有多条数据。这些数据只有类型参数,没有偏移量参数,所以要注意根据读命令的顺序将其一一对应起来。
Byte 16:数据块占位字节,从Byte21到校验和前的字节数,与数据块数量和类型有关。
Byte 20:数据块的个数。
Byte 21 开始为数据块,每一个数据块都以FF 04开始,接下来的两个字节表示这一数据块的长度,以位计算,然后依次是连续的数据。下一个数据块也是以FF 04开始,重复上述格式,直到结束。
上位机与PLC通讯时,上位机采用485芯片与PLC的编程口连接,,遵循PPI协议,主从式的通讯方式,一次读写操作的步骤包括:首先上位机发出读写命令,PLC作出接收正确的响应(返回应答数据E5H),上位机接到此响应则发出确认命令(10 02 5C 5E 16),PLC完成正确的读写响应,返回给上位机相应数据。这样收发两次数据,完成一次数据的读写。那么我们就可以利用上述PPI协议,读写S7-200PLC中的各种类型数据,包括I、Q、SM、M、V、S、T、C(T、C这两种类型暂时还没有成功,正在查找原因)等数据类型,能够直接读出以上变量中的位、字节、字、双字等,(其中读位变量时,实际是读取该位所在的字节值)。可以改变PLC的运行状态(RUN/STOP)。 在编程时,最好将读取的检测值、输出值等数据,存放在PLC的一个连续的变量区中,当上位机读取PLC的数据时,就可以一次读出这组连续的数据,减少数据的分次频繁读取。当修改设定值等数据时,进行写数据的通讯操作。