Modbus?是?使用?主从关系?实现?的?请求 - 响应?协议。 在?主从关系?中,?通信?总是?成?对?发生 - 一个?设备?必须?发起?请求,?然后?等待?响应 - 并且?发起?设备?(主?设备)?负责?发起?每次?交互。 通常,?主?设备?是?人?机?界面?(HMI)?或?监?控?和?数据?采集?(SCADA)?系统,?从?设备?是?传感器、?可?编?程?逻辑?控制器?(PLC)?或可?编?程?自动?化?控制器?(PAC)。 这些?请求?和?响应?的?内容?以及?发送?这些?消息?的?网络?层?由?协议?的?不同?层?来?定义。
在?最初?的?做法?中,?Modbus?是?建立?在?串?行?端?口?之上?的?单一?协议,?因此?它?不能?被?分成?多个?层。 随着?时间?的?推移,?该?协议?引入?了?不同?的?应用?程序?数据?单元?来?更改?串?行?通信?使用?的?数据?包?格式,?或?允许?使用?TCP/?IP?和?用户?数据?报?协议?(UDP)?网络。 这?实现?了?定义?协议?数据?单元?(PDU)?的?核心?协议?和?定义?应用?数据?单元?(ADU)?的?网络?层?的?分离。
PDU?及其?处理?代码?构成了Modbus?应用?协议?规范的?核心。 该?规范?定义?了?PDU?的?格式、?协议?使用?的?各种?数据?概念、?如何?使用?功能?代码?访问?数据,?以及?每?个?功能?代码?的?具体?实现?和?限制。
Modbus PDU?格式?被?定义?为?一个?功能?代码,?后面?跟着?一?组?关联?的?数据。 该?数据?的?大小?和?内容?由?功能?代码?定义,?整个?PDU(功能?代码?和?数据)?的?大小?不能?超过?253?个?字?节。 每?个?功能?代码?都有?一个?特定?的?行为,?从?设备?可以?根据?所需?的?应用?程序?行为?灵活?地?实现?这些?行为。 PDU?规范?定义?了?数据?访问?和?操作?的?核心?概念;?但是,?从?设备?可能?会?以?规范?中?未?明确?定义?的?方式?处理?数据。
通常,?Modbus?可?访问?的?数据?存储?在?四?个?数据?库?或?地址?范围?的?其中?一个: 线圈?状态、?离散?量?输入、?保持?寄存器?和?输入?寄存器。 与?许多?规范?一样,?名称?可能?因?行业?或?应用?而?异。 例如,?保持?寄存器?也可以?称为?输出?寄存器,?线圈?状态?可能?称为?数字?或?离散?量?输出。 这些?数据?库?定义?了?所?包含?数据?的?类型?和?访问?权限。 从?设备?可以?直接?访问?这些?数据,?因为?这些?数据?由?设备?本地?托管。 Modbus?可?访问?的?数据?通常?是?设备?主?存?的?一个?子?集。 相反,?Modbus?主?设备?必须?通过?各种?功能?代码?请求?访问?这些?数据。 表?1?中?描述?了?每?个?区块?的?行为。
内存?区块 | 数据?类型 | 主?设备?访问 | 从?设备?访问 |
线圈?状态 | 布尔 | 读/写 | 读/写 |
离散?输入 | 布尔 | 只读 | 读/写 |
保持?寄存器 | 无?符号?双?字?节?整型 | 读/写 | 读/写 |
输入?寄存器 | 无?符号?双?字?节?整型 | 只读 | 读/写 |
表?1. Modbus?数据?模型?区块
这些?区块?允许?您?限制?或?允许?访问?不同?的?数据?元素,?并且?为?应用?层?提供?简化?的?机制?来?访问?不同?的?数据?类型。
这些?区块?是?完全?概念?性的。 它们?可能?作为?独立?的?内存?地址?存在?于?给?定?的?系统?中,?但?也?可能?重叠。 例如,?线圈?状态?1?可能?存在?于?与?保持?寄存器?1?所?代表?的?字?的?第?一位?相同?的?内存?中。 寻?址?方案?完全?由?从?设备?定义,?其?对?每?个?内存?区?的?解释?是?设备?数据?模型?的?重要?组成?部分。
该?规范?将?每?个?区块?定义?为?包含?多?达?65,536(216)?个?元素?的?地址?空间。 在?PDU?的?定义?中,?Modbus?定义?了?每?个?数据?元素?的?地址,?范围?从?0?到?65,535。?但是,?每?个?数据?元素?的?编号?从?1?到?n,?其中?n?的?最大值?为?65,536。?也就是说,?线圈?状态?1?位于?地址?0?的?线圈?状态?区块?中,?而?保持?寄存器?54?位于?从?机?被?定义?为?保持?寄存器?的?内存?部分?中的?地址?53。
规范?允许?的?全部?范围?不需要?给?定?设备?实现。 例如,?设备?可能?会?选择?不?执行?线圈、?离散?输入?或?输入?寄存器,?而?只?使用?保持?寄存器?150?至?175?和?200?至?225。?这?是?完全?可以?接受?的,?并且?通过?例外?来?处理?无效?的?访问?尝试。
虽然?规范?将?不同?的?数据?类型?定义?为?存在?于?不同?的?区块?中,?并?为?每?种?类型?分配?一个?本地?地址?范围,?但?这?并不?一定?会?转化?为?用于?记录?或?理解?给?定?设备?的?Modbus?可?访问?内存?的?直观?编?址?方案。 为了?简化?对?内存?区块?位置?的?理解,?引入?了?一种?编号?方案,?其?将?前?缀?添加?到?所?讨论?的?数据?的?地址?中。
例如,?设备?手册?不会?引用?地址?13?寄存器?14?的?数据?项,?而是?引用?地址?4,014,40,014?或?400,014?的?数据?项。?在?任何?情况?下,?第?一个?数字?都是?4,?表示?保持?寄存器,?剩余?数字?则?表示?指定?地址。 4XXX、?4XXXX?和?4XXXXX?的?区别?取决?于?设备?使用?的?地址?空间。 如果?所有?65,536?个?寄存器?都在?使用?中,?应该?使用?4XXXXX?符号,?因为?其?允许?范围?为?400,001~465,536。?如果?只?使用?几个?寄存器,?通常?的?做法?是?使用?范围?4,001?到?4,999。
在?这种?寻?址?方案?中,?每?种?数据?类型?都?被?分配?了?一个?前?缀,?如?表?2?所?示。
数据?区块 | 前缀 |
线圈?状态 | 0 |
离散?输入 | 1 |
输入?寄存器 | 3 |
保持?寄存器 | 4 |
表?2. 数据?范围?前缀
线圈?状态?存在?前?缀?为?0?的?情况。?这?意味?着?4001?的?引用?可能?指?的是?保持?寄存器?1?或?线圈?4001。?因此,?建议?所有?新?寻?址?方案?都?采用?带?前?导?零?的?6?位?寻?址,?并?在?文?档?中?进行?标?注。 因此,?保持?寄存器?1?的?地址?为?400,001,?而?线圈?4001?的?地址?则为?004,001。
内存?地址?和?参考?数字?之间?的?差异?会?由?给?定?应用?程序?选择?的?索引?进一步?复杂?化。 如?前?所述,?保存?寄存器?1?位于?地址?零。 通常,?参考?号码?是?1?索引,?这?意味?着?给?定?范围?的?起始?值?为?1。 因此,?400,001?就?表示?为?地址?0?的?保持?寄存器?00001。?一些?做法?选择?以?零?开始?其?范围,?这?意味?着?400,000?转换?为?地址?零?的?保持?寄存器。 表?3?展示?了?这个?概念。
地址 | 寄存器?编号 | 编号?1(1?索引,?标准) | 编号?(0?索引,?替换) |
0 | 1 | 400001 | 400000 |
1 | 2 | 400002 | 400001 |
2 | 3 | 400003 | 400002 |
表?3.寄存器?索引?方案
1?索引?范围?应用?较?为?广泛,?强烈?建议?采用。 无论?哪?种?情况,?每?个?范围?的?起始?值?都?应?在?文?档?中?注明。
Modbus?标准?提供?了?一个?相对?简单?的?数据?模型,?它?不?包含?无?符号?字?和?位?值?之外?的?其他?数据?类型。 如果?系统?的?位?值?对应?于?螺线?管?和?继电器,?并且?字?值?对应?于?未?缩?放?的?ADC?值,?这?是?足够?的,?但?对于?更?高级?的?系统?则?可能?不足。 因此,?许多?Modbus?实现?都?包含?跨?寄存器?边界?的?数据?类型。 NI LabVIEW?数据?记录?和?监?控?(DSC)?模块和KEPServerEX都?定义?了?许多?参考?类型。 例如,?存储?在?保持?寄存器?中的?字符?串?遵循?标准?格式?(400,001),?但?后?跟?一个?十进制?数、?长度?和?字符?串?的?字?节?顺序?(400,001.2H?是?指?保持?寄存器?1?中的?两?个?字符?串,?其中?高位?字?节?对应?到?字符?串?的?第?一个?字符)。 这?是?必需?的,?因为?每?个?请求?的?大小?都是?有限?的,?所以?Modbus?主机?必须?知道?字符?串?的?确切?范围,?而不是?像?NULL?那样?搜索?长度?或?分隔?符。
除了?允许?访问?跨?寄存器?边界?的?数据?之外,?一些?Modbus?主?设备?还?支持?对?寄存器?中?各个?位?的?引用。 这?是有?好处?的,?因为?它?允许?设备?将?相同?内存?范围?内的?每?种?类型?的?数据?组合?在一起,?而不?必将?二?进制?数据?分成?线圈?整体?和?离散?量?输入?范围。 这?通常?使用?小数点?和?位?索引?或?数字?进行?索引,?具体?取决?于?如何?实现。 也就是说,?第?一个?寄存器?的?第?一位?可能是?400,001.00?或?400,001.01。 建议?任何?文?档?都要?说明?所?使用?的?索引?方案。
多?寄存器?数据?(单?精度?浮点?值),?可以?通过?将?数据?拆?分?到?两?个?寄存器,?轻松?地?在?Modbus?中?传输。 由于?这?不是?由?标准?定义?的,?因此?分割?的?字?节?顺序?没有?规定。 尽管?每?个?无?符号?字?必须?以?网络?(big-?endian)?字?节?顺序?发送?以?满足?标准,?但?许多?设备?会?颠倒?多?字?节?数据?的?字?节?顺序。 图?2?所?示?的是?一个?不?常见?但?有效?的?例子。
图?2.多?字?数据?的?字?节?顺序?交换
请?务必?理解?设备?如何?将?信息?存储?在?内存?中?并?对?其?进行?正确?解码。 建议?文?档?写?明?系统?所?使用?的?字?顺序。 如果?需要?灵活?性,?也可以?将?Endian?添加?为?系统?配置?选项,?提供?基础?的?编码?和?解码?功能。
字符?串?可以?很?容易?地?存储?在?Modbus?寄存器?中。 为了?简单?起?见,?一些?方法?要求?字符?串?长度?为?2?的?倍数,?并?使用?控制?来?填充?额外?的?空间。 字?节?顺序?也是?字符?串?交互?中的?一个?变量。 字符?串?格式?可能?包含?也?可能?不?包含?NULL?作为?最终?值。 举?个?例子,?一些?设备?的?数据?存储?方法?可能?如?图?3?所?示。
图?3. Modbus?字符?串?中的?字?节?顺序?反转
与?数据?模型?可能?因?设备?而?异?不同,?功能?代码?及其?数据?由?标准?明确?定义。 每?个?功能?都?遵循?一种?模式。 首先,?从?设备?会?验证?功能?代码、?数据?地址?和?数据?范围?等?输入。 然后?执行?所?请求?的?操作?并?发送?与?代码?相符?的?响应。 如果?此?过程?中的?任何?步骤?失败,?则会?向?请求?程序?返回?异常。 这些?请求?的?数据?传输?就?称为?PDU。
PDU?由?一个?单字?节?的?功能?代码?组成,?后面?跟着?多?达?252?字?节?的?针对?特定?函数?的?数据。
功能?代码?是?第?一个?需要?验证?的?项。 如果?功能?代码?没有?被?接收?到?请求?的?设备?识别,?则会?回应?一个?异常。 如果?功能?代码?被?接受,?则?从?设备?根据?功能?定义?开始?分解?数据。
由于?数据?包?大小?限制?为?253?字?节,?设备?可?传输?的?数据?量?有限。 最?常见?的?功能?代码?可以?240?到?250?字?节?的?从?设备?数据?模型?数据,?具体?取决?于?代码。
不同?的?函数?由?数据?模型?定义?访问?不同?的?概念?数据?块。 一个?常见?的?做法?是?让?代码?访问?静态?内存?位置,?但?其他?行为?是?可用?的。 例如,?功能?代码?1(读?取?线圈?状态)?和?3(读?取?保持?寄存器)?可以?访问?内存?中?相同?的?物理?位置。 而?功能?代码?3(读?取?保持?寄存器)?和?16(写?入?保持?寄存器)?可以?访问?内存?中?完全?不同?的?位置。 因此,?建议?在?定义?从?数据?模型?时?同时?考虑?每?个?功能?代码?的?执行。
无论?执行?的是?何?种?实际?行为,?所有?的?从?设备?都应该?遵循?每?个?请求?的?简单?状态?流程?图。 图?5?是?代码?1?读?取?线圈?状态?的?一个?例子。
图?5.Modbus?协议?规范?定义的?读?取?线圈?状态?流程图
每?个?从?设备?必须?验证?功能?代码、?输入?数量、?起始?地址、?总?范围?以及?实际?进行?读?取?行为?的?从属?定义?函数?(slave-?defined function)?的?执行。
尽管?上面?的?状态?图?包含?了?静态?地址?范围,?但?真实?系统?的?需求?可能?会?使?静态?地址?范围?与?定义?的?数字?有所不同。 在?某些?情况?下,?从?设备?无法?传输?协议?定义?的?最大?字?节?数。 也就是说,?如果?主?设备?请求?0x07D0?输入,?从?设备?只能?用?0x0400?进行?响应。 如果?主?设备?从?地址?0?开始?请求?125,?则?这?是?正确?的,?但是?如果?主?设备?从?地址?400?开始?发出?相同?的?请求,?最后?一个?线圈?状态?将?位于?地址?525,?超出?了?该?设备?的?范围,?会?导致?出现?状态?图?定义?的?异常?02。
每?个?标准?功能?代码?的?定义?都?包含?在?说明?书?中。 即使?对于?最?常见?的?功能?代码,?在?主?设备?上?启用?的?功能?与?从?设备?可以?处理?的?功能?之间?也?存在?不可避免?的?不?匹配。 为了?解决?这个?问题,?Modbus TCP?规范?的?早期?版本?定义?了三?个?一致性?类。 官方的Modbus?一致性?测试?规范没有?引用?这些?类,?而是?在?每?个?功能?的?基础?上?定义?一致性;?但是,?这些?仍然?很?容易?理解。 建议?任何?文?档?都?遵循?测试?规范,?并?根据?其?支持?的?代码?而不是?传统?分类?来?定义?它们?的?一致性。
0?类?代码?通常?被?认为?是?有用?Modbus?设备?的?最低?配置,?因为?它们?使?主?设备?能够?读?取?或?写?入?数据?模型。
代码 | 说明 |
3 | 读?多?寄存器 |
16 | 写?多?寄存器 |
表?4.0?类?一致性?代码
1?类?功能?代码?由?访问?所有?类型?的?数据?模型?所需?的?其他?代码?组成。 在?原始?定义?中,?这个?列表?包含?功能?代码?7(读?取?异常)。 但是,?此?代码?由?当前?规范?定义?为?仅?限于?串?行?的?代码。
代码 | 说明 |
1 | 读?线圈 |
2 | 读?离散?输入 |
4 | 读?输入?寄存器 |
5 | 写?单?线圈 |
6 | 写?单?寄存器 |
7 | 读?取?异常?状态?(仅?限?串?行) |
表?5. 1?类?一致性?代码
2?类?功能?代码?用于?更?为?专业?化?的?功能,?不太?常用。 例如,?读/?写?多个?寄存器?可能?有助?于?减少?请求/?响应?周期?的?总数,?但?该?行为?仍?可以?用?0?类?代码?实现。
代码 | 说明 |
15 | 写?多?线圈 |
20 | 读?文件?记录 |
21 | 写?文件?记录 |
22 | 屏蔽?写?寄存器 |
23 | 读/?写?多?寄存器 |
24 | 读?取?FIFO |
表?6. 2?类?一致性?代码
Modbus?封?装?接口?(MEI)?代码?功能?43?用于?封?装?Modbus?数据?包?内的?其他?数据。 目前,?有?两?个?MEI?号码?可用,?13(CANopen)?和?14(设备?识别)。
功能?43/14(设备?识别)?非常?有用,?因为?它?允许?传送?多?达?256?个?唯一?的?对象。 其中?一些?对象?已?预?定义?且?预?留?好,?例如?供应?商?名称?和?产品?代码,?但?应用?程序?可以?将?其他?对象?定义?为?通用?数据?集。
此?代码?并不?常用。
从?设备?使用?异常?来?指示?各种?不良?状况,?比如?错误?请求?或?不?正确?输入。 但是,?异常?也可以?作为?对?无效?请求?的?应用?程序?级?响应。 从?设备?不?响应?发出?异常?的?请求。 相反,?从?设备?忽略?不?完整?或?损坏?的?请求,?并?开始?等待?新的?消息?传?入。
异常?以?定义?好的?数据?包?格式?报告?给?用户。 首先?将?一个?功能?代码?返回?给?等?同?于?与?原始?功能?代码?的?请求?主?设备,?除了?设置?了?最高?有效?位。 这?等?同?于?为?原始?功能?代码?的?值?加上?0x80。 异常?响应?包括?一个?异常?代码?来?代替?与?给?定?函数?响应?相关?的?正常?数据。
在?标准?内,?四?种?最?常见?的?异常?代码?是?01,02,03?和?04。?表?7?介绍?了?这些?代码?以及?每?种?功能?的?标准?含义。
异常?代码 | 含义 |
01 | 不?支持?接收?到?功能?代码。 要?确认?原始?功能?代码,?请?从?返回?值?中?减去?0x80。 |
02 | 尝试?访问?的?请求?是?一个?无效?地址。 在?标准?中,?只有?起始?地址?和?请求?的?数值?超过216时?才?会?发生?这种?情况。 但是,?有些?设备?可能?会?限制?其?数据?模型?中的?地址?空间。 |
03 | 请求?包含?不?正确?的?数据。 在?某些?情况?下,?这?意味?着?参数?不?匹配,?例如?发送?的?寄存器?的?数量?与“字?节?数”字?段?之间?的?参数?不?匹配。 更?常见?的?情况?是,?主机?请求?的?数据?比?从?机?或?协议?允许?的?要?多。 例如,?主?设备?一次?只能?读?取?125?个?保持?寄存器,?而?资源?受限?的?设备?可能?会?将?此?值?限制?为?更少?的?寄存器。 例如,?主?设备?一次?只能?读?取?125?个?保持?寄存器,?而?资源?受限?的?设备?可能?会?将?此?值?限制?为?更少?的?寄存器。 |
04 | 尝试?处理?请求?时?发生?不可?恢复?的?错误。 这?是?一个?异常?的?代码,?表示?请求?有效,?但从?设备?无法?执行?该?请求。 |
表?7.常见?的?Modbus?异常?代码
每?个?功能?代码?的?状态?图?至少?应?包含?异常?代码?01,?通常?包含?异常?代码?04,02,03,?并且?任何?其他?定义?的?异常?代码?都是?可?选?的。
除了?Modbus?协议?的?PDU?核心?定义?的?功能?外,?您?还?可以?使用?多种?网络?协议。 最?常见?的?协议?是?串?行?和?TCP/?IP,?但?也可以?使用?其他?协议,?如?UDP。 为了?在?这些?层?之间?传输?Modbus?所需?的?数据,?Modbus?包含?一?组?适用?于?每?种?网络?协议?的?ADU。
Modbus?需要?某些?功能?来?提供?可靠?的?通信。 单元?ID?或?地址?用?在?每?个?ADU?格式?中,?为?应用?层?提供?路?由?信息。 每?个?ADU?都?带有?一个?完整?的?PDU,?其中?包含?给?定?请求?的?功能?代码?和?相关?数据。 为了?可靠性,?每?条?消息?都?包含?错误?检查?信息。 最后,?所有?的?ADU?都?提供?了?一种?机制?来?确定?请求?帧?的?开始?和?结束,?但?实现?这些?机制?的?方式?各不相同。
ADU?的?三?种?标准?格式?是?TCP、?远程?终端?单元?(RTU)?和?ASCII。 RTU?和?ASCII ADU?通常?用于?串?行?线路,?而?TCP?则?用于?现代?TCP/?IP?或?UDP/?IP?网络。
TCP ADU?由?Modbus?应用?协议?(MBAP)?报?文?头?和?Modbus PDU?组成。 MBAP?是?一个?通用?的?报?文?头,?依赖?于?可靠?的?网络?层。 此?ADU?的?格式?(包括?报?文?头)?如?图?6?所?示。
报?文?头?的?数据?字?段?代表?其?用途。 首先,?它?包含?一个?事务?处理?标识?符。 这?有助?于?网络?允许?同时?发生?多个?未?处理?的?请求。 也就是说,?主?设备?可以?发送?请求?1、?2?和?3。?在?稍?后?的?时间?点,?从?设备?可以?以?2、?1、?3?的?顺序?进行?响应,?并且?主?设备?可以?将?请求?匹配?到?响应?并?准确?解析?数据。 这?对?以太?网?网络?很有?用。
协议?标识?符?通常?为?零,?但?您?可以?使用?它?来?扩展?协议?的?行为。 协议?使用?长度?字?段?来?描述?数据?包?其余?部分?的?长度。 这个?元素?的?位置?也?表明?了?这个?报?文?头?格式?在?可靠?的?网络?层?上?的?依赖?关系。 由于?TCP?数据?包?具有?内?置?的?错误?检查?功能,?可?确保?数据?一致性?和?传送,?因此?数据?包?长度?可?位于?报?文?头?的?任何?位置。 在?可靠性?较?差?的?网络?上?(比如?串?行?网络),?数据?包?可能?会?丢失,?其?影响?是?即使?应用?程序?读?取?的?数据?流?包含?有效?的?事务?处理?和?协议?信息,?长度?信息?的?损坏?也?会?使?报?文?头?无效。 TCP?为?这种?情况?提供?了?适当的?保护。
TCP/?IP?设备?通常?不?适用?单元?ID。 但是,?Modbus?是?一种?常见?的?协议,?因此?通常?会?开发?一些?网?关?来?将?Modbus?协议?转换?为?另?一种?协议。 在?最初?的?预期?应用?中, Modbus TCP/?IP?转?串?行?网?关?用于?连接?新的?TCP/?IP?网络?和?旧?的?串?行?网络。 这时,?单元?ID?用于?确定?PDU?对应?的?从?设备?的?地址。
最后,?ADU?包含?一个?PDU。 对于?标准?协议,?PDU?的?长度?仍?限制?为?253?字?节。
RTU ADU?看起来?要?简单?得?多,?如?图?7?所?示。
与?较?为?复杂?的?TCP/?IP ADU?不同?的是,?除了?核心?PDU?之外,?该?ADU?仅?包含?两?条?信息。 首先,?地址?用于?定义?PDU?对应?的?从?设备。 在?大?多数?网络?中,?地址?0?定义?的是“广播”地址。 也就是说,?主?设备?可以?发送?输出?命令?到?地址?0,?而?所有?从?设备?应?处理?该?请求,?但是?不?做出?任何?响应。 除了?这个?地址?外,?CRC?还?用于?确保?数据?的?完整性。
然而,?现在?的?实现?机制?远?没有?那么?简单。 数据?包?的?首尾?一对?沉默?时间?(silent time),?即?总?线上?没有?通信?的?时?段。?对于?9,600?的?波特?率,?这个?速率?大约是?4ms。?该?标准?定义?了?一个?最小?沉默?长度,?不论?波特?率?如何,?都?低于?2 ms。
首先,?这?存在?性能?缺陷,?因为?在?处理?数据?包?之前?设备?必须?等待?空闲?时间?结束。 然而,?更?危险?的是?串?行?传输?引入?了?不同?技术,?并且?波特?率?比?标准?更?快。 例如,?使用?USB/?串?口?转换?器?电缆,?您?无法?控制?数据?的?数据?包?和?数据?传输。 测试?表明,?结合?NI-?VISA?驱动?程序?使用?USB?转?串?口?电缆?会?在?数据?流?中?引入?了?尺寸?可变?的?大?间隙,?而?这些?间隙 – 沉默?期 – 会“诱?骗”符合?规范?的?代码?相信?消息?是?完整?的。 由于?消息?不?完整,?通常?会?导致?CRC?无效,?并?导致?设备?将?ADU?解释?为?损坏。
除了?传输?问题?之外,?现代?驱动?程序?技术?还?大量?提取?串?行?通信,?并且?通常?需要?应用?程序?代码?中的?轮?询?机制。 例如,?除非?通过?轮?询?端?口上?的?字?节,.NET Framework 4.5 SerialPort Class和?NI-?VISA?驱动?程序?都不?提供?检测?串?行?线路?上?的?沉默?的?机制。 这?会?导致?性能?降低?(如果?轮?询?执行?过?慢)?或?CPU?使用?率?过?高?(如果?轮?询?执行?过?快)。
解决?这些?问题?的?常用?方法?是?打破?Modbus PDU?和?网络?层?之间?的?抽象?层。 也就是说,?串?行?代码?询问?Modbus PDU?数据?包?以?确定?功能?代码。 结合?数据?包?中的?其他?数据,?可以?发现?剩余?数据?包?的?长度,?从而?确定?数据?包?的?结尾。 利用?这些?信息,?可以?使用?更?长?的?超?时?时间,?以?允许?传输?间隙,?并且?应用?程序?级?的?轮?询?速度?可能?更慢。 这种?机制?推荐?用于?新的?开发。 不?采用?此?方法?可能?会?遇到?大于?预期?数量?的“损坏”数据?包。
如?图?8?所?示,?ASCII ADU?比?RTU?更?复杂,?但?也?避免?了?RTU?数据?包?的?许多?问题。 然而,?它?自身?也有?一些?缺点。
为了?解决?确定?数据?包?大小?的?问题,?ASCII ADU?为?每?个?数据?包?定义?了?一个?明确?且?唯一?的?开始?和?结束。 也就是说,?每?个?数据?包?以“:”开始 并?以?回车?(CR)?和?换?行?符?(LF)?结束。 另外,?像?NI-?VISA?和.NET Framework SerialPort Class?这样?的?串?行?API?可以?轻松?读?取?缓冲?区?中的?数据,?直到?收到?特定?字符?的?CR/?LF?为止。 这些?特性?有助?于?在?现代?应用?程序?代码?中?有效?地?处理?串?行?线路?上?的?数据?流。
ASCII ADU?的?缺点?是?所有?数据?都?以?ASCII?编码?的?十六?进制?字符?进行?传输。 也就是说,?针对?功能?代码?3(0x03)?发送?的?不是?单?个?字?节,?而是?发送?ASCII?字符“0”和“3”或?0x30/0x33。 这?使?协议?更?具?可读?性,?但?也?意味?着?必须?通过?串?行?网络?传输?两?倍?的?数据,?并且?发送?和?接收?应用?程序?必须?能够?解析?ASCII?值。
Modbus?是?一种?相对?简单?和?开放?的?标准,?可以?进行?修改?以?适应?给?定?应用?的?需求。 这?常用?于?HMI?和?PLC?或?PAC?之间?的?通信,?因为?在?这种?情况?下?组织?可以?控制?协议?的?首尾。 例如,?传感器?的?开发?人员?更?可能?遵守?书面?标准,?因为?他们?通常?只?控制?其?从?设备?的?实现,?互通性?也是?可能?实现?的。
一般?来说,?不?建议?修改?协议。 本?节?仅?作为?对?其他?人?用?来?调整?协议?行为?的?机制?的?确认。
Modbus?标准?定义?了?一些?功能?代码,?但?也?可?允许?您?开发?更多?的?功能?代码。 具体?而言,?功能?代码?1?至?64,73?至?99?以及?111?至?127?是?预?留?的?并?保证?唯一?的?公共?代码。 其余?代码?65?至?72?和?100?至?110?可?由?用户?自?定义。 使用?这些?用户?定义?的?代码?时,?您?可以?使用?任何?数据?结构。 数据?甚至?可能?超过?Modbus PDU?的?标准?253?字?节?限制,?但?应?验证?整个?应用?程序?以?确保?其他?层?在?PDU?超过?标准?限制?时?按?预期?工作。 高于?127?的?功能?代码?预?留作?异常?响应。
除了?串?行?和?TCP?之外,?Modbus?还?可以?在?许多?网络?层?上?运行。 一个可能的?实现?是?UDP,?因为?它?适合?于?Modbus?通信?风格。 Modbus?本质?上?是?基于?消息?的?协议,?因此?UDP?能够?发送?明确?定义?的?信息?包,?而?不需要?任何?额外?的?应用?程序?级?信息,?如?起始?字符?或?长度,?这?使得?Modbus?非常?易?于?实现。 Modbus PDU?数据?包?可以?使用?标准?的?UDP API?发送,?不需要?额外?的?ADU?或?重新?使用?现有?的?ADU,?并?由?另一?端?完全?接收。 虽然?由于?其?内?置?确认?系统,?TCP?对?某些?协议?有利,?但?Modbus?是在?应用?层?执行?确认。 因此,?以?这种?方式?使用?UDP?会?消除?TCP ADU?中的?事务?处理?标识?符?字?段,?从而?消除?了?存在?多个?同时?发生?的?未完成?事务?的?可能性。 因此,?主?设备?必须?是?同步?主?设备,?或者?UDP?数据?包?必须?有?一个?标识?符?以?帮助?主?设备?组织?请求?和?响应。 建议?的?做法?是在?UDP?网络?层?上?使用?TCP/?IP ADU。
最后,?应用?程序?可以?选择?修改?ADU,?或?使用?现有?ADU?的?未?使用?部分?(如?TCP)。 例如,?TCP?定义?了?一个?16?位?长度?字?段、?一个?16?位?协议?和?一个?8?位?单元?ID。?鉴于?最大?的?Modbus PDU?是?253?字?节,?长度?字?段?的?高?字?节?始终?为?零。 对于?Modbus/?TCP,?协议?字?段?和?单元?ID?始终?为?零。 协议?的?简单?扩展?可以?通过?将?协议?字?段?更改?为非?零?数字?并?使用?两?个?未?使用?的?字?节?(单元?ID?和?长度?字?段?的?高?字?节)?来?发送?两?个?附加?PDU?的?长度,?从而?同时?发送?三?个?数据?包?(请?参阅?图?9)。
原文:https://www.cnblogs.com/CodeWorkerLiMing/p/11333232.html