最新文章专题视频专题问答1问答10问答100问答1000问答2000关键字专题1关键字专题50关键字专题500关键字专题1500TAG最新视频文章推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37视频文章20视频文章30视频文章40视频文章50视频文章60 视频文章70视频文章80视频文章90视频文章100视频文章120视频文章140 视频2关键字专题关键字专题tag2tag3文章专题文章专题2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章专题3
当前位置: 首页 - 正文

Modbus Rtu 3-16号通信协议解释

来源:动视网 责编:小OO 时间:2025-09-23 21:00:00
文档

Modbus Rtu 3-16号通信协议解释

ModbusRtu通信协议(3,16号命令) 1、读取保持寄存器(单个和多个,以字为最小单位)发送命令帧:设备地址功能码地址H地址L数据量H数据量LCRCHCRCLAddr03HHoldStartDataNumCRC高位CRC低位帧长度:8个字节设备地址:1~247功能码:3H数据地址:0~6具体范围与相关设备有关数量:1~6具体范围与相关设备有关校验码:CRC16校验 返回命令帧:设备地址功能码数据量数据1数据NCRCHCRCLAddr13H返回数据的字节数NData(1~N)CRC高位CR
推荐度:
导读ModbusRtu通信协议(3,16号命令) 1、读取保持寄存器(单个和多个,以字为最小单位)发送命令帧:设备地址功能码地址H地址L数据量H数据量LCRCHCRCLAddr03HHoldStartDataNumCRC高位CRC低位帧长度:8个字节设备地址:1~247功能码:3H数据地址:0~6具体范围与相关设备有关数量:1~6具体范围与相关设备有关校验码:CRC16校验 返回命令帧:设备地址功能码数据量数据1数据NCRCHCRCLAddr13H返回数据的字节数NData(1~N)CRC高位CR
Modbus Rtu 通信协议(3,16号命令)

 1、 读取保持寄存器(单个和多个,以字为最小单位)

发送命令帧:

设备地址功能码地址H

地址L

数据量H

数据量L

CRC HCRC L
Addr03 HHoldStartDataNumCRC高位

CRC低位

帧 长 度:8个字节

设备地址:1~247

功 能 码:3H

数据地址:0~6具体范围与相关设备有关

数 量:1~6具体范围与相关设备有关

校 验 码:CRC16校验

 返回命令帧:

设备地址功能码数据量数据1

数据N

CRC HCRC L
Addr13 H返回数据的字节数N

Data (1~N)

CRC高位

CRC低位

帧 长 度:5+N 个字节

设备地址:1~247

功 能 码:3H

数 据 量:实际的读取数据数量

数 据:返回数据的意义

a=HoldStart

n= DataNum-1

VW a (VB a)

VWa(VB a+1)

VW a+n(VB a+n)

VWa+n(VB a+n+1)

Data(1)

Data(2)Data(N-1)Data(N)
校 验 码:CRC16校验

命令有误:

1)        没有任何返回

2)        返回异议帧

设备地址功能码错误信息CRC HCRC L
Addr183 H一个字节的错误信息CRC高位

CRC低位

2、 设置保持寄存器(多个,以字为最小单位)

发送命令帧:

 设备地址

功能码地址H

地址L

数据量H

数据量L

数据字节数具体

数据

CRC HCRC L
Addr010 HHoldStartDataNumbytN1~bytN

CRC高位

CRC低位

帧 长 度:9+bytN 个字节

设备地址:1~247

功 能 码:10H

数据地址:0~6具体范围与相关设备有关

数 量:1~1具体范围与相关设备有关

字 节 数:设置的字节个数 bytN= DataNum×2

数 据:具体的字节数据

校 验 码:CRC16校验

 返回命令帧:

设备地址功能码地址H

地址L

数据量H

数据量L

CRC HCRC L
Addr110 HHoldStartDataNumCRC高位

CRC低位

帧 长 度:8 个字节

设备地址:1~247

功 能 码:10H

数据地址:0~6具体范围与相关设备有关     

数 量:1~1具体范围与相关设备有关

校 验 码:CRC16校验

 命令有误:

1)    没有任何返回

2)     返回异议帧

地址功能码错误信息CRC HCRC L
Addr190 H一个字节的错误信息CRC高位

CRC低位

设置单个寄存器(06H)

发送命令帧:

 设备地址

功能码地址H

地址L

数据H

数据L

CRC HCRC L
Addr006H

HoldStartDataCRC高位

CRC低位

返回命令帧:

设备地址功能码地址H

地址L

数据H

数据L

CRC HCRC L
Addr106H

HoldStartDataCRC高位

CRC低位

CRC-16(循环冗余错误校验) 

 错误校验程序如下:报文(此处只涉及数据位,不指起始位、停止位和任选的奇偶校验位)被看作是一个连续的二进制,其最高有效位(MSB)首选发送。报文先与X^16相乘(左移16位),然后看X^16+X^15+X^2+1除,X^16+X^15+X^2+1可以表示为二进制数1 1000 0000 0000 0101。整数商位忽略不记,16位余数加入该报文(MSB先发送),成为2个CRC校验字节。余数中的1全部初始化,以免所有的零成为一条报文被接收。经上述处理而含有CRC字节的报文,若无错误,到接收设备后再被同一多项式(X^16+X^15+X^2+1)除,会得到一个零余数(接收设备核验这个CRC字节,并将其与被传送的CRC比较)。全部运算以2为模(无进位)。 

 习惯于成串发送数据的设备会首选送出字符的最右位(LSB-最低有效位)。而在生成CRC情况下,发送首位应是被除数的最高有效位MSB。由于在运算中不用进位,为便于操作起见,计算CRC时设MSB在最右位。生成多项式的位序也必须反过来,以保持一致。多项式的MSB略去不记,因其只对商有影响而不影响余数。 

生成CRC-16校验字节的步骤如下: 

①装如一个16位寄存器,所有数位均为1。 

②该16位寄存器的高位字节与开始8位字节进行“异或”运算。运算结果放入这个16位寄存器。 

③把这个16寄存器向右移一位。 

④若向右(标记位)移出的数位是1,则生成多项式1010000000000001和这个寄存器进行“异或”运算;若向右移出的数位是0,则返回③。 

⑤重复③和④,直至移出8位。 

⑥另外8位与该十六位寄存器进行“异或”运算。 

⑦重复③~⑥,直至该报文所有字节均与16位寄存器进行“异或”运算,并移位8次。 

⑧这个16位寄存器的内容即2字节CRC错误校验,被加到报文的最高有效位。 

 

 另外,在某些非ModBus通信协议中也经常使用CRC16作为校验手段,而且产生了一些CRC16的变种,他们是使用CRC16多项式X↑16+X↑15+X↑2+1,单首次装入的16位寄存器为0000;使用CRC16的反序X↑16+X↑14+X↑1+1,首次装入寄存器值为0000或FFFFH。 

 

LRC(纵向冗余错误校验) 

 错误校验用于ASCII模式。这个错误校验是一个8位二进制数,可作为2个ASCII十六进制字节传送。把十六进制字符转换成二进制,加上无循环进位的二进制字符和二进制补码结果生成LRC错误校验(参见图)。这个LRC在接收设备进行核验,并与被传送的LRC进行比较,冒号(:)、回车符号(CR)、换行字符(LF)和置入的其他任何非ASCII十六进制字符在运算时忽略不计。 

十六进制 

二进制

地址 0 2 0000 0010

功能码 0 1 0000 0001

起始地址高位 0 0 0000 0000

起始地址低位 0 0 0000 0000

单元数量 0 0 0000 0000

0 8 + 0000 1000

0000 1011

变成补码 1111 0101

错误校验 F 5 F 5

 接受PC把所有收到的数据字节(包括最后的LRC)加在一起,8位应全部为0(注意:和可能超过8位,应略去最低位) 0000 0010

0000 0001

0000 0000

0000 0000

0000 0000

0000 1000

错误校验 1111 0101和 0000 0000

3、CRC检测 

 使用RTU模式,消息包括了一基于CRC方法的错误检测域。CRC域检测了整个消息的内容。 

CRC域是两个字节,包含一16位的二进制值。它由传输设备计算后加入到消息中。接收设备重新计算收到消息的CRC,并与接收到的CRC域中的值比较,如果两值不同,则有误。 

 

 是先调入一值是全“1”的16位寄存器,然后调用一过程将消息中连续的8位字节各当前寄存器中的值进行处理。仅每个字符中的8Bit数据对CRC有效,起始位和停止位以及奇偶校验位均无效。 

 

 产生过程中,每个8位字符都单独和寄存器内容相或(OR),结果向最低有效位方向移动,最高有效位以0填充。LSB被提取出来检测,如果LSB为1,寄存器单独和预置的值或一下,如果LSB为0,则不进行。整个过程要重复8次。在最后一位(第8位)完成后,下一个8位字节又单独和寄存器的当前值相或。最终寄存器中的值,是消息中所有的字节都执行之后的CRC值。 

CRC添加到消息中时,低字节先加入,然后高字节。 

CRC简单函数如下: 

unsigned short CRC16(puchMsg, usDataLen) 

unsigned char *puchMsg ; /* 要进行CRC校验的消息 */ 

unsigned short usDataLen ; /* 消息中字节数 */ 

unsigned char uchCRCHi = 0xFF ; /* 高CRC字节初始化 */ 

unsigned char uchCRCLo = 0xFF ; /* 低CRC 字节初始化 */ 

unsigned uIndex ; /* CRC循环中的索引 */ 

while (usDataLen--) /* 传输消息缓冲区 */ 

uIndex = uchCRCHi ^ *puchMsgg++ ; /* 计算CRC */ 

uchCRCHi = uchCRCLo ^ auchCRCHi[uIndex} ; 

uchCRCLo = auchCRCLo[uIndex] ; 

return (uchCRCHi << 8 | uchCRCLo) ;

/* CRC 高位字节值表 */ 

static unsigned char auchCRCHi[] = { 

0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 

0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 

0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 

0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 

0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 

0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 

0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 

0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 

0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 

0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 

0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 

0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 

0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 

0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 

0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 

0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 

0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 

0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 

0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 

0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 

0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 

0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 

0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 

0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 

0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 

0x80, 0x41, 0x00, 0xC1, 0x81, 0x40 

} ; 

/* CRC低位字节值表*/ 

static char auchCRCLo[] = { 

0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 

0x07, 0xC7, 0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD, 

0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09, 

0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A, 

0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC, 0x14, 0xD4, 

0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3, 

0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 

0xF2, 0x32, 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4, 

0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A, 

0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29, 

0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF, 0x2D, 0xED, 

0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26, 

0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, 

0x61, 0xA1, 0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67, 

0xA5, 0x65, 0x, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F, 

0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68, 

0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA, 0xBE, 0x7E, 

0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5, 

0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 

0x70, 0xB0, 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92, 

0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C, 

0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B, 

0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x, 0x4B, 0x8B, 

0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C, 

0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 

0x43, 0x83, 0x41, 0x81, 0x80, 0x40 

} ;

转自:生活安全网(http://anquanweb.com)

表1 ModBus功能码 

 

功能码 名称 作用

01 读取线圈状态 取得一组逻辑线圈的当前状态(ON/OFF)

02 读取输入状态 取得一组开关输入的当前状态(ON/OFF)

03 读取保持寄存器 在一个或多个保持寄存器中取得当前的二进制值

04 读取输入寄存器 在一个或多个输入寄存器中取得当前的二进制值

05 强置单线圈 强置一个逻辑线圈的通断状态

06 预置单寄存器 把具体二进值装入一个保持寄存器

07 读取异常状态 取得8个内部线圈的通断状态,这8个线圈的地址由控制器决定,用户逻辑可以将这些线圈定义,以说明从机状态,短报文适宜于迅速读取状态

08 回送诊断校验 把诊断校验报文送从机,以对通信处理进行评鉴

09 编程(只用于484) 使主机模拟编程器作用,修改PC从机逻辑

10 控询(只用于484) 可使主机与一台正在执行长程序任务从机通信,探询该从机是否已完成其操作任务,仅在含有功能码9的报文发送后,本功能码才发送

11 读取事件计数 可使主机发出单询问,并随即判定操作是否成功,尤其是该命令或其他应答产生通信错误时

12 读取通信事件记录 可是主机检索每台从机的ModBus事务处理通信事件记录。如果某项事务处理完成,记录会给出有关错误

13 编程(184/384 484 584) 可使主机模拟编程器功能修改PC从机逻辑

14 探询(184/384 484 584) 可使主机与正在执行任务的从机通信,定期控询该从机是否已完成其程序操作,仅在含有功能13的报文发送后,本功能码才得发送

15 强置多线圈 强置一串连续逻辑线圈的通断

16 预置多寄存器 把具体的二进制值装入一串连续的保持寄存器

17 报告从机标识 可使主机判断编址从机的类型及该从机运行指示灯的状态

18 (884和MICRO 84) 可使主机模拟编程功能,修改PC状态逻辑

19 重置通信链路 发生非可修改错误后,是从机复位于已知状态,可重置顺序字节

20 读取通用参数(584L) 显示扩展存储器文件中的数据信息

21 写入通用参数(584L) 把通用参数写入扩展存储文件,或修改之

22~ 保留作扩展功能备用 

65~72 保留以备用户功能所用 留作用户功能的扩展编码

73~119 非法功能 

120~127 保留 留作内部作用

128~255 保留 用于异常应答

unsigned int alex_crc16(unsigned char *buf, unsigned int len) 

{

    int i,j;

    unsigned int c, crc = 0xFFFF;

    for (i = 0; i < len; i++){

   c = *(buf+i) & 0x00FF;

   crc^=c;

        for(j=0;j<8;j++){

             if (crc & 0x0001)

                 {crc>>=1;crc^=0xA001;}

             else crc>>=1;

        }

    }

    return(crc);

}

int main(void)

{

char buf[] = {0x01, 0x02, 0x00, 0xc4, 0x00, 0x16}; 

printf("CRC:%x\\n",alex_crc16(buf, 6));

return 0;

}

文档

Modbus Rtu 3-16号通信协议解释

ModbusRtu通信协议(3,16号命令) 1、读取保持寄存器(单个和多个,以字为最小单位)发送命令帧:设备地址功能码地址H地址L数据量H数据量LCRCHCRCLAddr03HHoldStartDataNumCRC高位CRC低位帧长度:8个字节设备地址:1~247功能码:3H数据地址:0~6具体范围与相关设备有关数量:1~6具体范围与相关设备有关校验码:CRC16校验 返回命令帧:设备地址功能码数据量数据1数据NCRCHCRCLAddr13H返回数据的字节数NData(1~N)CRC高位CR
推荐度:
  • 热门焦点

最新推荐

猜你喜欢

热门推荐

专题
Top