|
|
本帖最后由 qingyun 于 2016-2-14 20:42 编辑
4.读操作
读demo1:
西门子1200: 读取DB10, count=17 ,offset=19
PC发出报文
(A[3]~A[4]=0x001F=31=读取报文总长度, A[12]~A[13]=0x001C=序列号,A[24]~A[25]=0x0011=17=读取请求count;
A[26]~A[27]=0x000A=10=DB10, A[28]=0x84=读取的数据类型为DB块,A[29]~A[31]=0x000098=152=19*8=读取偏移量offset(bit为单位) )
03 00 00 1F 02 F0 80 32 01 00 00 00 1C 00 0E 00
00 04 01 12 0A 10 02 00 11 00 0A 84 00 00 98
PLC回复报文:
(B[3]~B[4]=0x002A=42=回复报文总长度, B[12]~B[13]=0x001C=序列号,B[16]~B[17]=0x0015=21=读取请求count(17)+4
B[24]~B[25]=0x0088=17*8=请求数据长度(bit为单位), B[26]~最后=数据值)
03 00 00 2A 02 F0 80 32 03 00 00 00 1C 00 02 00
15 00 00 04 01 FF 04 00 88 13 14 15 16 17 00 00
00 00 00 00 00 00 00 00 00 00
读demo2:
西门子1200: 读取DB11, count=17 ,offset=19
PC发出报文:
(A[3]~A[4]=0x001F=31=读取报文总长度, A[12]~A[13]=0x008E=序列号,A[24]~A[25]=0x0011=17=读取请求count;
A[26]~A[27]=0x000B=11=DB11, A[28]=0x84=读取的数据类型为DB块,A[29]~A[31]=0x000098=152=19*8=读取偏移量offset(bit为单位) )
03 00 00 1F 02 F0 80 32 01 00 00 00 8E 00 0E 00
00 04 01 12 0A 10 02 00 11 00 0B 84 00 00 98
PLC回复报文:
(B[3]~B[4]=0x002A=42=回复报文总长度, B[12]~B[13]=0x001C=序列号,B[16]~B[17]=0x0015=21=读取请求count(17)+4
B[24]~B[25]=0x0088=17*8=请求数据长度(bit为单位), B[26]~B[42]=数据值)
03 00 00 2A 02 F0 80 32 03 00 00 00 8E 00 02 00
15 00 00 04 01 FF 04 00 88 13 14 15 16 17 18 00
00 00 00 00 00 00 00 21 22 23
读demo3:
西门子1200:读取DB11, count=16 ,offset=18
PC发出报文:
(A[3]~A[4]=0x001F=31=读取报文总长度, A[12]~A[13]=0x0013=序列号,A[24]~A[25]=0x0010=16=读取请求count;
A[26]~A[27]=0x000B=11=DB11, A[28]=0x84=读取的数据类型为DB块,A[29]~A[31]=0x000090=146=18*8=读取偏移量offset(bit为单位) )
03 00 00 1F 02 F0 80 32 01 00 00 00 13 00 0E 00
00 04 01 12 0A 10 02 00 10 00 0B 84 00 00 90
PLC回复报文:
(B[3]~B[4]=0x0029=41=回复报文总长度, B[12]~B[13]=0x0013=序列号,B[16]~B[17]=0x0014=20=读取请求count(16)+4
B[24]~B[25]=0x0080=16*8=请求数据长度(bit为单位), B[26]~B[41]=数据值)
03 00 00 29 02 F0 80 32 03 00 00 00 13 00 02 00
14 00 00 04 01 FF 04 00 80 00 13 14 15 16 17 18
00 00 00 00 00 00 00 00 21
读demo4:
西门子300 (314) 读取D50, count=20 ,offset=4000
PC发出报文:
(A[3]~A[4]=0x001F=31=读取报文总长度, A[12]~A[13]=0x0028=序列号,A[24]~A[25]=0x0014=20=读取请求count;
A[26]~A[27]=0x0032=50=DB50, A[28]=0x84=读取的数据类型为DB块,A[29]~A[31]=0x007D00=32000
=4000*8=读取偏移量offset(bit为单位) )
03 00 00 1F02 F0 80 32 01 00 00 00 28 00 0E 00
00 04 01 12 0A 10 02 00 14 00 32 8400 7D 00
PLC回复报文:
(B[3]~B[4]=0x002D=45=回复报文总长度, B[12]~B[13]=0x0028=序列号,B[16]~B[17]=0x0018=24=读取请求count(20)+4
B[24]~B[25]=0x00A0=20*8=请求数据长度(bit为单位), B[26]~B[45]=数据值)
03 00 00 2D02 F0 80 32 03 00 00 00 28 00 02 00
1800 00 04 01 FF 04 00 A0 00 04 0E AB 00 00 00
00 00 00 03 00 00 00 00 00 00 00 00 00
读demo5:
西门子300 (315) 读取D10, count=100 ,offset=2
PC发出报文:
(A[3]~A[4]=0x001F=31=读取报文总长度, A[12]~A[13]=0x0003=序列号,A[24]~A[25]=0x0064=100=读取请求count;
A[26]~A[27]=0x000A=10=DB10, A[28]=0x84=读取的数据类型为DB块,A[29]~A[31]=0x000010=16=2*8=读取偏移量offset(bit为单位) )
03 00 00 1F 02 F0 80 32 01 00 00 00 03 00 0E 00
00 04 01 12 0A 10 02 00 64 00 0A 84 00 00 10
PLC回复报文:
(B[3]~B[4]=0x007D=125=回复报文总长度, B[12]~B[13]=0x0003=序列号,B[16]~B[17]=0x0068=104=读取请求count(100)+4
B[24]~B[25]=0x0320=100*8=请求数据长度(bit为单位), B[26]~B[125]=数据值)
03 00 00 7D 02 F0 80 32 03 00 00 00 03 00 02 00
68 00 00 04 01 FF 04 03 20 00 00 00 01 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00
读demo6:
西门子1200 读取X输入(input)两个byte:
PC发出报文:
(A[3]~A[4]=0x001F=31=读取报文总长度, A[12]~A[13]=0x0002=序列号,A[24]~A[25]=0x0002=2=读取请求count;
A[26]~A[27]=0x000A=10=DB10[其实这里写什么都可以,因为input不属于DB块],
A[28]=0x81=读取的数据类型为Input,A[29]~A[31]=0x000000=0=0*8=读取偏移量offset(bit为单位) )
03 00 00 1F 02 F0 80 32 01 00 00 00 02 00 0E 00
00 04 01 12 0A 10 02 00 02 00 0A 81 00 00 00
PLC回复报文:
(B[3]~B[4]=0x001B=27=回复报文总长度, B[12]~B[13]=0x0002=序列号,B[16]~B[17]=0x0068=104=读取请求count(100)+4
B[24]~B[25]=0x0320=100*8=请求数据长度(bit为单位), B[26]~B[27]=数据值)
03 00 00 1B 02 F0 80 32 03 00 00 00 02 00 02 00
06 00 00 04 01 FF 04 00 10 08 00
读demo7:
西门子1200 读取Y输出(output)两个byte:
PC发出报文:
(A[3]~A[4]=0x001F=31=读取报文总长度, A[12]~A[13]=0x0001=序列号,A[24]~A[25]=0x0002=2=读取请求count;
A[26]~A[27]=0x000A=10=DB10[其实这里写什么都可以,因为input不属于DB块],
A[28]=0x82=读取的数据类型为Output,A[29]~A[31]=0x000000=0=0*8=读取偏移量offset(bit为单位) )
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 0A 82 00 00 00
PLC回复报文:
(B[3]~B[4]=0x001B=27=回复报文总长度, B[12]~B[13]=0x0002=序列号,B[16]~B[17]=0x0068=104=读取请求count(100)+4
B[24]~B[25]=0x0320=100*8=请求数据长度(bit为单位), B[26]~B[27]=数据值)
03 00 00 1B 02 F0 80 32 03 00 00 00 01 00 02 00
06 00 00 04 01 FF 04 00 10 05 00
读demo8:
西门子1200 读取flag两个byte:
PC发出报文:
03 00 00 1F 02 F0 80 32 01 00 00 05 65 00 0E 00
00 04 01 12 0A 10 02 00 02 00 09 83 00 00 00
PLC回复报文:
(B[3]~B[4]=0x001B=27=回复报文总长度, B[12]~B[13]=0x0565=序列号,B[16]~B[17]=0x0006=6=读取请求count(2)+4
B[24]~B[25]=0x0010=2*8=请求数据长度(bit为单位), B[26]~B[27]=数据值)
03 00 00 1B 02 F0 80 32 03 00 00 05 65 00 02 00
06 00 00 04 01 FF 04 00 10 FF 17
根据以上8个报文的demo,摸索出大致规律如下(未必完全正确,但是应付项目可以了);
A[1]~A[2]: 03 00 固定报文头;
A[3]~A[4]: 00 1F 整个读取请求长度为0x1F= 31 ;
A[5]~A[11]: 02 F0 80 32 01 00 00 固定6个字节;
A[12]~A[13]: 两个字节,标识序列号,回复报文相同位置和这个完全一样;范围是0~65535;
A[14]~A[23]:00 0E 00 00 04 01 12 0A 10 02 固定10个字节
A[24]~A[25]:两个字节,访问数据的个数,以byte为单位;
A[26]~A[27]: DB块的编号,比如DB50, 就是0x32=50, 两个字节,范围是0~65535(也许是一个1个字节,因为没有设置估DB255以上的数据块,所以不知道到底是几个字节,姑且认为是2个字节);
A[28] : 访问数据块的类型:0x81-input ,0x82-output ,0x83-flag , 0x84-DB(这个最常见);
A[29]~A[31]: 访问DB块的偏移量offset (地址+1以byte为单位); 3个字节,范围是0~16777216(一般 用不到这么大)
程序设计的时候,其实主要关注最后4个信息,即:
1. A[24]~A[25]: 访问byte个数
2. A[26]~A[27]: DB块编号
3. A[28] : 数据块类型
4.A[29]~A[31] :访问地址偏移量;相当于首地址编号
B[1]~B[2]: 03 00 固定报文头
B[3]~B[4]: 整个读取回复报文长度:25+读取长度;
B[5]~B[11]: 02 F0 80 32 03 00 00 固定6个字节,和读取请求相同的位置几乎一样,就 B[9]=0x03 ;A[9]=0x01;
B[12]~B[13]: 两个字节,标识序列号,回复报文相同位置和这个完全一样;范围是0~65535;
B[14]~B[15]: 两个字节,固定为00 02;对应读取位置是 00 0E;正好 02+0E=10 ;有点补码的感觉,其实不需要关注规律,反正是固定的;
B[16]~B[17]:两个字节,=请求读取的字节数+4;
B[18]~B[23]:6个字节,固定为:00 00 04 01 FF 04 ;
B[24]~B[25]:两个字节, 请求访问的byte个数*8 ;其实就是以二进制为单位的个数;由此可以看出,一口气最多访问的地址个数是8192;
B[26]~ 最后一个 :以offset作为首地址,所对应的各个byte的值;
程序设计的时候,其实只要关注两个信息:
1.校验B[3]~B[4]:校验长度正确;
2.B[26]~最后一个 :获取对应的值;
到这里读的处理就算结束了;几个小注意点:
1. 对于不同信号的PLC,除了初始化的CPUSolt不同;正常读/写指令是一样的;
2.读的时候,都是以byte为单位的,如果程序只需要bit,那么还是以Byte为单位去读,将读出的部分按bit再去分解;
3.flag类型到底是什么,不是很清楚,有点类似三菱里的M点;这个也不需要去深究,一般项目里主要就是用DB块;
4.读取的长度如果是N(以byte为单位),那么返回的长度就是N*8(以bit为单位);怎么判断长度是否要*8;主要看后面是不是紧挨着数据,
如果是数据,就需要*8;offset都是以bit为单位的;
5.正常读的操作都是DB块,所以在A[26]~A[27]这个字节写入DB块的编号,但是对于input,output,flags这三个类型,是不需要数据块编号的,
不过我们可以随便写一个DB编号;
|
|