Modbus-rtu协议入门讲解 以及我司小主机兼容其他公司485设备的具体要求
1、字Word, 字节byte, 位bit
1Word=2byte(1个汉字=2个字节,1个英文=1个字节)
1byte=8bit二进制(位)(比特)位是数据存储的最小单位
编 码 |
8位二进制 |
数据位 |
8位 |
奇偶校验位 |
无 |
停止位 |
1位 |
错误校验 |
CRC(冗余循环码) |
波特率 |
2400bit/s、4800bit/s、9600 bit/s可设,出厂默认为4800bit/s |
注意:
编码8位二进制的解释:业内规定8位二进制(8bit)称为一个字节,二进制就是冯2进1,表示11111111,换算成10进制就是255,换算成16进制就是FF。故一个字节表示16进制的最大表示到FF。
8位数据位解释如下:即485组网中,主站问询以及设备应答帧结构,每一帧数据都是1个字节为单位体现的,而一个字节就是一个二进制的8位。如下:
主机问询帧结构:
地址码 | 功能码 | 寄存器起始地址 | 寄存器长度 | 校验码低位 | 校验码高位 |
1字节 | 1字节 | 2字节 | 2字节 | 1字节 | 1字节 |
从机应答帧结构:
地址码 | 功能码 | 有效字节数 | 数据一区 | 第二数据区 | 第N数据区 | 校验码 |
1字节 | 1字节 | 1字节 | 2字节 | 2字节 | 2字节 | 2字节 |
从上方表格中可以看出主站问询及从站应答帧结构来看,都是以1个8位二进制即1个字节为单位传送的。
数据区:数据区是具体通讯数据,注意16bits数据高字节在前!解释如下:
再解释何为高字节之前,需要了解所有帧结构中的数值都是16进制的。
举例说明一:
1、假设485设备起始地址为3,我司环境监控主机作为485主站通过0x00 00号和0x00 01号寄存器读取该485设备数据
主站问询0x00 00号和0x00 01号寄存器值
地址码 | 功能码 | 起始地址 | 数据长度 | 校验码低位 | 校验码高位 |
0x03 | 0x03 | 0x00 0x00 | 0x00 0x02 | 0xC5 | 0xE9 |
从站应答帧(例如读到1号寄存器为65435,0号寄存器为658)
地址码 | 功能码 | 有效字节数 | 0号寄存器值 | 1号寄存器值 | 校验码低位 | 校验码高位 |
0x03 | 0x03 | 0x04 | 0x02 0x92 | 0xFF 0x9B | 0x79 | 0xFD |
上方表格中,主站问询了地址为3的485设备,3号功能码中0号和1号寄存器;
485设备作出应答,3号设备3号功能码数据区应答了4个有效字节,数据区0号寄存器两个字节,数据区1号寄存器2个字节;
从设备应答帧可以看出,485设备每个数据区寄存器是存了个16位的数据,即两个字节的数据,即16位二进制,1111111111111111,换算成10进制即是65535,也就是说每个寄存器最大存的10进制数是65535;
以数据区0号寄存器为例,应答 02 92两个字节,02在前,92在后,02这个字节就是高字节,带标数值的高位(个十百千万,万是高位,数值写在前方),即代表16进制的数值292,换算成10进制就是658。
若是低字节在前,就变成16进制的922了,换算成10进制就是2338
举例说明二:
2、我司环境监控主机读取我司20wlux光照度的数据,我司光照度设备只用到功能码0x03(读取寄存器数据)。假设20Wlux光照度485地址为3,以下是我司光照度设备寄存器地址。
寄存器地址 |
PLC或组态地址 |
内容 |
操作 |
0000 H |
40001 |
湿度 |
只读 |
0001 H |
40002 |
温度 |
只读 |
0002 H |
40003 |
光照度 |
只读 |
|
|||
0003 H |
40004 |
(只在0~200000Lux启用,单位1Lux) |
|
0006 H |
40007 |
光照度 |
只读 |
|
|||
(0~65535单位1Lux |
|||
|
|||
0~200000单位百Lux) |
那么我司环境监控主机作为485主站读取我司20Wlux光照度的数据时,主机问询帧如下:
地址码 | 功能码 | 起始地址 | 数据长度 | 校验码低位 | 校验码高位 |
0x03 | 0x03 | 0x00 0x02 | 0x00 0x02 | 0x65 | 0xCB |
我司光照度应答帧如下:(例如读到光照度为200000 Lux)
地址码 | 功能码 | 有效字节数 | 光照度高位 | 光照度低位 | 校验码低位 | 校验码高位 |
0x01 | 0x03 | 0x04 | 0x00 0x03 | 0x0D 0x40 | 0x0F | 0x53 |
光照度计算说明:
此协议只在0~200000Lux量程变送器下使用,单位为1Lux
30D40 H(十六进制) = 200000=> 光照度=200000 Lux
从设备应答帧来看,设备应答了了4个有效字节,第一数据区应对应的2号寄存器,所存的数值是20wLUX的数值高位(03);
第二数据区对应的3号寄存器,所存的数值是20Wlux的数值低位 (0D 40);
主机作为485主站,整合高位及低位之后形成一个32位无符号的数,16进制下的30D40,换算成10进制,即200000;
注意低字节D前面的0务必加上,高字节3前面的0加不加的无所谓,因为高字节03前面没有0以上的数了,03加上这个0或者不加上这个0都带表3,低字节0D若是舍弃这个0,5位数30D40就变成4位数3D40了;就像10进制中10100与1100的意思一样,最高位数与中间位数的0是有意义的,而最高位前面加个0,什么都代表不了;
从以上两个例子中,我们可以做以下总结:
若是需要我司环境监控主机去采集其他公司的485设备,那么需要该485设备符合以下条件:
8位数据位 |
1位停止位 |
无校验 |
波特率支持2400,4800,9600任意一种均可 |
寄存器中的数据必须都是高字节在前的! |
且寄存器中的原始数值转换规律必须写清楚才能明确我司环境监控主机是否能采集该485设备数据 |
进制简介:
对于任何一种进制---X进制,就表示某一位置上的数运算时是逢X进一位。 十进制是逢十进一,十六进制是逢十六进一,二进制就是逢二进一,以此类推,x进制就是逢x进位。
2进制是由0,1两个大小不同的数,冯2进1。
16进制每一位上可以是从小到大为0、1、2、3、4、5、6、7、8、9、A、B、C、D、E、F16个大小不同的数,即逢16进1,其中用A,B,C,D,E,F(字母不区分大小写)这六个字母来分别表示10,11,12,13,14,15。
当温度为负的时候:
我司485设备,当温度为负的时候,是以补码的形式存在的,负数的补码是在其原码的基础上, 符号位不变, 其余各位取反, 最后+1。