简介:
Modbus是一种串行通信协议,是Modicon公司(现在的施耐德电气 Schneider Electric)于1979年为使用可编程逻辑控制器(PLC)通信而发表。Modbus已经成为工业领域通信协议的业界标准(De facto),并且现在是工业电子设备之间常用的连接方式。
Modbus协议是一个master/slave架构的协议。有一个节点是master节点,其他使用Modbus协议参与通信的节点是slave节点。每一个slave设备都有一个唯一的地址。在串行和MB+网络中,只有被指定为主节点的节点可以启动一个命令(在以太网上,任何一个设备都能发送一个Modbus命令,但是通常也只有一个主节点设备启动指令)。
一个ModBus命令包含了打算执行的设备的Modbus地址。所有设备都会收到命令,但只有指定位置的设备会执行及回应指令(地址0例外,指定地址0的指令是广播指令,所有收到指令的设备都会运行,不过不回应指令)。所有的Modbus命令包含了检查码,以确定到达的命令没有被破坏。基本的ModBus命令能指令一个RTU改变它的寄存器的某个值,控制或者读取一个I/O端口,以及指挥设备回送一个或者多个其寄存器中的数据。
工作方式:
Modbus的工作方式是请求/应答,每次通讯都是主站先发送指令,可以是广播,或是向特定从站的单播;从站响应指令,并按要求应答,或者报告异常。当主站不发送请求时,从站不会自己发出数据,从站和从站之间不能直接通讯。
Modbus协议是应用层(协议层)报文传输协议,它定义了一个与物理层无关的协议数据单元(PDU)
即PDU=功能码+数据域,功能码1byte,数据域不确定。
Modbus协议能够应用在不同类型的总线或网络。对应不同的总线或网络,Modbus协议引入一些附加域映射成应用数据单元(ADU),即ADU=附加域+PDU,例如modbus tcp/ip------ ADU=MBAP+ADU。
查询—回应
(1)、查询
查询消息中的功能代码告之被选中的从设备要执行何种功能。数据段包含了从设备要执行功能的任何附加信息。例如功能代码03是要求从设备读保持寄存器并返回它们的内容。数据段必须包含要告之从设备的信息:从何寄存器开始读及要读的寄存器数量。错误检测域为从设备提供了一种验证消息内容是否正确的方法。
(2)、回应
如果从设备产生正常的回应,在回应消息中的功能代码是在查询消息中的功能代码的回应。数据段包括了从设备收集的数据:象寄存器值或状态。如果有错误发生,功能代码将被修改以用于指出回应消息是错误的,同时数据段包含了描述此错误信息的代码。错误检测域允许主设备确认消息内容是否可用。
Modbus RTU通常具有优良的通讯能力和更大的存储容量,适用于更恶劣的温度和湿度环境,提供更多的计算功能。广泛应用于智慧水利、智慧环保、工业物联网、智慧市政等,如:水文远程监控、水资源远程监测、水源井远程监控、山洪灾害监测、地质灾害监测、河道监测预警、气象监测、泵站远程监控、污染源远程监控等远程测控领域。
modbus共有三种模式,分别是:RTU模式,ASCII模式和TCP模式。
从机都有相应的地址码,便于主机识别,从机地址为0到255,0为广播地址,248-255保留。总线上只能有一个主设备,但可以有一个或者多个(最多247个 ip地址1-247)从设备。
数据以帧为单位进行数据传输,每帧最长为252字节,最短为0。
帧校验:CRC循环冗余校验,检验整个报文内容
起始 | 地址码 | 功能码 | 数据 | 校验 | 回车换行 |
---|---|---|---|---|---|
字符 ‘:’(冒号) | 两字节 | 两字节 | 0到2 * 252字节 | 两字节(LRC校验) | 两字节(CR,LF) |
MODBUS TCP/IP通信结构:
串行链路上一个主站多个从站的模式演变为多个客户机和多个服务器的模式,IANA(Internet Assigned NumbersAuthority,互联网编号分配管理机构)给Modbus协议赋予TCP端口号为502,Modbus TCP/IP 服务器端通常该端口作为接收报文的端口, 这是目前在仪表与自动化行业中唯一分配到的端口号。
Modbus TCP的数据帧可分为两部分:MBAP+PDU(简单协议数据单元)。
主站为client端,主动建立连接;从站为server端,等待连接。
MBAP报文头包括下列域:
域 | 长度 | 描述 | 客户机 | 服务器 |
---|---|---|---|---|
事务元标识符 | 2个字节 | MODBUS请求/响应事务处理的识别码 | 客户机启动 | 服务器从接收的请求中重新复制 |
协议标识符 | 2个字节 | MODBUS协议 | 客户机启动 | 服务器从接收的请求中重新复制 |
长度字段 | 2个字节 | 以下字节的数量 | 客户机启动(请求) | 服务器(响应)启动 |
单元标识符 | 1个字节 | 串行链路或其它总线上连接的远程从站的识别码 | 客户机启动 | 服务器从接收的请求中重新复 |
PDU(简单协议数据单元)
功能码+数据段
MODBUS PLUS,一种高速令牌传递网络,MODBUS PLUS 链路层采用的是HDLC。
MB+网的特点
MB+网是ModBusPlus网络的简称,它是一种高速现场总线网络,允许计算机、可编程控制器PLC和其他数据源以对等式令牌循环方式进行通信,其电气特性为-485,适用于工业控制领域。MB+网具有高速、对等通信、结构简单、安装费用低等特点;其通信速度为1MBPs,通信介质为双绞线或同轴电缆或光纤。
Modbus是一种通讯结构,广泛应用在智能设备之间进行主-从方式通讯。一个Modbus信息桢包括从机地址、功能码、数据区和数据校验码。正因为 Modbus仅仅定义了通讯结构,所以可以使用RS232、RS422和RS485端口,可以使用光纤、无线等媒质实现通讯。
而Modbus Plus则是一种典型的令牌环网,完整定义了通讯协议、网络结构、连接电缆(或者光缆)以及安装工具等方面的性能指标。
Modbus+网络中的设备通过‘令牌’的方式实现数据的交换, 严格定义了令牌的传递方式,数据校验以及通讯短口等方面的技术参数。
MODBUS PLUS比MODBUS的性能更好,通讯速率快,从协议开发上来说区别较大,modbus比较简单。
Modbus 串行链路协议是一个主-从协议。 在同一时刻,只有一个主节点连接于总线,一个或多个子节点 (最大编号为 247)连接于同一个串行总线。Modbus 通信总是由主节点发起。子节点在没有收到来自主节点的请求时,不会发送数据。子节点之间从不会互相通信。主节点在同一时刻只 会发起一个 Modbus 事务处理。
地址248 - 255是供用户自由扩展用的,如果标准规范覆盖0-255,那么255以上的地址或其它需要的特定功能就无法扩展了,这时可自由定义247以上的地址配合消息域实现非标扩展的同时尽量保持协议的兼容性,当然,该保留区用户也可以做其它定义,如特定地址段的广播指令等等,总之,这是为方便用户进行扩展使用而特意保留的。
主节点以两种模式对子节点发出 Modbus 请求:
在单播模式,主节点以特定地址访问某个子节点,子节点接到并处理完请求后,子节点向主节 点返回一个报文(一个 ‘应答’)。 在这种模式, 一个 Modbus 事务处理包含 2 个报文: 一个来自主节点的请求, 一个来自子节点的应答。 每个子节点必须有唯一的地址 (1 到 247),这样才能区别于其它节点被独立的寻址。
在广播模式,主节点向所有的子节点发送请求。 对于主节点广播的请求没有应答返回。 广播请求一般用于写命令。所有设备必须接受广播模式的写功能。地址 0 是专门用于表示广播数据的。
主站向从站发送请求帧进行事务请求,从站对接收到的请求帧进行分析,检验请求帧中的地址,功能码,寄存器地址,寄存器数量,校验码等,请求帧正确无误情况下,从站正常响应并返回正确的响应帧,若请求帧出错,则对应不响应或者异常响应,异常响应会返回对应的差错码和异常码(差错码=请求功能码|0x80;异常码用于指示差错原因)。
当服务器对客户机响应时,它使用功能码域来指示正常(无差错)响应或者出现某种差错(称为异常响应)。对于一个正常响应来说,服务器仅对原始功能码响应。
对于异常响应,服务器返回一个与原始功能码等同的码,设置该原始功能码的最高有效位为逻辑 1。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
寄存器是CPU内部用来存放数据的一些小型存储区域,用来暂时存放参与运算的数据和运算结果。其实寄存器就是一种常用的时序逻辑电路,但这种时序逻辑电路只包含存储电路。寄存器的存储电路是由锁存器或触发器构成的,因为一个锁存器或触发器能存储1位二进制数,所以由N个锁存器或触发器可以构成N位寄存器。寄存器是中央处理器内的组成部分。寄存器是有限存储容量的高速存储部件,它们可用来暂存指令、数据和位址。
线圈寄存器,实际上就可以类比为开关量,每一个bit都对应一个信号的开关状态。所以一个byte就可以同时控制8路的信号。比如控制外部8路IO的高低。 线圈寄存器支持读也支持写,写在功能码里面又分为写单个线圈寄存器和写多个线圈寄存器。
离散输入寄存器,如果线圈寄存器理解了这个自然也明白了。离散输入寄存器就相当于线圈寄存器的只读模式,他也是每个bit表示一个开关量,而他的开关量只能读取输入的开关信号,是不能够写的。
保持寄存器,这个寄存器的单位不再是bit而是两个byte,也就是可以存放具体的数据量的,并且是可读写的。比如我我设置时间年月日,不但可以写也可以读出来现在的时间。
输入寄存器,这个和保持寄存器类似,但是也是只支持读而不能写。一个寄存器也是占据两个byte的空间。类比我通过读取输入寄存器获取现在的AD采集值。
如上图所示TCP的报文格式由事务标识符,协议标识符,长度,单元标识符,功能码,数据组成TCP应用数据单元ADU,由功能码加数据组成PDU协议数据单元。
RTU 由单元标识符,功能码,数据,差错校验,组成 应用数据单元ADU,由功能码,数据组成协议数据单元PDU。
RTU
设备地址 | 功能代码 | 数据格式 | CRC校验L | CRC校验H |
---|---|---|---|---|
8bit | 8bit | N*8bit | 8bit | 8bit |
TCP
事务标识 | 协议标识符 | 长度 | 单元标识符 | 功能码 | 数据 |
---|---|---|---|---|---|
2Bytes | 2Bytes | 2Bytes | 1Bytes | 1Bytes | n*Bytes |
异常帧格式
RTU
从站地址 | 异常功能码 | 异常码 | CRCL | CRCH |
---|---|---|---|---|
0x01 | (01,03,0f,10)+0x80 | 01/02/03 | 81 | 90 |
异常应答:按照功能码高位置1得到异常功能码,按照功能码非法或数据地址非法或数据值非法判断相应的异常码,计算低高位校验码获得异常响应报文。
TCP
事务标识 | 协议标识符 | 长度 | 从站地址 | 异常功能码 | 异常码 |
---|---|---|---|---|---|
2Bytes | 2Bytes | 2Bytes | 0x01 | (01,03,0f,10)+0x80 | 01/02/03 |
异常应答:按照功能码高位置1得到异常功能码,按照功能码非法或数据地址非法或数据值非法判断相应的异常码。
读线圈状态:在一个远程设备中,使用该功能码读取线圈的1至2000连续状态。
假设从机地址为01H,读取的线圈寄存器的起始地址为0017H,读取38个寄存器。
RTU
读线圈寄存器指令:01 01 00 17 00 26 0D D4
从机地址 | 功能码 | 起始地址高位 | 起始地址低位 | 寄存器数量高位 | 寄存器数量低位 | CRC高位 | CRC低位 |
---|---|---|---|---|---|---|---|
01 | 01 | 00 | 17 | 00 | 26 | 0D | D4 |
TCP 在RTU的基础上去掉差错校验,加上MBAP头。
读线圈寄存器指令:00 01 00 00 00 06 01 01 00 17 00 26
各线圈的状态与数据内容的每个bit对应,1代表ON,0代表OFF。如果查询的线圈数量不是8的倍数,则在最后一个字节的高位补0。
读线圈状态的返回结果:
线圈0017H到001E的状态
从机地址 | 功能码 | 返回字节数 | 数据1 | 数据2 | 数据3 | 数据4 | 数据5 | CRC高位 | CRC低位 |
---|---|---|---|---|---|---|---|---|---|
01 | 01 | 05 | CD | 6B | B2 | 0E | 1B | 44 | EA |
其中,第一个字节CDH对应线圈0017H到001E的状态,转为二进制是11001101,其中bit0对应0017H,bit7对应001E。
线圈0017H到001EH的状态
001EH | 001DH | 001CH | 001BH | 001AH | 0019H | 0018H | 0017H |
---|---|---|---|---|---|---|---|
1 | 1 | 0 | 0 | 1 | 1 | 0 | 1 |
ON | ON | OFF | OFF | ON | ON | OFF | ON |
最后一个字节为1BH,对应线圈0037H到003CH的状态,转为二进制是00011011,其中bit0对应0037H,bit5对应003CH,其余两位用0填充
线圈0037H到003CH的状态
003CH | 003BH | 003AH | 0039H | 0038H | 0037H | 0036H | 0035H |
---|---|---|---|---|---|---|---|
0 | 0 | 0 | 1 | 1 | 0 | 1 | 1 |
填充 | 填充 | OFF | ON | ON | OFF | ON | ON |
读保持寄存器,字节指令操作,可读单个或者多个(保持寄存器是一个字:word)
假设从机地址为01H,读取的保持寄存器的起始地址为006BH,读取3个寄存器
读保持寄存器指令:
从机地址 | 功能码 | 起始地址高位 | 起始地址低位 | 寄存器数量高位 | 寄存器数量低位 | CRC高位 | CRC低位 |
---|---|---|---|---|---|---|---|
01 | 03 | 00 | 6B | 00 | 03 | 74 | 17 |
每个保持寄存器的长度为2个字节。保持寄存器之间,低地址寄存器先传输,高地址寄存器后传输。单个保持寄存器,高字节数据先传输,低字节数据后传输。
从机地址 | 功能码 | 字节数 | 006BH高字节 | 006BH低字节 | 006CH高字节 | 006CH低字节 | 006DH高字节 | 006DH低字节 | CRC高位 | CRC低位 |
---|---|---|---|---|---|---|---|---|---|---|
01 | 03 | 06 | 00 | 6B | 00 | 13 | 00 | 00 | F5 | 79 |
功能码0FH写多个线圈寄存器。如果对应的数据位为1,表示线圈状态为ON;如果对应的数据位为0,表示线圈状态为OFF。线圈寄存器之间,低地址寄存器先传输,高地址寄存器后传输。单个线圈寄存器,高字节数据先传输,低字节数据后传输。如果写入的线圈寄存器的个数不是8的倍数,则在最后一个字节的高位补0。
假设从机地址为01H,线圈寄存器的起始地址为0013H,写入10个寄存器
从机地址 | 功能码 | 起始地址高位 | 起始地址低位 | 数量高位 | 数量低位 | 字节数 | 数据1 | 数据2 | CRC高位 | CRC低位 |
---|---|---|---|---|---|---|---|---|---|---|
01 | 0F | 00 | 13 | 00 | 0A | 02 | CD | 01 | 72 | CB |
其中,CDH对应线圈0013H到001AH的内容,01H对应线圈001B到001CH的内容,未使用位用0填充。
线圈寄存器0013H到001CH的内容
001AH | 0019H | 0018H | 0017H | 0016H | 0015H | 0014H | 0013H |
---|---|---|---|---|---|---|---|
1 | 1 | 0 | 0 | 1 | 1 | 0 | 1 |
0022H | 0021H | 0020H | 001FH | 001EH | 001DH | 001CH | 001BH |
---|---|---|---|---|---|---|---|
0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
如果写入成功,返回写入的寄存器数量:
写多个线圈寄存器的返回结果
从机地址 | 功能码 | 起始地址高位 | 起始地址低位 | 数量高位 | 数量低位 | CRC高位 | CRC低位 |
---|---|---|---|---|---|---|---|
01 | 0F | 00 | 13 | 00 | 0A | 24 | 09 |
假设从机地址为01H,保持寄存器的起始地址为0001H,写入2个寄存器
从机地址 | 功能码 | 起始地址高位 | 起始地址低位 | 数量高位 | 数量低位 | 字节数 | 0001H高位 | 0001H低位 | 0002H高位 | 0002H低位 | CRC高位 | CRC低位 |
---|---|---|---|---|---|---|---|---|---|---|---|---|
01 | 10 | 00 | 01 | 00 | 02 | 04 | 00 | 0A | 01 | 02 | 92 | 30 |
如果写入成功,返回写入的寄存器数量
写多个保持寄存器的返回结果
从机地址 | 功能码 | 起始地址高位 | 起始地址低位 | 数量高位 | 数量低位 | CRC高位 | CRC低位 |
---|---|---|---|---|---|---|---|
01 | 10 | 00 | 01 | 00 | 02 | 10 | 08 |
常用的通信从传输方向上可以分为单工通信、半双工通信、全双工通信三类。
单工通信就是指只允许一方向另外一方传送信息,而另一方不能回传信息。比如电视遥控器、收音机广播等,都是单工通信技术。
半双工通信是指数据可以在双方之间相互传播,但是同一时刻只能其中一方发给另外一方,比如我们的对讲机就是典型的半双工。
全双工通信就发送数据的同时也能够接收数据,两者同步进行,就如同我们的电话一样,我们说话的同时也可以听到对方的声音。
通信双方共用一个时钟,这是同步通信区分于异步通信的最显著的特点,为了保证接收正确无误,发送方除了传送数据外,还要传送同步时钟。
同步传输是以数据块为传输单位,在数据块传送时,为提高通信速度,去掉了起始位和停止位。数据开始传送前用同步字符来指示(常约定1~2 个),并由时钟来实现发送端和接收端的同步,即检测到规定的同步字符后,下面就连续按顺序传送数据,直到一块数据传送完毕。
数据块与数据块之间的时间间隔是固定的,且不允许有空位,当线路空闲或不发信息时,发送同步字符。
同步传输中,发送方发出数据后等接收方发回响应以后才发下一个数据包。
在异步通信中,数据通常是以字符为单位组成字符帧传送的。字符帧由发送端一帧一帧地发送,每一帧数据均是低位在前,高位在后,通过传输线被接收端一帧一帧地接收。发送端和接收端可以由各自独立的时钟来控制数据的发送和接收,这两个时钟彼此独立,互不同步。
在异步通信中,接收端是依靠字符帧格式来判断发送端是何时开始发送,何时结束发送的。字符帧格式是异步通信的一个重要指标。
字符帧(Character Frame)
字符帧也叫数据帧,由起始位、数据位、奇偶校验位和停止位等4部分组成。
波特率(baud rate)
异步通信的另一个重要指标为波特率。
波特率为每秒钟传送二进制数码的位数,也叫比特数,单位为b/s,即位/秒。波特率用于表征数据传输的速度,波特率越高,数据传输速度越快。但波特率和字符的实际传输速率不同,字符的实际传输速率是每秒内所传字符帧的帧数,和字符帧格式有关。
RS232传输电平信号
接口的信号电平值较高(信号“1”为“-3V至-15V”,信号“0”为“3至15V”),易损坏接口电路的芯片,又因为与TTL电平(0“<0.8v”,1“>2.0V”)不兼容故需使用电平转换电路方能与TTL电路连接。另外抗干扰能力差。
RS485传输差分信号
逻辑“1”以两线间的电压差为+(2—6) V表示;逻辑“0”以两线间的电压差为-(2—6)V表示。接口信号电平比RS-232降低了,就不易损坏接口电路的芯片,且该电平与TTL电平兼容,可方便与TTL电路连接。
通讯距离长短
RS232:
RS232传输距离有限,最大传输距离标准值为15米,且只能点对点通讯,最大传输速率最大为20kB/s。
RS485:
RS485最大无线传输距离为1200米。最大传输速率为10Mbps,在100Kb/S的传输速率下,才可以达到最大的通信距离。
采用阻抗匹配、低衰减的专用电缆可以达到1800米!超过1200米,可加中继器(最多8只),这样传输距离接近10Km。
能否支持多点通讯
**RS232:**RS232接口在总线上只允许连接1个收发器,不能支持多站收发能力,所以只能点对点通信,不支持多点通讯。
**RS485:**RS485接口在总线上是允许连接多达128个收发器。即具有多站通讯能力,这样用户可以利用单一的RS485接口方便地建立起设备网络。
通讯线的差别
RS232:
可以采用三芯双绞线、三芯屏蔽线等。
RS485:
可以采用两芯双绞线、两芯屏蔽线等。
在低速、短距离、无干扰的场合可以采用普通的双绞线,反之,在高速、长线传输时,则必须采用阻抗匹配(一般为120Ω)的RS485专用电缆(STP-120Ω(用于RS485 & CAN)一对18AWG),而在干扰恶劣的环境下还应采用铠装型双绞屏蔽电缆(ASTP-120Ω(用于RS485 & CAN)一对18AWG)。
TCP/IP是一个协议簇,里面包括很多协议。
TCP(Transmission Control Protocol,传输控制协议)是面向连接的协议,即在收发数据钱 ,都需要与对面建立可靠的链接,即三次握手以及TCP的四次挥手!
三次握手:建立一个TCP连接时,需要客户端和服务端总共发送3个包以确认连接的建立, 在Socket编程中,这一过程由客户端执行connect来触发,具体流程如下:
四次挥手:所谓四次挥手(Four-Way Wavehand)即终止TCP连接,就是指断开一个TCP连接时,需要客户端和服务端总共发送4个包以确认连接的断开。在socket编程中,这一过程由客户端或服务端任一方执行close来触发,整个流程如下图所示:
人机界面又称用户界面或使用者界面,是人与计算机之间传递、交换信息的媒介和对话接口,是计算机系统的重要组成部分。是系统和用户之间进行交互和信息交换的媒介,它实现信息的内部形式与人类可以接受形式之间的转换。凡参与人机信息交流的领域都存在着人机界面。
就对于此次实现的四个主从站的UI界面而言
本次实现主要是通过QT来设计用户界面;UI设计是指对软件的人机交互、操作逻辑、界面美观的整体设计。
设计原则为:
TIME_WAIT状态,接着发送一个ACK给Server,确认序号为收到序号+1,Server进入CLOSED状态,完成四次挥手
人机界面又称用户界面或使用者界面,是人与计算机之间传递、交换信息的媒介和对话接口,是计算机系统的重要组成部分。是系统和用户之间进行交互和信息交换的媒介,它实现信息的内部形式与人类可以接受形式之间的转换。凡参与人机信息交流的领域都存在着人机界面。
就对于此次实现的四个主从站的UI界面而言
本次实现主要是通过QT来设计用户界面;UI设计是指对软件的人机交互、操作逻辑、界面美观的整体设计。
设计原则为: