无线RTU有什么功能,是否支持modbus通讯协议格式协议?

请问通讯模式ascii和rtu有什么不同?
请问各位老师,modbus通信模式有modbusascii和modbusrtu请问这两种模式有什么异同?该如何选择呀?本人对通讯比较小白,请各位老师指点。谢谢。
最佳答案 1.modbus通信模式有modbusascii和modbusrtu请问这两种模式有什么异同?设备间采用modbus协议进行通讯,如果所有数据帧采用ascii码方式进行编码时,这种叫modbusascii通讯方式;如果采用二进制方式进行编码时,就是rtu方式。从功能来说没有区别,都可以实现设备间的modbus协议通讯。不过从性能来说,区别较大:1)rtu方式通讯速率较高,可达115kbps,ascii方式通讯速率较低,最高不超过38.4kbps。2)效率差异较大,采用rtu方式进行通讯时发一个请求最多8个字节。如果采用ascii码通讯时,发一个请求需要19个字节。因此,效率很低;2.该如何选择呀?很多设备上述两种方式都支持,如果支持一种的话,绝大部分支持rtu方式。国产的仪表很多由于开发问题,支持ascii的较多。
西门子工程师
线下培训课程
免费视频教程用户名:guangrou
访问量:13253
注册日期:
阅读量:1297
阅读量:3317
阅读量:583720
阅读量:468894
[匿名]51cto游客:
51CTO推荐博文
Modbus 是一个工业上常用的通讯协议、一种通讯约定。
ModBus 协议是应用层报文传输协议(OSI 模型第7层),它定义了一个与通信层无关的协议数据单元(PDU),即PDU=功能码+数据域。
ModBus 协议能够应用在不同类型的总线或网络。对应不同的总线或网络,Modbus 协议引入一些附加域映射成应用数据单元(ADU),即ADU=附加域+PDU。目前,Modbus 有下列三种通信方式:
1. 以太网,对应的通信模式是Modbus TCP。
2. 异步串行传输(各种介质如有线RS-232-/422/485/;光纤、无线等),对应的通信模式是 Modbus RTU 或 Modbus ASCII。Modbus 的ASCII、RTU 协议规定了消息、数据的结构、命令和应答的方式,数据通讯采用Maser/Slave方式。
3. 高速令牌传递网络,对应的通信模式是Modbus PLUS。
Modbus 需要对数据进行校验,串行协议中除有奇偶校验外,ASCII 模式采用LRC 校验;RTU 模式采用16位CRC 校验;TCP 模式没有额外规定校验,因为TCP 是一个面向连接的可靠协议。
Modbus 协议的应用中,最常用的是Modbus RTU&传输模式。
RTU 传输模式&
当设备使用RTU&(Remote&Terminal&Unit)&模式在&Modbus&&串行链路通信,&报文中每个位字节含有两个位十六进制字符。这种模式的主要优点是较高的数据密度,在相同的波特率下比ASCII&模式有更高的吞吐率。每个报文必须以连续的字符流传送。&
RTU 模式每个字节&(&11&位&)&的格式为:
&&&&&& 编码系统:& 8位二进制。 报文中每个位的字节含有两个位十六进制字符(0&9,&
& Bits&per&Byte:& 1&起始位
&&&&&&&&&&&& & & & 8&数据位,&首先发送最低有效位
&&&&&&&&&&& & & && 1&位作为奇偶校验
&&&&&&&&&&&&&&& && 1&停止位
偶校验是要求的,其它模式&(&奇校验,&无校验&)&也可以使用。为了保证与其它产品的最大兼容性,同时支持无校验模式是建议的。默认校验模式模式&必须为偶校验。注:使用无校验要求2&个停止位。&
字符的串行传送方式:
每个字符或字节均由此顺序发送(从左到右):最低有效位&(LSB)&.&.&.&最高有效位&(MSB)
650) this.width=650;" src="/images//0927.png" alt="" />
图1:RTU&模式位序列&
设备配置为奇校验、偶校验或无校验都可以接受。如果无奇偶校验,将传送一个附加的停止位以填充字符帧:
650) this.width=650;" src="/images//3933.png" alt="" />
图2:RTU&模式位序列&(无校验的特殊情况)
帧检验域:循环冗余校验&(CRC)
在RTU&模式包含一个对全部报文内容执行的,基于循环冗余校验&(CRC&-&Cyclical&Redundancy&Checking)&算法的错误检验域。
CRC&域检验整个报文的内容。不管报文有无奇偶校验,均执行此检验。
CRC&包含由两个位字节组成的一个位值。&&
CRC&域作为报文的最后的域附加在报文之后。计算后,首先附加低字节,然后是高字节。CRC&高字节为报文发送的最后一个子节。
附加在报文后面的CRC&的值由发送设备计算。接收设备在接收报文时重新计算&CRC&的值,并将计算结果于实际接收到的CRC&值相比较。如果两个值不相等,则为错误。
CRC&的计算,开始对一个位寄存器预装全。&然后将报文中的连续的位子节对其进行后续的计算。只有字符中的个数据位参与生成CRC&的运算,起始位,停止位和校验位不参与&CRC&计算。
CRC&的生成过程中,&每个&8&位字符与寄存器中的值异或。然后结果向最低有效位(LSB)方向移动(Shift)&1位,而最高有效位(MSB)位置充零。&然后提取并检查&LSB:如果LSB&为1,&则寄存器中的值与一个固定的预置值异或;如果LSB&为&0,&则不进行异或操作。
这个过程将重复直到执行完次移位。完成最后一次(第次)移位及相关操作后,下一个位字节与寄存器的当前值异或,然后又同上面描述过的一样重复次。当所有报文中子节都运算之后得到的寄存器中的最终值,就是CRC。
当CRC&附加在报文之后时,首先附加低字节,然后是高字节。
CRC 算法如下:
private&bool&CheckResponse(byte[]&response)&{&&&&&&&&&&byte[]&CRC&=&new&byte[2];&&&&&GetCRC(response,&ref&CRC);&&&&&if&(CRC[0]&==&response[response.Length&-&2]&&&&CRC[1]&==&response[response.Length&-&1])&&&&&return&true;&&&&&else&&&&&return&false;&}&&private&void&GetCRC(byte[]&message,&ref&byte[]&CRC)&{&&&&&&&&&&&&&&&&ushort&CRCFull&=&0xFFFF;&&&&&byte&CRCHigh&=&0xFF,&CRCLow&=&0xFF;&&&&&char&CRCLSB;&&&&&&for&(int&i&=&0;&i&&&(message.Length)&-&2;&i++)&&&&&{&&&&&CRCFull&=&(ushort)(CRCFull&^&message[i]);&&&&&&for&(int&j&=&0;&j&&&8;&j++)&&&&&{&&&&&&&&&CRCLSB&=&(char)(CRCFull&&&0x0001);&&&&&&&&&CRCFull&=&(ushort)((CRCFull&&&&1)&&&0x7FFF);&&&&&&&&&&if&(CRCLSB&==&1)&&&&&&&&&CRCFull&=&(ushort)(CRCFull&^&0xA001);&&&&&}&&&&&}&&&&&CRC[1]&=&CRCHigh&=&(byte)((CRCFull&&&&8)&&&0xFF);&&&&&CRC[0]&=&CRCLow&=&(byte)(CRCFull&&&0xFF);&}&
帧描述 (如下图所示) :
650) this.width=650;" src="/images//5524.png" alt="" />
图3:RTU&报文帧
注意:Modbus&&RTU&帧最大为256字节。
下面是我为公司设计的一个 Modbus RTU 通信测试小工具,界面截图如下:
650) this.width=650;" src="/images//3977.png" alt="" />
图4:Modbus RTU 通信工具
我的通用Modbus RTU 动态库,modbus.cs 如下:
modbus.cs&&using&S&using&System.Collections.G&using&System.T&using&System.IO.P&using&System.T&&namespace&SerialPort_Lib&{&&&&&public&class&modbus&&&&&{&&&&&&&&&private&SerialPort&sp&=&new&SerialPort();&&&&&&&&&public&string&modbusS&&&&&&&&&&#region&Constructor&/&Deconstructor&&&&&&&&&public&modbus()&&&&&&&&&{&&&&&&&&&}&&&&&&&&&~modbus()&&&&&&&&&{&&&&&&&&&}&&&&&&&&&#endregion&&&&&&&&&&#region&Open&/&Close&Procedures&&&&&&&&&public&bool&Open(string&portName,&int&baudRate,&int&databits,&Parity&parity,&StopBits&stopBits)&&&&&&&&&{&&&&&&&&&&&&&&&&&&&&&&&&&&if&(!sp.IsOpen)&&&&&&&&&&&&&{&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&sp.PortName&=&portN&&&&&&&&&&&&&&&&&sp.BaudRate&=&baudR&&&&&&&&&&&&&&&&&sp.DataBits&=&&&&&&&&&&&&&&&&&&sp.Parity&=&&&&&&&&&&&&&&&&&&sp.StopBits&=&stopB&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&sp.ReadTimeout&=&-1;&&&&&&&&&&&&&&&&&sp.WriteTimeout&=&10000;&&&&&&&&&&&&&&&&&&try&&&&&&&&&&&&&&&&&{&&&&&&&&&&&&&&&&&&&&&sp.Open();&&&&&&&&&&&&&&&&&}&&&&&&&&&&&&&&&&&catch&(Exception&err)&&&&&&&&&&&&&&&&&{&&&&&&&&&&&&&&&&&&&&&modbusStatus&=&&Error&opening&&&+&portName&+&&:&&&+&err.M&&&&&&&&&&&&&&&&&&&&&return&false;&&&&&&&&&&&&&&&&&}&&&&&&&&&&&&&&&&&modbusStatus&=&portName&+&&&opened&successfully&;&&&&&&&&&&&&&&&&&return&true;&&&&&&&&&&&&&}&&&&&&&&&&&&&else&&&&&&&&&&&&&{&&&&&&&&&&&&&&&&&modbusStatus&=&portName&+&&&already&opened&;&&&&&&&&&&&&&&&&&return&false;&&&&&&&&&&&&&}&&&&&&&&&}&&&&&&&&&public&bool&Close()&&&&&&&&&{&&&&&&&&&&&&&&&&&&&&&&&&&&if&(sp.IsOpen)&&&&&&&&&&&&&{&&&&&&&&&&&&&&&&&try&&&&&&&&&&&&&&&&&{&&&&&&&&&&&&&&&&&&&&&sp.Close();&&&&&&&&&&&&&&&&&}&&&&&&&&&&&&&&&&&catch&(Exception&err)&&&&&&&&&&&&&&&&&{&&&&&&&&&&&&&&&&&&&&&modbusStatus&=&&Error&closing&&&+&sp.PortName&+&&:&&&+&err.M&&&&&&&&&&&&&&&&&&&&&return&false;&&&&&&&&&&&&&&&&&}&&&&&&&&&&&&&&&&&modbusStatus&=&sp.PortName&+&&&closed&successfully&;&&&&&&&&&&&&&&&&&return&true;&&&&&&&&&&&&&}&&&&&&&&&&&&&else&&&&&&&&&&&&&{&&&&&&&&&&&&&&&&&modbusStatus&=&sp.PortName&+&&&is&not&open&;&&&&&&&&&&&&&&&&&return&false;&&&&&&&&&&&&&}&&&&&&&&&}&&&&&&&&&#endregion&&&&&&&&&&#region&CRC&Computation&&&&&&&&&private&void&GetCRC(byte[]&message,&ref&byte[]&CRC)&&&&&&&&&{&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&ushort&CRCFull&=&0xFFFF;&&&&&&&&&&&&&byte&CRCHigh&=&0xFF,&CRCLow&=&0xFF;&&&&&&&&&&&&&char&CRCLSB;&&&&&&&&&&&&&&for&(int&i&=&0;&i&&&(message.Length)&-&2;&i++)&&&&&&&&&&&&&{&&&&&&&&&&&&&&&&&CRCFull&=&(ushort)(CRCFull&^&message[i]);&&&&&&&&&&&&&&&&&&for&(int&j&=&0;&j&&&8;&j++)&&&&&&&&&&&&&&&&&{&&&&&&&&&&&&&&&&&&&&&CRCLSB&=&(char)(CRCFull&&&0x0001);&&&&&&&&&&&&&&&&&&&&&CRCFull&=&(ushort)((CRCFull&&&&1)&&&0x7FFF);&&&&&&&&&&&&&&&&&&&&&&if&(CRCLSB&==&1)&&&&&&&&&&&&&&&&&&&&&&&&&CRCFull&=&(ushort)(CRCFull&^&0xA001);&&&&&&&&&&&&&&&&&}&&&&&&&&&&&&&}&&&&&&&&&&&&&CRC[1]&=&CRCHigh&=&(byte)((CRCFull&&&&8)&&&0xFF);&&&&&&&&&&&&&CRC[0]&=&CRCLow&=&(byte)(CRCFull&&&0xFF);&&&&&&&&&}&&&&&&&&&#endregion&&&&&&&&&&#region&Build&Message&&&&&&&&&private&void&BuildMessage(byte&address,&byte&type,&ushort&start,&ushort&registers,&ref&byte[]&message)&&&&&&&&&{&&&&&&&&&&&&&&&&&&&&&&&&&&byte[]&CRC&=&new&byte[2];&&&&&&&&&&&&&&message[0]&=&&&&&&&&&&&&&&message[1]&=&&&&&&&&&&&&&&message[2]&=&(byte)(start&&&&8);&&&&&&&&&&&&&message[3]&=&(byte)&&&&&&&&&&&&&message[4]&=&(byte)(registers&&&&8);&&&&&&&&&&&&&message[5]&=&(byte)&&&&&&&&&&&&&&GetCRC(message,&ref&CRC);&&&&&&&&&&&&&message[message.Length&-&2]&=&CRC[0];&&&&&&&&&&&&&message[message.Length&-&1]&=&CRC[1];&&&&&&&&&}&&&&&&&&&#endregion&&&&&&&&&&#region&Check&Response&&&&&&&&&private&bool&CheckResponse(byte[]&response)&&&&&&&&&{&&&&&&&&&&&&&&&&&&&&&&&&&&byte[]&CRC&=&new&byte[2];&&&&&&&&&&&&&GetCRC(response,&ref&CRC);&&&&&&&&&&&&&if&(CRC[0]&==&response[response.Length&-&2]&&&&CRC[1]&==&response[response.Length&-&1])&&&&&&&&&&&&&&&&&return&true;&&&&&&&&&&&&&else&&&&&&&&&&&&&&&&&return&false;&&&&&&&&&}&&&&&&&&&#endregion&&&&&&&&&&#region&Get&Response&&&&&&&&&private&void&GetResponse(ref&byte[]&response)&&&&&&&&&{&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&for&(int&i&=&0;&i&&&response.L&i++)&&&&&&&&&&&&&{&&&&&&&&&&&&&&&&&response[i]&=&(byte)(sp.ReadByte());&&&&&&&&&&&&&}&&&&&&&&&}&&&&&&&&&#endregion&&&&&&&&&&#region&GetModbusData&获得接收数据&&&&&&&&&public&bool&GetModbusData(ref&byte[]&values)&&&&&&&&&{&&&&&&&&&&&&&&&&&&&&&&&&&&if&(sp.IsOpen)&&&&&&&&&&&&&{&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&try&&&&&&&&&&&&&&&&&{&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&int&count&=&sp.BytesToR&&&&&&&&&&&&&&&&&&&&&if&(count&&&0)&&&&&&&&&&&&&&&&&&&&&{&&&&&&&&&&&&&&&&&&&&&&&&&byte[]&readBuffer&=&new&byte[count];&&&&&&&&&&&&&&&&&&&&&&&&&&GetResponse(ref&readBuffer);&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&if&(CheckResponse(readBuffer))&&&&&&&&&&&&&&&&&&&&&&&&&{&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&values&=&readB&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&modbusStatus&=&&Write&successful&;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&sp.DiscardInBuffer();&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&return&true;&&&&&&&&&&&&&&&&&&&&&&&&&}&&&&&&&&&&&&&&&&&&&&&&&&&else&&&&&&&&&&&&&&&&&&&&&&&&&{&&&&&&&&&&&&&&&&&&&&&&&&&&&&&modbusStatus&=&&CRC&error&;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&sp.DiscardInBuffer();&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&return&false;&&&&&&&&&&&&&&&&&&&&&&&&&}&&&&&&&&&&&&&&&&&&&&&}&&&&&&&&&&&&&&&&&&&&&else&return&false;&&&&&&&&&&&&&&&&&}&&&&&&&&&&&&&&&&&catch&(Exception&err)&&&&&&&&&&&&&&&&&{&&&&&&&&&&&&&&&&&&&&&modbusStatus&=&&Error&in&write&event:&&&+&err.M&&&&&&&&&&&&&&&&&&&&&&sp.DiscardInBuffer();&&&&&&&&&&&&&&&&&&&&&&return&false;&&&&&&&&&&&&&&&&&}&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&}&&&&&&&&&&&&&else&&&&&&&&&&&&&{&&&&&&&&&&&&&&&&&modbusStatus&=&&Serial&port&not&open&;&&&&&&&&&&&&&&&&&return&false;&&&&&&&&&&&&&}&&&&&&&&&}&&&&&&&&&#endregion&&&&&&&&&&#region&SendModbusData&打包发送数据&&&&&&&&&public&bool&SendModbusData(ref&byte[]&values)&&&&&&&&&{&&&&&&&&&&&&&&&&&&&&&&&&&&if&(sp.IsOpen)&&&&&&&&&&&&&{&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&sp.DiscardOutBuffer();&&&&&&&&&&&&&&&&&sp.DiscardInBuffer();&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&byte[]&response&=&new&byte[values.Length&+&2];&&&&&&&&&&&&&&&&&Array.Copy(values,&response,&values.Length);&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&byte[]&CRC&=&new&byte[2];&&&&&&&&&&&&&&&&&GetCRC(response,&ref&CRC);&&&&&&&&&&&&&&&&&response[response.Length&-&2]&=&CRC[0];&&&&&&&&&&&&&&&&&response[response.Length&-&1]&=&CRC[1];&&&&&&&&&&&&&&&&&&values&=&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&try&&&&&&&&&&&&&&&&&{&&&&&&&&&&&&&&&&&&&&&sp.Write(response,&0,&response.Length);&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&return&true;&&&&&&&&&&&&&&&&&}&&&&&&&&&&&&&&&&&catch&(Exception&err)&&&&&&&&&&&&&&&&&{&&&&&&&&&&&&&&&&&&&&&modbusStatus&=&&Error&in&read&event:&&&+&err.M&&&&&&&&&&&&&&&&&&&&&return&false;&&&&&&&&&&&&&&&&&}&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&}&&&&&&&&&&&&&else&&&&&&&&&&&&&{&&&&&&&&&&&&&&&&&modbusStatus&=&&Serial&port&not&open&;&&&&&&&&&&&&&&&&&return&false;&&&&&&&&&&&&&}&&&&&&&&&&}&&&&&&&&&#endregion&&&&&&}&}&
调用的主要代码如下:
modbus类的winform调用代码&&public&partial&class&FormConfig&:&Form,IModbusData&{&&&&&&&&&&B_ModbusData&ModbusDataBLL&=&new&B_ModbusData();&&&&&&modbus&mb&=&new&modbus();&&&&&&&&&&System.Timers.Timer&timer&=&new&System.Timers.Timer();&&&&&&public&FormConfig()&&&&&{&&&&&&&&&InitializeComponent();&&&&&&&&&&&&&&&&&timer.Elapsed&+=&new&ElapsedEventHandler(timer_Elapsed);&&&&&}&&&&&&#region&Timer&Elapsed&事件处理程序&&&&&bool&runEnd&=&true;&&&&&void&timer_Elapsed(object&sender,&ElapsedEventArgs&e)&&&&&{&&&&&&&&&if&(runEnd&==&true)&&&&&&&&&{&&&&&&&&&&&&&runEnd&=&false;&&&&&&&&&&&&&PollFunction();&&&&&&&&&&&&&runEnd&=&true;&&&&&&&&&}&&&&&}&&&&&&&&&&&private&void&PollFunction()&&&&&{&&&&&&&&&byte[]&values&=&null;&&&&&&&&&try&&&&&&&&&{&&&&&&&&&&&&&mb.GetModbusData(ref&values);&&&&&&&&&&&&&&&&&&&&&&}&&&&&&&&&catch&(Exception&err)&&&&&&&&&{&&&&&&&&&&&&&DoGUIStatus(&Error&in&modbus&read:&&&+&err.Message);&&&&&&&&&}&&&&&&&&&&if&(values&!=&null)&&&&&&&&&{&&&&&&&&&&&&&&&&&&&&&&&&&&byte[]&sendData&=&ModbusDataProcess(values);&&&&&&&&&}&&&&&}&&&&&#endregion&&&&&&#region&IModbusData&接口成员处理&&&&&public&byte[]&ModbusDataProcess(byte[]&_data)&&&&&{&&&&&&&&byte[]&sendData&=&ModbusDataBLL.ModbusDataProcess(_data);&&&&&&&&&&&&&&&&&mb.SendModbusData(ref&sendData);&&&&&&&&&return&sendD&&&&&}&&&&&#endregion&}&
其实,三步就能成功调用:
modbus&mb&=&new&modbus();&mb.GetModbusData(ref&values);&&byte[]&sendData&=&ModbusDataBLL.ModbusDataProcess(values);&&mb.SendModbusData(ref&sendData);&&
主要代码已全部提供,由于工作原因暂不提供完整工具源代码,见谅!
&本文出自 “” 博客,请务必保留此出处
了这篇文章
类别:┆阅读(0)┆评论(0)modbus通信协议中的功能码使用以及异常功能码和错误码的使用
Modbus协议主要构成是地址码/标识码,功能码,寄存器地址,数据报文等内容。由于modbus协议是请求/应答通信协议,其其中功能码主要用于表述该数据报文执行的功能,当服务器对客户机进行响应时,它使用功能码域来指示正常响应(无差错)或者异常响应(即出现某种差错),其中的modbus协议的功能码众多,在此我们一一列出与大家分享。
功能码(十六进制)
异常功能码
物理离散量输入
读输入离散量
内部比特或者物理线圈
写单个线圈
写多个线圈
16比特访问
输入存储器
读输入寄存器
内部存储器或物理输出存储器(保持寄存器)
读多个寄存器
写单个寄存器
写多个寄存器
读/写多个寄存器
屏蔽写寄存器
文件记录访问
读文件记录
写文件记录
其中物理离散量输入和输入寄存器只能有I/O系统提供的数据类型,即只能是由I/O系统改变离散量输入和输入寄存器的数值,而上位机程序不能改变的数据类型,在数据读写上表现为只读,而内部比特或者物理线圈和内部寄存器或物理输出寄存器(保持寄存器)则是上位机应用程序可以改变的数据类型,在数据读写上表现为可读可写。
错误代码表
对于服务器(或从站)来说,询问中接收到的功能码是不可允许的操作,可能是因为功能码仅适用于新设备而被选单元中不可实现同时,还指出服务器(或从站)在错误状态中处理这种请求,例如:它是未配置的,且要求返回寄存器值。
非法数据地址
对于服务器(或从站)来说,询问中接收的数据地址是不可允许的地址,特别是参考号和传输长度的组合是无效的。对于带有100个寄存器的控制器来说,偏移量96和长度4的请求会成功,而偏移量96和长度5的请求将产生异常码02。
非法数据值
对于服务器(或从站)来说,询问中包括的值是不可允许的值。该值指示了组合请求剩余结构中的故障。例如:隐含长度是不正确的。modbus协议不知道任何特殊寄存器的任何特殊值的重要意义,寄存器中被提交存储的数据项有一个应用程序期望之外的值。
从站设备故障
当服务器(或从站)正在设法执行请求的操作时,产生不可重新获得的差错。
与编程命令一起使用,服务器(或从站)已经接受请求,并且正在处理这个请求,但是需要长持续时间进行这些操作,返回这个响应防止在客户机(或主站)中发生超时错误,客户机(或主机)可以继续发送轮询程序完成报文来确认是否完成处理。
从属设备忙
与编程命令一起使用,服务器(或从站)正在处理长持续时间的程序命令,当服务器(或从站)空闲时,客户机(或主站)应该稍后重新传输报文。
存储奇偶性差错
与功能码20和21以及参考类型6一起使用,指示扩展文件区不能通过一致性校验。服务器(或从站)设备读取记录文件,但在存储器中发现一个奇偶校验错误。客户机(或主机)可重新发送请求,但可以在服务器(或从站)设备上要求服务。
不可用网关路径
与网关一起使用,指示网关不能为处理请求分配输入端口值输出端口的内部通信路径,通常意味着网关是错误配置的或过载的。
网关目标设备响应失败
与网关一起使用,指示没有从目标设备中获得响应,通常意味着设备未在网络中。
我们以Modbus RTU协议为例,地址码为0x01,写操作0x10,寄存器地址为0x018E,CRC校验。如寄存器可读写的话,返回正常,如寄存器只读,返回异常。
下发指令:01 10 01 8E 00 01 02 00 00 69 BE(向寄存器0x018E写入一个数值为0的数据)
正确回应指令:01 10 01 8E 00 01 60 1E(向寄存器地址0x018E写操作一个寄存器)
错误回应指令:01 90 01 8D C0(写操作非法功能,可能是向输入寄存器写数据)}

我要回帖

更多关于 modbus协议 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信