Modbus 网络通讯协议
2014-05-15 16:35
260 查看
开发人员编码注意:
在使用Modbus通讯协议,一定要编写Modbus通讯协议和CRC校验。
(在远距离数据通信中,为确保高效而无差错地传送数据,防止数据被破坏或者篡改,必须对数据进行CRC校验。
尽管CRC在错误检测中非常有用,但CRC并不能可靠地校验数据完整性,这是因为CRC多项式是线性结构,可以非常容易地通过改变数据方式达到CRC碰撞,这里给一个更加通俗的解释,假设一串带有CRC校验的代码在传输中,如果连续出现差错,当出错次数达到一定次数时,那么几乎可以肯定会出现一次碰撞(值不对但CRC结果正确),但随着CRC数据位增加,碰撞几率会显著降低,比如CRC32比CRC16具有更可靠的验证性,CRC64又会比CRC32更可靠,当然这都是按照ITU规范标准条件下。)
如果你发送指定的指令,其中的CRC校验直接使用提供的CRC低位字节表和CRC高位字节表中的字节数据,那就不需要编写CRC校验。
如今在工业现场总线中,常采用串口实现一些要求不太高的通讯控制,modbus协议更是最常用的传输数据的协议,而在整个通讯过程中,CRC校验码计算是一个注意点。
Moldbus没有规定物理层用什么接口实现。只要半双工以上就可以。所以232口没问题。 如果你的PLC用的是Modbus,那你一定要实现 CRC校验。否则接收端如果收不到 CRC校验包或者 CRC校验包不对,就会认为收到的数据包错误,不做任何响应。
modbus通信协议是应用层协议(第七层),它目前可以用于3种通信网络:
1)用于串行口通信网络,传输模式为modbusRTU和modbusASCII;
2)用于以太网口通信网络,传输模式为modbusTCP;
3)用于高速链路网络,传输模式为modbusPLUS。 包括modbus协议在内,有很多种========================通信协议都可以用于现场总线。modbusPLUS就是一种现场总线,而modbusRTU/ASCII、modbusTCP只是低速的普通通信网络。
通讯传送分为独立的信息头,和发送的编码数据
编码8位二进制 起始位1位 数据位8位 奇偶校验位1位(偶校验位) 停止位1位 错误校检CRC(冗余循环码) 初始结构=≥4字节的时间
(传送的数据帧结构组成如下)
地址码=1字节
功能码=1字节
数据区=N字节
错误校检=16位CRC码
结束结构=≥4字节的时间
地址码:地址码为通讯传送的第一个字节。这个字节表明由用户设定地址码的从机将接收由主机发送来的信息。并且每个从机都有具有唯一的地址码,并且响应回送均以各自的地址码开始。主机发送的地址码表明将发送到的从机地址,而从机发送的地址码表明回送的从机地址。地址码在温湿度传感器上电启动后,可以显示屏上看得到,且读取地址码发送的命令中必须跟该地址码一致。否则接收过来的响应会是错误的信号。
功能码:通讯传送的第二个字节。ModBus通讯规约定义功能号为1到127。本仪表只利用其中的一部分功能码。作为主机请求发送,通过功能码告诉从机执行什么动作。作为从机响应,从机发送的功能码与从主机发送来的功能码一样,并表明从机已响应主机进行操作。如果从机发送的功能码的最高位为1(比如功能码大与此同时127),则表明从机没有响应操作或发送出错。
数据区:数据区是根据不同的功能码而不同。数据区可以是实际数值、设置点、主机发送给从机或从机发送给主机的地址。
CRC码:二字节的错误检测码。
传输格式
(1)命令报文格式
读数据:
地址 | 功能码 | 数据起始地址高位 | 数据起始地址低位 | 数据个数高位 | 数据个数低位 | CRC 16位校验 |
xx | 04 | 00 | 00 | 00 | 02 | xxxx低位在前 |
地址 | 功能码 | 字节长度 | 数据1输入 | 数据2输入 | … | CRC 16位校验 |
xx | 04 | 04 | xx高位在前 | xx高位在前 | xx | xxxx低位在前 |
非法功能:
从站地址 | 功能码 | 异常码 | CRC16校验 |
xx | 80H+原功能码 | 01 | xxxx低位在前 |
从站地址 | 功能码 | 异常码 | CRC16校验 |
xx | 80H+原功能码 | 02 | xxxx低位在前 |
从站地址 | 功能码 | 异常码 | CRC16校验 |
xx | 80H+原功能码 | 03 | xxxx低位在前 |
命令报文格式:
命令代码高位 | 命令代码地位 | 地址数据 | CRC 16位校验 |
FF | A5 | xx | xxxx低位在前 |
命令代码高位 | 命令代码地位 | 地址数据 | CRC 16位校验 |
FF | A5 | xx | xxxx低位在前 |
//*pushMsg为需要校验的数组指针变量,usDataLen为需要校验的数据个数变量
voidCRC16(BYTE*pushMsg,unsignedshortusDataLen) { BYTEuchCRCHi=0xFF; BYTEuchCRCLo=0xFF; unsignedintuIndex; while(usDataLen--) { uIndex=uchCRCHi^*pushMsg++; //计算CRC uchCRCHi=uchCRCLo^auchCRCHi[uIndex]; uchCRCLo=auchCRCLo[uIndex]; } *pushMsg++=uchCRCHi; //校验数据高位在后 *pushMsg=uchCRCLo; //校验数据低位在前 }
地址为1时,读取温湿度值:(CRC校验低位在前)
上位机发送:01030002000265CB(读从数据起始地址为0000H开始的1个模拟量)
变送器返回:01030400B401EA3BBD
即显示屏上显示的温湿度数据:
T:17.9
H:49.0
读取地址码值(即获取设备的型号ID):(CRC校验低位在前)
上位机发送:00030000000185DB(读从数据起始地址为0000H开始的1个模拟量)
变送器返回:00030200,地址L,CRC_L,CRC_H
从机返回的温湿度数据分别用两个字节表示,高位在前,低位在后;
返回的数据范围-32768~32767,实际温湿度数据需要将返回值除以10;
例如:
返回湿度16进制数据:0x0311,对应10进制785,表示湿度为78.5%RH
返回温度16进制数据:0x00FF,对应10进制255,表示温度为25.5℃
返回温度16进制数据:0x8064,最高位为1表示附属对应10进制785,表示湿度为78.5%RH
为变送器设置新地址码,如“2”:(CRC校验低位在前)
上位机发送:FFA502BB61
变送器返回:FFA502BB61
如设置新地址码“6”:(CRC校验低位在前)
上位机发送:FFA506BAA2
变送器返回:FFA506BAA2
(若需要同时与多台设备Modbus协议通讯时,也可以自己去设置地址码)
Modbus网络通信其实就是二进制从做到右传输.一般来说,标准MODBUS是:1:串行通信, 物理层和RS232/485等都是一样的,
========================
Modbus协议是应用于电子控制器上的一种通用语言。通过此协议,控制器相互之间、控制器经由网络(例如以太网)和其它设备之间可以通信。它已经成为一通用工业标准。有了它,不同厂商生产的控制设备可以连成工业网络,进行集中监控。此协议定义了一个控制器能认识使用的消息结构,而不管它们是经过何种网络进行通信的。它描述了一控制器请求访问其它设备的过程,如果回应来自其它设备的请求,以及怎样侦测错误并记录。它制定了消息域格局和内容的公共格式。 当在一Modbus网络上通信时,此协议决定了每个控制器须要知道它们的设备地址,识别按地址发来的消息,决定要产生何种行动。如果需要回应,控制器将生成反馈信息并用Modbus协议发出。在其它网络上,包含了Modbus协议的消息转换为在此网络上使用的帧或包结构。这种转换也扩展了根据具体的网络解决节地址、路由路径及错误检测的方法。 1、在Modbus网络上转输 标准的Modbus口是使用一RS-232C兼容串行接口,它定义了连接口的针脚、电缆、信号位、传输波特率、奇偶校验。控制器能直接或经由Modem组网。 控制器通信使用主—从技术,即仅一设备(主设备)能初始化传输(查询)。其它设备(从设备)根据主设备查询提供的数据作出相应反应。典型的主设备:主机和可编程仪表。典型的从设备:可编程控制器。
Modbus支持的功能码:
下表是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/384484584)
可使主机模拟编程器功能修改PC从机逻辑
14
探询(184/384484584)
可使主机与正在执行任务的从机通信,定期控询该从机是否已完成其程序操作,仅在含有功能13的报文发送后,本功能码才得发送
15
强置多线圈
强置一串连续逻辑线圈的通断
16
预置多寄存器
把具体的二进制值装入一串连续的保持寄存器
17
报告从机标识
可使主机判断编址从机的类型及该从机运行指示灯的状态
18
(884和MICRO84)
可使主机模拟编程功能,修改PC状态逻辑
19
重置通信链路
发生非可修改错误后,是从机复位于已知状态,可重置顺序字节
20
读取通用参数(584L)
显示扩展存储器文件中的数据信息
21
写入通用参数(584L)
把通用参数写入扩展存储文件,或修改之
22~64
保留作扩展功能备用
65~72
保留以备用户功能所用
留作用户功能的扩展编码
73~119
非法功能
120~127
保留
留作内部作用
128~255
保留
用于异常应答
在这些功能码中较长使用的是1、2、3、4、5、6号功能码,使用它们即可实现对下位机的数字量和模拟量的读写操作。
1、读可读写数字量寄存器(线圈状态):
计算机发送命令:[设备地址][命令号01][起始寄存器地址高8位][低8位][读取的寄存器数高8位][低8位][CRC校验的低8位][CRC校验的高8位]
例:[11][01][00][13][00][25][CRC低][CRC高]
意义如下:
<1>设备地址:在一个485总线上可以挂接多个设备,此处的设备地址表示想和哪一个设备通讯。例子中为想和17号(十进制的17是十六进制的11)通讯。
<2>命令号01:读取数字量的命令号固定为01。
<3>起始地址高8位、低8位:表示想读取的开关量的起始地址(起始地址为0)。比如例子中的起始地址为19。
<4>寄存器数高8位、低8位:表示从起始地址开始读多少个开关量。例子中为37个开关量。
<5>CRC校验:是从开头一直校验到此之前。在此协议的最后再作介绍。此处需要注意,CRC校验在命令中的高低字节的顺序和其他的相反。
设备响应:[设备地址][命令号01][返回的字节个数][数据1][数据2]...[数据n][CRC校验的低8位][CRC校验的高8位]
例:[11][01][05][CD][6B][B2][0E][1B][CRC低][CRC高]
意义如下:
<1>设备地址和命令号和上面的相同。
<2>返回的字节个数:表示数据的字节个数,也就是数据1,2...n中的n的值。
<3>数据1...n:由于每一个数据是一个8位的数,所以每一个数据表示8个开关量的值,每一位为0表示对应的开关断开,为1表示闭合。比如例子中,表示20号(索引号为19)开关闭合,21号断开,22闭合,23闭合,24断开,25断开,26闭合,27闭合...如果询问的开关量不是8的整倍数,那么最后一个字节的高位部分无意义,置为0。
<4>CRC校验同上。
2、读只可读数字量寄存器(输入状态):
和读取线圈状态类似,只是第二个字节的命令号不再是1而是2。
3、写数字量(线圈状态):
计算机发送命令:[设备地址][命令号05][需下置的寄存器地址高8位][低8位][下置的数据高8位][低8位][CRC校验的低8位][CRC校验的高8位]
例:[11][05][00][AC][FF][00][CRC低][CRC高]
意义如下:
<1>设备地址和上面的相同。
<2>命令号:写数字量的命令号固定为05。
<3>需下置的寄存器地址高8位,低8位:表明了需要下置的开关的地址。
<4>下置的数据高8位,低8位:表明需要下置的开关量的状态。例子中为把该开关闭合。注意,此处只可以是[FF][00]表示闭合[00][00]表示断开,其他数值非法。
<5>注意此命令一条只能下置一个开关量的状态。
设备响应:如果成功把计算机发送的命令原样返回,否则不响应。
4、读可读写模拟量寄存器(保持寄存器):
计算机发送命令:[设备地址][命令号03][起始寄存器地址高8位][低8位][读取的寄存器数高8位][低8位][CRC校验的低8位][CRC校验的高8位]
例:[11][03][00][6B][00][03][CRC低][CRC高]
意义如下:
<1>设备地址和上面的相同。
<2>命令号:读模拟量的命令号固定为03。
<3>起始地址高8位、低8位:表示想读取的模拟量的起始地址(起始地址为0)。比如例子中的起始地址为107。
<4>寄存器数高8位、低8位:表示从起始地址开始读多少个模拟量。例子中为3个模拟量。注意,在返回的信息中一个模拟量需要返回两个字节。
设备响应:[设备地址][命令号03][返回的字节个数][数据1][数据2]...[数据n][CRC校验的低8位][CRC校验的高8位]
例:[11][03][06][02][2B][00][00][00][64][CRC低][CRC高]
意义如下:
<1>设备地址和命令号和上面的相同。
<2>返回的字节个数:表示数据的字节个数,也就是数据1,2...n中的n的值。例子中返回了3个模拟量的数据,因为一个模拟量需要2个字节所以共6个字节。
<3>数据1...n:其中[数据1][数据2]分别是第1个模拟量的高8位和低8位,[数据3][数据4]是第2个模拟量的高8位和低8位,以此类推。例子中返回的值分别是555,0,100。
<4>CRC校验同上。
5、读只可读模拟量寄存器(输入寄存器):
和读取保存寄存器类似,只是第二个字节的命令号不再是2而是4。
6、写单个模拟量寄存器(保持寄存器):
计算机发送命令:[设备地址][命令号06][需下置的寄存器地址高8位][低8位][下置的数据高8位][低8位][CRC校验的低8位][CRC校验的高8位]
例:[11][06][00][01][00][03][CRC低][CRC高]
意义如下:
<1>设备地址和上面的相同。
<2>命令号:写模拟量的命令号固定为06。
<3>需下置的寄存器地址高8位,低8位:表明了需要下置的模拟量寄存器的地址。
<4>下置的数据高8位,低8位:表明需要下置的模拟量数据。比如例子中就把1号寄存器的值设为3。
<5>注意此命令一条只能下置一个模拟量的状态。
设备响应:如果成功把计算机发送的命令原样返回,否则不响应。
相关文章推荐
- Modbus 通讯协议
- 国内部分软件网络通讯协议分析(含特征码)
- 网络编程(8)自定义网络通讯协议
- Modbus 通讯协议
- 免费下载软件--网络通讯协议图屏保
- 网络通讯和网络协议
- EtherCAT 实时以太网络通讯协议
- 如何通过序列化在网络间传递对象,网络协议:轻松定义自己的网络通讯协议
- 网络通讯,网络协议控件,SSH 安全组件,MIME加密组件,数字证书
- 网络通讯更自由 谈Java串行端口技术协议
- 我的IM - 基础篇[3] - 基于UDP通讯的IM设计[基于XML格式的网络通讯协议 以及 包解析器和包处理器的基础概念]
- 网络通讯协议定义语言及代理代码生成器
- OSI和TCP/IP模型之间的区别-----无线网络通讯协议有哪些
- 第9将 网络编程-怎样理解应用程序协议和网络通讯协议的关系
- modbus工业网络协议(转)
- 轻松定义自己的网络通讯协议
- 联营网络通讯协议指南
- 自定义网络通讯协议 socket通讯时都是走字符序列,注意字符串长度
- TCP/IP 中文译名为传输控制协议/因特网互联协议,又叫网络通讯协议