modbus协议概述内容摘要:

生(称作异议回应)。 对正常回应,从设备仅回应相应的功能代码。 对异议回应,从设备返回一等同于正常代码的代码,但最重要的位 置为逻辑 1。 例如:一从主设备发往从设备的消息要求读一组保持寄存器,将产生如下功能代码: 0 0 0 0 0 0 1 1 (十六进制 03H) 对正常回应,从设备仅回应同样的功能代码。 对异议回应,它返回: 1 0 0 0 0 0 1 1 (十六进制 83H) 除功能代码因异议错误作了修改外,从设备将一独特的代码放到回应消息的数据域中,这能告诉主设备发生了什么错误。 主设备应用程序得到异议的回应后,典型的处理过程是重发消息,或者诊断发给从设备的消息并报告给操作员。 数据域 数据域是由两个十六 进制数集合构成的,范围 00...FF。 根据网络传输模式,这可以是由一对 ASCII 字符组成或由一 RTU 字符组成。 从主设备发给从设备消息的数据域包含附加的信息:从设备必须用于进行执行由功能代码所定义的所为。 这包括了象不连续的寄存器地址,要处理项的数目,域中实际数据字节数。 例如,如果主设备需要从设备读取一组保持寄存器(功能代码 03),数据域指定了起始寄存器以及要读的寄存器数量。 如果主设备写一组从设备的寄存器(功能代码 10十六进制),数据域则指明了要写的起始寄存器以及要写的寄存器数量,数据域的数据字节数,要写入 寄存器的数据。 如果没有错误发生,从从设备返回的数据域包含请求的数据。 如果有错误发生,此域包含一异议代码,主设备应用程序可以用来判断采取下一步行动。 在某种消息中数据域可以是不存在的( 0 长度)。 例如,主设备要求从设备回应通信事件记录(功能代码 0B 十六进制),从设备不需任何附加的信息。 错误检测域 标准的 Modbus 网络有两种错误检测方法。 错误检测域的内容视所选的检测方法而定。 ASCII 当选用 ASCII 模式作字符帧,错误检测域包含两个 ASCII 字符。 这是使用 LRC(纵向冗长检测)方法对消息内 容计算得出的,不包括开始的冒号符及回车换行符。 LRC 字符附加在回车换行符前面。 RTU 当选用 RTU 模式作字符帧,错误检测域包含一 16Bits 值 (用两个 8 位的字符来实现 )。 错误检测域的内容是通过对消息内容进行循环冗长检测方法得出的。 CRC域附加在消息的最后,添加时先是低字节然后是高字节。 故 CRC 的高位字节是发送消息的最后一个字节。 字符的连续传输 当消息在标准的 Modbus 系列网络传输时,每个字符或字节以如下方式发送(从左到右): 最低有效位 ...最高有效位 使用 ASCII 字符帧时,位的序 列是: 有奇偶校验 启始位 1 2 3 4 5 6 7 奇偶位 停止位 无奇偶校验 启始位 1 2 3 4 5 6 7 停止位 停止位 图 4. 位顺序( ASCII) 使用 RTU 字符帧时,位的序列是: 有奇偶校验 启始位 1 2 3 4 5 6 7 8 奇偶位 停止位 无奇偶校验 启始位 1 2 3 4 5 6 7 8 停止位 停止位 图 4. 位顺序( RTU) 四、错误检测方法 标准的 Modbus 串行网络采用两种错误检测方法。 奇偶校验对每个字符都可用,帧检测( LRC 或 CRC)应用于整个消息。 它们都是在消息发送前由主设备产生的,从设备在接收过程中检测每个字符和整个消息帧。 用户要给主设备配置一预先定义的超时时间间隔,这个时间间隔要足够长,以使任何从设备都能作为正常反应。 如果从设备测到一传输错误,消息将不会接收,也不会向主设备作出回应。 这样超时事件将触发主设备来处理 错误。 发往不存在的从设备的地址也会产生超时。 奇偶校验 用户可以配置控制器是奇或偶校验,或无校验。 这将决定了每个字符中的奇偶校验位是如何设置的。 如果指定了奇或偶校验,“ 1”的位数将算到每个字符的位数中( ASCII 模式 7个数据位, RTU中 8 个数据位)。 例如 RTU 字符帧中包含以下 8 个数据位: 1 1 0 0 0 1 0 1 整个“ 1”的数目是 4 个。 如果便用了偶校验,帧的奇偶校验位将是 0,便得整个“ 1”的个数仍是 4 个。 如果便用了奇校验,帧的奇偶校验位将是 1,便得整个“ 1”的个数是 5 个。 如果 没有指定奇偶校验位,传输时就没有校验位,也不进行校验检测。 代替一附加的停止位填充至要传输的字符帧中。 LRC 检测 使用 ASCII 模式,消息包括了一基于 LRC方法的错误检测域。 LRC域检测了消息域中除开始的冒号及结束的回车换行号外的内容。 LRC 域是一个包含一个 8 位二进制值的字节。 LRC 值由传输设备来计算并放到消息帧中,接收设备在接收消息的过程中计算 LRC,并将它和接收到消息中 LRC 域中的值比较,如果两值不等,说明有错误。 LRC 方法是将消息中的 8Bit 的字节连续累加,丢弃了进位。 LRC 简单函数如下: static unsigned char LRC(auchMsg,usDataLen) unsigned char *auchMsg。 /* 要进行计算的消息 */ unsigned short usDataLen。 /* LRC 要处理的字节的数量 */ { unsigned char uchLRC = 0。 /* LRC 字节初始化 */ while (usDataLen) /* 传送消息 */ uchLRC += *auchMsg++。 /* 累加 */ return ((unsigned char)(((char_uchLRC)))。 } CRC 检测 使用 RTU 模式,消息包括了一基于 CRC 方法的错误检测域。 CRC 域检测了整个消息的内容。 CRC 域是两个字节,包含一 16 位的二进制值。 它由传输设备计算后加入到消息中。 接收设备重新计算收到消息的 CRC,并与接收到的 CRC 域中的值比较,如果两值不同,则有误。 CRC 是先调入一值是全“ 1”的 16 位寄存器,然后调用一过程将消息中连续的 8 位字节各当前寄存器中的值进行处理。 仅每个字符中的 8Bit 数据对 CRC 有效,起始位和停止位以 及奇偶校验位均无效。 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, 0x8。
阅读剩余 0%
本站所有文章资讯、展示的图片素材等内容均为注册用户上传(部分报媒/平媒内容转载自网络合作媒体),仅供学习参考。 用户通过本站上传、发布的任何内容的知识产权归属用户或原始著作权人所有。如有侵犯您的版权,请联系我们反馈本站将在三个工作日内改正。