西门子PLC的S7协议报文解析说明

我们以S7的1500系列来查看握手和读取、写入【字Word或者位Bit】命令报文

以下报文不做说明时都是十六进制字节。

西门子PLC需要连接成功后发送两次握手命令方可进行读写通信。

西门子PLC的S7协议的头由四个字节组成.。

第一个字节数固定为03,第二个字节数固定为00

第三个字节和第四个字节代表【报文字节总长度】,比如00 16就代表报文总长度为22

报文字节总长度=256*buffer[2]+buffer[3]

【高字节在前,低字节在后】,而在C#程序中是低字节在前,高字节在后的。

因此,对报文的解析是 通过 03 00 开头,然后查找第三个和第四个字节,来获取【报文字节总长度】,然后依次查找【报文字节总长度-4】个字节即终止。

S7协议的地址(偏移量)是按照位来运算的,因此需要地址值乘以8。

地址的三个字节范围为0x000000~0x08FFFF

比如M30000,实际地址就是30000*8=240000,然后转化为3个字节。

240000=0x03A980,对应三个字节【03 A9 80】

比如DB21234.40000 其中DB号21234为0x52F2,DB编号对应两个字节【52 F2】

偏移量(地址)40000乘以8就是320000,也就是0x04E200,对应三个字节【04 E2 00】

第一次握手First Handshake

发送命令【22个字节】:

03 00 00 16 11 E0 00 00 00 01 00 C0 01 0A C1 02 01 02 C2 02 01 00

反馈命令【22个字节】:

03 00 00 16 02 D0 80 32 01 00 00 02 00 00 08 00 00 F0 00 00 01 00

第二次握手Second Handshake

发送命令【25个字节】:

03 00 00 19 02 F0 80 32 01 00 00 04 00 00 08 00 00 F0 00 00 01 00 01 01 E0

反馈命令【27个字节】:

03 00 00 1B 02 F0 80 32 01 00 00 02 00 00 08 00 00 00 00 00 01 00 01 00 F0 00 F0

读取报文命令解析:

发送报文解析:


    固定报文头:buffer[0]=0x03,buffer[1]=0x00

    报文长度(字节个数):buffer[2]=0x00,buffer[3]=0x1F 【报文长度=256*buffer[2]+buffer[3]】
    固定协议标识:buffer[4]=0x02,buffer[5]=0xF0,buffer[6]=0x80,buffer[7]=0x32  

    发送命令:buffer[8]=0x01
    冗余标识(保留):buffer[9]=0x00,buffer[10]=0x00,buffer[11]=0x00,buffer[12]=0x01
    读取命令长度:【报文长度-17】,即从索引17开始,有多少个字节       

                      buffer[13]=0x00,buffer[14]=0x0E                           
    读取内部数据时为00,读取CPU型号为数据长度 buffer[15]=0x00,buffer[16]=0x00
    读写指令,04读,05写: buffer[17]=0x04
    读取数据块个数:  buffer[18]=0x01
    下面每12个字节作为一个数据块:
    {
        指定有效值类型 buffer[19]=0x12
        接下来本次地址访问长度 buffer[20]=0x0A
        语法标记ANY, buffer[21]=0x10
        按字为单位02,按位为单位01  buffer[22]=0x02
        访问数据的字节个数 buffer[23]=0x00,buffer[24]=0x02
        DB块编号,M区为0   buffer[25]=0x00,buffer[26]=0x00
        访问区域标识:buffer[27]=0x83【M区为0x83,DB块为0x84】
        偏移位置:buffer[28]=0x00,buffer[29]=0x03,buffer[30]=0x20 【偏移量最大为0x07FFFF】
        偏移量计算方式 : 
            M区地址需要乘以8.比如 M100=100*8=800=0x0320,
            DB块偏移量乘以8. 比如DB30000.12000 DB块号30000=0x7530,偏移位置需要乘以8,即12000*8=96000=0x017700
    }

反馈(接收)报文解析:


    
    按字读取:从索引21开始查找 反馈数据开始标记 0xFF04,然后读取2个字节的长度,0x5BA0,即十进制 23456

    按位读取:从索引21开始查找 反馈数据开始标记 0xFF03,然后读取一个字节的长度,具体值为0x01,即为true

写入报文命令解析:

发送报文解析:


    固定报文头:buffer[0]=0x03,buffer[1]=0x00  报文长度(字节个数):buffer[2]=0x00,buffer[3]=0x25 【报文长度=35+字节数组个数】
    固定协议标识:buffer[4]=0x02,buffer[5]=0xF0,buffer[6]=0x80,buffer[7]=0x32  

    发送命令:buffer[8]=0x01
    标识序列号:buffer[9]=0x00,buffer[10]=0x00,buffer[11]=0x00,buffer[12]=0x01
    固定:buffer[13]=0x00,buffer[14]=0x00
    写入长度:写入长度+4 因从索引31开始计算,故为length+4 buffer[15]=0x00,buffer[16]=0x06
    读写指令,04读,05写 buffer[17]=0x05,
    写入数据块个数  buffer[18]=0x01
    下面共12个字节作为一个数据块:
    {
        指定有效值类型 buffer[19]=0x12
        接下来本次地址访问长度 buffer[20]=0x0A
        语法标记ANY, buffer[21]=0x10
        按字为单位02,按位为单位01  buffer[22]=0x02
        访问数据的字节个数 buffer[23]=0x00,buffer[24]=0x02
        DB块编号,M区为0   buffer[25]=0x00,buffer[26]=0x00
        访问区域标识:buffer[27]=0x83【M区为0x83,DB块为0x84】
        偏移位置:buffer[28]=0x07,buffer[29]=0x79,buffer[30]=0x90 【偏移量最大为0x07FFFF】
        偏移量计算方式 : 
            M区地址需要乘以8.比如 M61234=61234*8=489872=0x077990,
            DB块偏移量乘以8. 比如DB30000.12000 DB块号30000=0x7530,偏移位置需要乘以8,即12000*8=96000=0x017700
    }
    按字写入:buffer[31]=0x00,buffer[32]=0x04,如果按位写入,则buffer[32]=0x03
    按位计算长度:即字节长度*8 buffer[33]=0x00,buffer[34]=0x10
    具体写入的字节数据:buffer[35]=0x7A,buffer[36]=0x02

反馈(接收)报文解析:

最后一个字节是0xFF代表写入成功,否则失败 

下面是具体命令报文示例:

读取M区和DB块,按字读取

发送命令【读取M100的short值【23456】】:

03 00 00 1F 02 F0 80 32 01 00 00 00 01 00 0E 00 00 04 01 12 0A 10 02 00 02 00 00 83 00 03 20

反馈命令:

03 00 00 1B 02 F0 80 32 03 00 00 00 01 00 02 00 06 00 00 04 01 FF 04 00 02 5B A0

发送命令【DB30000.12000的short值【12345】】:

03 00 00 1F 02 F0 80 32 01 00 00 00 01 00 0E 00 00 04 01 12 0A 10 02 00 02 75 30 84 01 77 00

反馈命令:

03 00 00 1B 02 F0 80 32 03 00 00 00 01 00 02 00 06 00 00 04 01 FF 04 00 02 30 39

读取M区和DB块,按位读取

发送命令【M61236读取bool为true】:

03 00 00 1F 02 F0 80 32 01 00 00 00 01 00 0E 00 00 04 01 12 0A 10 01 00 01 00 00 83 07 79 A0

反馈命令:

03 00 00 1A 02 F0 80 32 03 00 00 00 01 00 02 00 05 00 00 04 01 FF 03 00 01 01

发送命令【DB12345.65432.3读取bool为true】:

03 00 00 1F 02 F0 80 32 01 00 00 00 01 00 0E 00 00 04 01 12 0A 10 01 00 01 30 39 84 07 FC C3

反馈命令:

03 00 00 1A 02 F0 80 32 03 00 00 00 01 00 02 00 05 00 00 04 01 FF 03 00 01 01

写入M区和DB块,按字写入

发送命令【M56789的Int32为987654321】:

03 00 00 27 02 F0 80 32 01 00 00 00 01 00 0E 00 08 05 01 12 0A 10 02 00 04 00 00 83 06 EE A8 00 04 00 20 3A DE 68 B1

反馈命令:

03 00 00 16 02 F0 80 32 03 00 00 00 01 00 02 00 01 00 00 05 01 FF

发送命令【DB23789.36789的Int32为-1234567890】:

03 00 00 27 02 F0 80 32 01 00 00 00 01 00 0E 00 08 05 01 12 0A 10 02 00 04 5C ED 84 04 7D A8 00 04 00 20 B6 69 FD 2E

反馈命令:

03 00 00 16 02 F0 80 32 03 00 00 00 01 00 02 00 01 00 00 05 01 FF

写入M区和DB块,按位写入

发送命令【M51133.0写入true】:

03 00 00 24 02 F0 80 32 01 00 00 00 01 00 0E 00 05 05 01 12 0A 10 01 00 01 00 00 83 06 3D E8 00 03 00 01 01

反馈命令:

03 00 00 16 02 F0 80 32 03 00 00 00 01 00 02 00 01 00 00 05 01 FF

发送命令【DB23789.36789.2写入true】:

03 00 00 24 02 F0 80 32 01 00 00 00 01 00 0E 00 05 05 01 12 0A 10 01 00 01 5C ED 84 04 7D AA 00 03 00 01 01

反馈命令:

03 00 00 16 02 F0 80 32 03 00 00 00 01 00 02 00 01 00 00 05 01 FF 

   
    
   

   

    

你可能感兴趣的:(IOT,C#,S7协议,IOT,西门子PLC的S7报文)