Modbus采用的是异步通信,以主从字节为单位,传输信息11位的字格式:
字格式(串行数据)    11位二进制
起始位            1位
数据位            8位
奇偶校验位        1位:有奇偶校验位/无:无奇偶校验位
停止位            1位:有奇偶校验位/2位:无奇偶校验位

通讯(信息帧)格式
数据格式:    地址码        功能码        数据区        错误校验
数据长度    :    1        1        N        2(16位CRC码)

地址码:
    地址码是通讯信息帧的首地址(1字节),范围是0-255。地址码是用户用来确定从机的唯一设备地址的标志。主机和从机通讯中,只有正确的地址码才能回送信息。回送信息也是以各自的地址码开始。
功能码:
    功能码是每次通讯信息帧传送的第二个字节。ModBus通讯规约可定义的功能码为1到127。主机可以根据发送不同的功能码来表明进行相关的操作。

MODBUS部分功能码
功能码    定  义        操  作(二进制)
02    读开关量输入    读取一路或多路开关量状态输入数据
01    读开关量输出    读取一路或多路开关量输出状态数据
03    读寄存器数据    读取一个或多个寄存器的数据
05    写开关量输出    控制一路继电器“合/分”输出
06    写单路寄存器    把一组二进制数据写入单个寄存器
10    写多路寄存器    把多组二进制数据写入多个寄存器

数据区:
    数据区包括需要由从机返送何种信息或执行什么动作。这些信息可以是数据(如:开关量输入/输出、模拟量输入/输出、寄存器等等)、参考地址等。例如,主机通过功能码03告诉从机返回寄存器的值(包含要读取寄存器的起始地址及读取寄存器的长度),则返回的数据包括寄存器的数据长度及数据内容。对于不同的从机,地址和数据信息都不相同。
错误校验:
    主机或从机可用校验码进行判别接收信息是否正确。由于电子噪声或一些其它干扰,信息在传输过程中有时会发生错误,错误校验码(CRC)可以检验主机或从机在通讯数据传送过程中的信息是否有误,错误的数据可以放弃(无论是发送还是接收),这样增加了系统的安全和效率。

常见的功能码介绍:

/********************************************************************/

功能码“03”:读多路寄存器输入

例如:主机要读取地址为01,起始地址为0116的3个从机寄存器数据。

从机数据寄存器的地址和数据为:

寄存器地址    寄存器数据    从机数据
0x0116        0x1784        Data1
0x0117        0x1780        Data2
0x0118        0x178A        Data2

主机发送的报文格式:
主机发送        字节数    发送的信息    备  注
从机地址        1    01        发送至地址为01的从机
功能码        1    03           读取寄存器
起始地址        2    0116        起始地址为0116
数据长度        3    0003        读取3个寄存器(共6个字节)
CRC码        2    E5F3        由主机计算得到CRC码

从机响应返回的报文格式:

从机响应        字节数    返回的信息    备注
从机地址        1    01        来自从机01
功能码        1    03        读取寄存器
读取字        1    06        3个寄存器共6个字节
寄存器数据1    2    1784        地址为0116内存的内容
寄存器数据2    2    1780        地址为0117内存的内容
寄存器数据3    2    178A        地址为0118内存的内容
CRC码        2    5847        由从机计算得到CRC码

/*****************************************************************/

功能码“06”:写一路路寄存器输入

例如:主机要读取地址为01,起始地址为0116的1个从机寄存器数据。

从机数据寄存器的地址和数据为:

寄存器地址    寄存器数据    从机数据
0x0116        0x1784        Data1

主机发送的报文格式:
主机发送        字节数    发送的信息    备  注
从机地址        1    01        发送至地址为01的从机
功能码        1    06           写入寄存器
起始地址        2    0116        起始地址为0116
写入数据        2    0003        写入1个寄存器(共2个字节)
CRC码        2    E5F3        由主机计算得到CRC码

从机响应返回的报文格式:

从机响应        字节数    返回的信息    备注
从机地址        1    01        来自从机01
功能码        1    06        功能码
起始地址        2    0116        起始地址为0116
写入数据        2    0003        地址为0116内存的内容
CRC码        2    E5F3        由从机计算得到CRC码

/****************************************************************/

功能码“10”:写多路路寄存器输入

例如:主机要读取地址为01,起始地址为0116的1个从机寄存器数据。

例如:主机要读取地址为01,起始地址为0116的3个从机寄存器数据。

从机数据寄存器的地址和数据为:

寄存器地址    寄存器数据    写入数据
0x002C        0x04B0        Data1
0x002D        0x1388        Data2

主机发送的报文格式:
主机发送        字节数    发送的信息    备  注
从机地址        1    01        发送至地址为01的从机
功能码        1    10           写多路寄存器
起始地址        2    002C        需写入得寄存器起始地址
保存数据节长度    2    0002        保存数据的字长度(共2字)
保存数据字节长    1    04        保存数据的字节长度(共4字节)
保存数据1    2    04B0        数据地址002C
保存数据2    2    1388        数据地址002D
CRC码        2    FC63        由主机计算得到的CRC码

从机响应返回的报文格式:

从机响应        字节数    返回的信息    备注
从机地址        1    01        发送至地址为01的从机
功能码        1    10           写多路寄存器
起始地址        2    002C        需写入得寄存器起始地址
保存数据节长度    2    0002        保存数据的字长度(共2字)
CRC码        2    FC63        由主机计算得到的CRC码

/***************************************************************************/

CRC码的计算方法是:
1.预置1个16位的寄存器为十六进制FFFF(即全为1);称此寄存器为CRC寄存器;
2.把第一个8位二进制数据(既通讯信息帧的第一个字节)与16位的CRC寄存器的低8位相异或,把结果放于CRC寄存器;
3.把CRC寄存器的内容右移一位(朝低位)用0填补最高位,并检查右移后的移出位;
4.如果移出位为0:重复第3步(再次右移一位);如果移出位为1:CRC寄存器与多项式A001(1010 0000 0000 0001)进行异或;
5.重复步骤3和4,直到右移8次,这样整个8位数据全部进行了处理;
6.重复步骤2到步骤5,进行通讯信息帧下一个字节的处理;
7.将该通讯信息帧所有字节按上述步骤计算完成后,得到的16位CRC寄存器的高、低字节进行交换;
8.最后得到的CRC寄存器内容即为:CRC码。