1、Siemens PPI协议分析西门子 S7-200 PLC之间或者 PLC与 PC之间通信有很多种方式:自由口,PPI方式,MPI 方式,Profibus 方式。使用自由口方式进行编程时,在上位机和 PLC中都要编写数据通信程序。使用 PPI协议进行通信时,PLC 可以不用编程,而且可读写所有数据区,快捷方便。这也是我们之所以要研究、找出 PPI协议的源动力!下面我们就要说说分析的方法了!西门子的 STEP 7 MicroWIN 是用于 S7-200系列 PLC的开发工具,它使用PC机上的 COM口通过一条 PC/PPI编程电缆连到 PLC的编程口上。这说明,PC实际上是可以通过串口同 S7-
2、200 CPU通讯。只是我们不知道通讯协议而已。通过截获 PC机串口上的收发数据,对照 Step 7软件发出的指令,我们就有可能分析出有关指令的报文和通讯方式;然后,直接通过串口向 PLC发送报文,以验证这些指令报文是否正确。本着这一思想,我们采用以下步骤获得这些报文。PC与 PLC采用主从方式通讯,PC 按如下文的格式发读写指令,PLC 作出接收正确的响应(返回应答数据 E5H或 F9H见下文分析),上位机接到此响应则发出确认命令(10 02 5C 5E 16),PLC 再返回给上位机相应数据。一般上位机要连接 PLC就要先发送如下寻呼数据 10 02 00 49 4B 16 同志们呐!我们
3、可都是有血、有肉、有思想、有灵感的高级动物啊,面对这么多枯燥、无味、复杂、混乱的机器数字你怎么记呢?反正我是记不住啊!(_开始洗脑)这时你可以闭上眼睛,安静、静、再静。想一想战争时期的战地对讲机通话模式,那么这个指令(10 02 00 49 4B 16)就可以理解为:00 呼叫 02,听到请回答。 10 起始符 02 是上位机要联系的下位级的地址站号,就是要找的人 00 就是上位级本本身自己的站号 49 寻呼指令 16 终止符 其中 4B为校验码,是这样得来的:02+00+49 的最后两位就是校验码,这就是所说的偶校验或称和校验也称余校验,因为取的是余数。计算器在 16进制计算时公式(02+0
4、0+49)mod 100得出的数就是校验码,你计算一下是不是等于 4B啊!其他的所有 PPI协议校验都是如此。假如 02站号的 PLC收到寻呼信号那么会回答: 10 00 02 00 02 16 意思是:报告 00 ,02 收到,请指示 这样的解释是不是有意思啊!你有更好的解释吗?接下来呢,找到了要寻呼的人 PC就是司令啦就可以发号施令了,发号施令后 PLC正确接收后就会发送 E5 字符,意思是:“02 洞两明白”。其实啊,说到这里 PLC只说他明白,他已经明白了上位机 PC的指示,但并没有执行命令,那么要怎么他才执行命令呢?就是上位机 PC发出确认命令后才执行。这时上位机会发出(10 02
5、5C 5E 16),意思是:“请立即执行”。然后PLC就干他应当干的工作了啊!原来 PLC也不容易啊,怪不得叫下位机呢!说了这么多乱不乱呐!目的就是要理清上下级关系、主从关系,指令的顺序,用一个好的记忆方法记住枯燥无味的机器码。读命令分析:一次读一条数据SD LE LER SD DA SA FC DASP SSAP DU FCS ED SD:(Start Delimiter)开始定界符(68H)LE:(Length)报文数据长度LER:(Repeated Length)重复数据长度SD: (Start Delimiter)开始定界符(68H)SA:(Source Address)目标地址,指该
6、地址的值,就是 PLC的地址DA:(Destination Address)本地地址,指该地址的指针,就是上位机自己的地址FC:(Function Code)功能码,5CH 为交替周期触发,6CH 为首次信息周期触发,7CH为交替周期触发。DSAP:(Destination Service Access Point)目的服务存取点SSAP:(Source Service Access Point)源服务存取点DU:(Data Unit)数据单元FCS:(Frame Check Sequence)校验码ED:(End Delimiter)结束分界符(16H)报文数据长度和重复数据长度为自 DA至
7、 DU的数据长度,校验码为 DA至 DU数据的和校验,只取其中的末字节值关于这个校验码的计算方法同上面说明。在读写 PLC的变量数据中,读数据的功能码为 6CH,写数据的功能码为 7CH。对于一次读取一个数据,读命令都是 33个字节。前面的 021字节是相同的,为 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21SD LE LER SD DA SA FC开始符长度长度开始符站号源地址功能码协议识别远程控制冗余识别冗余识别协议数据单元参考参数长度参数长度数据长度数据长度04读05写变量地址数68 1B 1B 68 02 00 6C 3
8、2 01 00 00 00 00 00 0E 00 00 04 01 12 0A 10下面我们列表分析读取 PLC 密码的指令:68 1B 1B 68 02 00 6C 32 01 00 00 00 00 00 0E 00 00 04 01 12 0A 10 02 00 08 00 00 03 00 05 E0 D2 1622 23 24 25 26 27 28 29 30 31 32DU FCS DE读取长度 数据个数 存储器类型 偏移量 校验码 结束符02 00 08 00 00 03 00 05 E0 D2 16因为是 PC 上发的读 PLC 数据的命令,SA=00,DA=02,如果有多
9、个站,DA 要改成相应的站号。读命令中从 DA 到 DU 的长度为 1B 即 27 个字节。从 22 字节开始根据读取数据的类型、位置不同而不同。上表是读不同存储器命令的 Byte2232。字节 22 23 24 25 26 27 28 29 30 31 32功能 读取长度 数据个数 存储器类型 偏移量 校验 码 结束 符读 Q0.1 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 0
10、0 05 00 00 01 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:Doubl
11、e WordByte 24 数据个数,这里是 01 ,一次读多个数据时见下面的说明。Byte 26 存储器类型,01:V 存储器 00:其它Byte 27 存储器类型04:S 05:SM 06:AI 07:AQ 1E: C81:I 82:Q 83:M 84:V 1F: TByte 28,29,30 存储器偏移量指针(存储器地址*8),如:VB100,存储器地址为 100,偏移量指针为 800,转换成 16 进制就是 320H,则 Byte 2829 这三个字节就是:00 03 20。Byte 31 校验和,前面已说到这是从(DA+SA+DSAP+SSAP+DU) Mod 256 。一次读多条数
12、据对于一次读多个数据的情况,前 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=8Byte 19-30 按上述一次读一个数据的格式依次列出,Byte 31-42 另一类型的数据,也是按上述格式给出。以此类推,一次最多读取 22
13、2 个字节的数据。写命令分析:一次写一个 Double Word 类型的数据,写命令是 40 个字节,其余为 38 个字节。写一个 Double Word 类型的数据,前面的 021 字节为 :0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21开始符 长度 长度开始符68 21 21 68 02 00 7C 32 01 00 00 00 00 00 0E 00 00 04 01 12 0A 1068 23 23 68 02 00 6C 32 01 00 00 00 00 00 0E 00 00 04 01 12 0A 10写一个其它类
14、型的数据,前面的 021 字节为 :(与上面比较,只是长度字节发生变化)68 21 21 68 02 00 6C 32 01 00 00 00 00 00 0E 00 00 04 01 12 0A 1022 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37数据长度 数据个数 存储类型 偏移量 数据形式 数据位数 写入 值 校验 码 终止 符01 00 01 00 00 82 00 00 00 00 03 00 01 01 79 16从 22 字节开始根据写入数据的值和位置不同而变化。上表是几个写命令的Byte2240。字 节 22 23 24 25 26
15、 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 0
16、0 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最后, 经分析我们可以得出以下结果:Byte 22- Byte 30 写入数据的长度、存储器类型、存储器偏移量与读命令相同。T,C 等不能用写命令写入。 Byte 32 如果写
17、入的是位数据这一字节为 03,其它则为 04Byte 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,结束。如果写个的是双字数据(四字节),Byte3538 就是写入的值, Byte39=检验码,Byte40=16H,结束。看完上面的指令分析
18、我们现在就举例几个常用的 PPI 协议来分析一下:PC 寻呼:10 02 00 49 4B 16 PLC 返回:10 00 02 02 04 16PC 发送:10 02 00 5C 5E 16 PLC 返回: E5我们先来看看西门子 S7200PLC 的读取密码指令:请用串口软件以 16 进制发送,端口设置 9600;e;8;1 发送:68 1B 1B 68 02 00 6C 32 01 00 00 00 00 00 0E 00 00 04 01 12 0A 10 02 00 08 00 00 03 00 05 E0 D2 16 意思:要求传送系统存储区 05E0 位开始的 8 个字符(这就是
19、 8 个密码数值)。如果通讯无误,PLC 会返回 E5,意思:已经收到那么这时上位机再次发送指令 10 02 00 5C 5E 16 意思:请执行命令。(说到这里打住一下,PLC 返回 E5 指令后上位机 PC 要在很短的时间内发送确认指令,晚了刚才的指令就无效了具体多长时间我也没测准,反正 1、2 秒时间是没有问题的。)那么这时 PLC 就真的执行命令了返回如下字符:68 1D 1D 68 00 02 08 32 03 00 00 00 00 00 02 00 0C 00 00 04 01 FF 04 00 40 9B 98 02 06 9D 9A 00 76 7D 16好了,说到这里就此停
20、止,大家看看密码是多少啊!你如果真正明白了 PPI 协议就不难找出出密码了,但是这个密码是经过二次加密的,并不是真正的密码,还需要破译,至于密码算法在此不便公开,不过你多做实验一定能得出结果的。下面再看一个读取 PLC 版本号的指令:我们在解密中首先要确定的是 PLC 的版本号。就是要看看是老版本还是 02 版的,也好做出加解密方案。他的通讯源码是这样的:0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 3268 1B 1B 68 02 00 7C 32 01 00 00
21、00 00 00 0E 00 00 04 01 12 0A 10 02 00 14 00 00 03 00 00 00 09 16发送完上面数据 PLC 返回 E5.再次发送确认指令:10 02 00 5C 5E 16 这时 plc 的版本号就返回来了。看下面:68 29 29 68 00 02 08 32 03 00 00 00 00 00 02 00 18 00 00 04 01 FF 04 00 A0 43 50 55 20 32 32 36 20 43 4E 20 20 20 20 20 20 30 32 30 31 D7 16 你看这一段:43 50 55 20 32 32 36 2
22、0 43 4E 20 20 20 20 20 20 30 32 30 31 就是 plc 版本号的 ASCII 码。用 ASC 方式显示就会看的更明白上面数据是:C P U SP 2 2 6 SP C N 0 2 0 1 (sp 就是空格)再一个就是读 TD200 密码指令:68 1B 1B 68 02 00 6C 32 01 00 00 00 00 00 0E 00 00 04 01 12 0A 10 02 00 02 00 01 84 00 00 50 B9 16 (VW10)写 M0 指令68 20 20 68 02 00 7C 32 01 00 00 00 00 00 0E 00 05
23、 05 01 12 0A 10 01 00 01 00 00 83 00 00 00 00 03 00 01 01 80 16读 222 位 3 区(系统区)数据指令68 1B 1B 68 02 00 6C 32 01 00 00 00 00 00 0E 00 00 04 01 12 0A 10 02 00 DE 00 00 03 00 00 00 C3 16 读取密码保护位指令68 1B 1B 68 02 00 6C 32 01 00 00 00 00 00 0E 00 00 04 01 12 0A 10 02 00 01 00 00 03 00 05 D8 C3 16改写密码保护位指令(
24、你来验证是否可行)68 20 20 68 02 00 7C 32 01 00 00 00 00 00 0E 00 05 05 01 12 0A 10 08 00 01 00 00 03 00 05 D8 00 04 00 08 04 EF 1668 20 20 68 02 00 7C 32 01 00 00 00 00 00 0E 00 05 05 01 12 0A 10 02 00 01 00 00 03 00 05 D8 00 03 00 08 04 E8 16全部清除指令:68 21 21 68 02 00 7C 32 07 00 00 00 24 00 08 00 0C 00 01 1
25、2 04 11 45 01 00 FF 09 00 08 16 19 06 0D 01 08 18 1E EE 16 块代码:08 程序块 0A 数据块 0B 系统块 写指令:先发 10 02 00 5C 5E 16 后发写指令1、写一位 M 区(例子 M0.0)先发 10 02 00 5C 5E 16 收到 E5 后发 68 20 20 68 02 00 7C 32 01 00 00 00 00 00 0E 00 05 05 01 12 0A 10 01 00 01 00 00 83 00 00 00 00 03 00 01 01 80 16收到 E5 说明写入完成(只要报文长度,跟校验码对
26、了,就会回复 E5)0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21开始符报文长度报文长度开始符目标地址(PLC)源站地址(上位机)功能码写68 20 20 68 02 00 7C 32 01 00 00 00 00 00 0E 00 05 05 01 12 0A 10报文长度为: 目标地址 到 倒数第二位的校验位前面 的字节长度(根据写入值不通报文长度不同)功能码:7C 表示写入;6C 表示读取。17 位:05 表示写入;04 表示读取。16 位: 16 位的 05 表示写入的是 位或者字节(即用一个字节存储)06 表示 字; 0
27、8 表示双字(4 个字节); 0C 表示 8 个字节22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37数据长度 数据个数 存储类型 偏移量 数据形式 数据位数 写入 值 校验 码 终止 符01 00 01 00 00 82 00 00 00 00 03 00 01 01 79 16数据长度(22 位):01 位;02 字节;04 字;06 双字。数据个数:0100 表示一个;0200 表示连续的两个;0400 连续的 4 个。存储类型:26 位:01 V 区;00 其他。27 位:04 S 区;05 SM 区;06 AI;07 AQ;1E C;81
28、I;82 Q;83 M;84 V ;1F T偏移量: 0000 0000 0000 0000 0000 0XXX (XXX 表示位)例如:10.3=101 0.011 即 00 00 53数据形式:03 表示位;04 表示其他。数据位数:即写入数据多少位。01 一位;08 八位;10 十六位;20 三十二位。写入值:写入位,字节均用一个字节存储;写入双字得用四个字节。校验码:即报文的偶校验(所有之和 Mod 100H)终止符:16H若 M10.3=1 写入, 00 00 53 01 D3 (校验码 D3 是从开头第五个 02 到倒数第三个 01 的所有数字的偶校验(算术和) 因为 0101 0
29、.011(10.3)为 00 00 53即:68 20 20 68 02 00 7C 32 01 00 00 00 00 00 0E 00 05 05 01 12 0A 10 01 00 01 00 00 83 00 00 53 00 03 00 01 01 D3 16M10.3=0即:68 20 20 68 02 00 7C 32 01 00 00 00 00 00 0E 00 05 05 01 12 0A 10 01 00 01 00 00 83 00 00 53 00 03 00 01 00 D2 162、写 V 区一个字节(例子 VB100=10H)先发 10 02 00 5C 5E
30、16 收到 E5 后发:68 20 20 68 02 00 7C 32 01 00 00 00 00 00 0E 00 05 05 01 12 0A 10 02 00 01 00 01 84 00 03 20 00 04 00 08 10 bd 163、写 V 区一个字(双字)发:68 21 21 68 02 00 7C 32 01 00 00 00 00 00 0E 00 06 05 01 12 0A 10 04 00 01 00 01 84 00 03 20 00 04 00 10 ab cd 30 16发:68 23 23 68 02 00 7C 32 01 00 00 00 00 00
31、 0E 00 08 05 01 12 0A 10 06 00 01 00 01 84 00 03 20 00 04 00 20 ab cd ef fe 31 16读指令:先发读指令,后发 10 02 00 5C 5E 161、读取数据(例子读取 VW10 的值,值为 FF FF)先发读取命令:68 1B 1B 68 02 00 6C 32 01 00 00 00 00 00 0E 00 00 04 01 12 0A 10 02 00 02 00 01 84 00 00 50 B9 16 (红色或者改为 04 00 01 00 校验也得改)回复 E5然后发送 10 02 00 5C 5E 16
32、收到数据:68 17 17 68 00 02 08 32 03 00 00 00 00 00 02 00 06 00 00 04 01 FF 04 00 10 FF FF 5D 16 22 23 24 25 26 27 28 29 30 31 32DU FCS DE读取长度 数据个数 存储器类型 偏移量 校验码 结束符02 00 08 00 00 03 00 05 E0 D2 16读指令的前 21 位都是相同的。读取长度,数据个数,存储类型,偏移量都与写指令里面的定义一样。收到数据中的16 位:05 表示收到数据用一个字节存储,可能是 PLC 位,也可能是一个字节;06 表示用两个字节存储,即
33、一个字;08 双字;0C 表示 8 个字节。22 位:数据形式,03 表示位;04 表示其他。(主要针对 C,T 可能是位也可能是计数值,计数时间)24 位:表示读取数值的位数。01 表示一位;08 八位;10 十六位;20 三十二位。25 位之后几位:要读取的数值。若回复 F9(会产生不同结果,但接受值不变)然后发送 10 02 00 5C 5E 16收到数据:(关闭串口再打开的不同结果)DA A1 21 1B 90 32 61 66 40 40 80 00 00 00 02 00 06 00 00 04 01 FF 04 00 10 FF FF 5D 16B4 A1 21 1B 10 30
34、 61 66 40 80 80 00 00 00 02 00 06 00 00 04 01 FF 04 00 10 FF FF 5D 1668 17 17 68 00 02 08 32 03 00 00 00 00 00 02 00 06 00 00 04 01 FF 04 00 10 FF FF 5D 164、读取 VB1068 1B 1B 68 02 00 6C 32 01 00 00 00 00 00 0E 00 00 04 01 12 0A 10 02 00 01 00 01 84 00 00 50 B8 1668 16 16 68 00 02 08 32 03 00 00 00 00
35、 00 02 00 05 00 00 04 01 FF 04 00 08 FF 55 165、读取 VD1068 1B 1B 68 02 00 6C 32 01 00 00 00 00 00 0E 00 00 04 01 12 0A 10 06 00 01 00 01 84 00 00 50 BC 1668 19 19 68 00 02 08 32 03 00 00 00 00 00 02 00 08 00 00 04 01 FF 04 00 20 FF FF 00 00 6F 166、读取 VB10 后面的 8 个字节68 1B 1B 68 02 00 6C 32 01 00 00 00 0
36、0 00 0E 00 00 04 01 12 0A 10 02 00 08 00 01 84 00 00 50 Bf 1668 1D 1D 68 00 02 08 32 03 00 00 00 00 00 02 00 0C 00 00 04 01 FF 04 00 40 FF FF 00 00 00 00 00 00 93 167、读取 V10.068 1B 1B 68 02 00 6C 32 01 00 00 00 00 00 0E 00 00 04 01 12 0A 10 01 00 01 00 01 84 00 00 50 B7 1668 16 16 68 00 02 08 32 03
37、00 00 00 00 00 02 00 05 00 00 04 01 FF 03 00 01 01 4F 164、读取 Q0.1发送:68 1B 1B 68 02 00 6C 32 01 00 00 00 00 00 0E 00 00 04 01 12 0A 10 01 00 01 00 00 82 00 00 01 65 16回复:E5然后发送 10 02 00 5C 5E 16 收到数据:68 16 16 68 00 02 08 32 03 00 00 00 00 00 02 00 05 00 00 04 01 FF 03 00 01 00 4E 16 Q0.1 为 0时68 16 16
38、 68 00 02 08 32 03 00 00 00 00 00 02 00 05 00 00 04 01 FF 03 00 01 01 4F 16 Q0.1 为 1时5、读取 Q1.3发送:68 1B 1B 68 02 00 6C 32 01 00 00 00 00 00 0E 00 00 04 01 12 0A 10 01 00 01 00 00 82 00 00 0B 65 1668 16 16 68 00 02 08 32 03 00 00 00 00 00 02 00 05 00 00 04 01 FF 03 00 01 00 4E 166、读取 M0.0发送:68 1B 1B 68 02 00 6C 32 01 00 00 00 00 00 0E 00 00 04 01 12 0A 10 01 00 01 00 00 83 00 00 00 65 1668 16 16 68 00 02 08 32 03 00 00 00 00 00 02 00 05 00 00 04 01 FF 03 00 01 00 4E 16