一、简介
ModBus是一种串行通信协议,是施耐德电气与1979年发布的,目前已经成为工业领域通信协议的业界标准,它一般是基于RS485,默认波特率为9600。
每一帧的数据格式为
说明 | 地址域 | 功能域 | 数据域 | CRC校验域 |
---|
字节数 | 1 | 1 | N | 2 |
1、地址域,在帧首,一般只使用1~247。该字节表明了终端设备的地址,而且是唯一的。须有被寻址到的终端才会响应,终端响应时,需要把自己的地址放在帧中。直流电表的默认地址为1。 | | | | |
2、功能域,它用来告知被寻址的终端需要执行何种功能。如下部分功能码 | | | | |
功能域 | 意义 | 行为 |
---|
0x03 | 读取保持寄存器 | 在一个或多个保持寄存器中去得当前的二进制值 |
0x10 | 预置多寄存器 | 把具体的二进制值装入一串连续的保持寄存器 |
0x06 | 写单路寄存器 | 把一组二进制数据写入单个寄存器 |
3、数据域,数据域的内容根据发送和接收而不同。 | | |
如果是发送,数据域为4字节,前两字节为数据地址的起始地址,后两个字节为要读取寄存器的个数,都是高字节在前,低字节在后。例如 | | |
00 | 00 | 00 | 02 |
---|
表明数据起始地址为0x00,要读取2个寄存器。 | | | |
如果是接收,数据域的字节数不固定,第一个字节为功能域,第二个字节为后续数据的长度,从第三个字节开始,都是数据。例如 | | | |
03 | 04 | 13 | 88 |
– | – | – | – |
表明数据的长度为4字节,后续为实际数据,在特来电直流电表手册中,表明这是一组电压数据,每一个数据2个字节,一共2个。高字节在前,低字节在后,故电压为0x1388,电压系数为0xFFFF,故最终电压为500V。 | | | |
4、CRC校验域,帧的CRC校验,前面的所有数据都要校验。 | | | |
二、实例
1、0x03功能码
下图是通过RS485抓取到的直流电表的通讯数据。
这个电表不是特来电的电表,故在数据寄存器地址上有差异。
首先是向终端发送读取保持寄存器的命令,终端地址为1,数据寄存器的起始地址为0x0C,读取数据的个数是4个。
终端返回读取到的数据,因为该电表会检测两个充电枪,故读出来的数据是两个,8字节。第一组的数据为“0x89,0x13,0x00,0x14”,这组数据是2字节一组,并且按照小端存储,实际的读数应该为0x148913=1345811,实际的读数为13458.03,这是A枪的电量。第二组的数据为B枪的电量
同理后面两个帧也是如此,先向终端发送读取命令,然后再回复读取到的数据。4字节是一组命令,其中顺序依次为A枪电压、B枪电压、A枪电流、B枪电流。
2、0x06功能码
主机要把数据07D0,保存到地址为002C的从机寄存器中去(从机地址码为01)。通讯数据保存结束后,地址为002C的PDM表原存储信息为:
地址 | 原来存储数据(16进制) |
---|
002C | 04B0 |
主机发送的报文格式: | |
主机发送 | 字节数 |
– | – |
从机地址 | 1 |
功能码 | 1 |
起始地址 | 2 |
写入数据 | 2 |
CRC码 | 2 |
从机(PDM)响应返回的报文格式与主机发送的报文格式及数据内容完全相同。 | |