modbus协议之串行链路
一、modbus简介
Modbus是一种串行通信协议,是Modicon公司(现在的施耐德电气Schneider Electric)于1979年为使用可编程逻辑控制(PLC)通信而发表。Modbus已经成为工业领域通信协议的业界标准(De facto),并且现在是工业电子设备之间常用的连接方式。
Modbus有下列三种通信方式
1、以太网,对应的通信模式是MODBUS TCP。
2、异步串行传输(各种介质如有线RS-232-/422/485/;光纤、无线等),对应的通信模式是MODBUS RTU或MODBUS ASCII。
3、高速令牌传递网络,对应的通信模式是Modbus PLUS。
二、modbus消息桢
Modbus消息桢包括RTU、ASCII、TCP。其中MODBUS-RTU最常用,RTU、ASCII消息桢用于异步串行传输通信,TCP通信方式的消息桢与RTU、ASCII消息桢也有关联,具体见《MODBUS-TCP》。 其中异步串行传输通信中RTU类型的消息桢最为常用。
2.1、通用消息桢
ADU: 应用数据单元 PDU: 协议数据单元
2.2、ASCII消息桢
1、消息以冒号(:)字符(ASCII码 3AH)开始,以回车换行符结束(ASCII码 0DH,0AH)。
2、其它域可以使用的传输字符是十六进制的0...9,A...F。网络上的设备不断侦测“:”字符,当有一个冒号接收到时,每个设备都解码下个域(地址域)来判断是否发给自己的。
3、消息中字符间发送的时间间隔最长不能超过1秒,否则接收的设备将认为传输错误。
//串行链路bit格式
十六进制,ASCII字符0...9,A...F
----消息中的每个ASCII字符都是一个十六进制字符组成 每个字节的位
1个起始位
7个数据位,最小的有效位先发送
1个奇偶校验位,无校验则无
1个停止位(有校验时),2个Bit(无校验时)
LRC(纵向冗长检测)
问:ASCII消息桢模式通信,在消息中的每个8Bit字节都作为两个ASCII字符发送,怎么理解?
答:实际上在ASCII模式下,所有的通讯数据都是ASCII码,包括帧结束用的也是ASCII码里的回车、换行。每个字节都作为一个ASCII码,这里说的有点歧义。应该说是两个ASCII码。比如要传送一个字节,字节内容是0x23,则实际传送的是两个ASCII码,即字符2(0x32)和字符3(0x33)。这种编码的好处是所有的字符都是可读的,不会出现0x00、0xFF这种不可读的,方便调试。缺点是效率低,把一个字节拆成两个ASCII码,数据量变大了。
追问:字节内容是0x23,这是几个字节,是几进制?
追答:0x23 这个是十六进制表示方法。这是一节字节的数据,是指MODBUS里面的数据,与传送无关。传送的时候,把一个字节拆成2个ASCII表示,0x32,0x33,这个是传送的过程中的一种变换,接收方在接收到后,需要重新拼接,还原成数据,即0x23。
2.3、RTU消息桢
1、消息发送至少要以3.5个字符时间的停顿间隔开始。在网络波特率下多样的字符时间,这是最容易实现的(如下图的T1-T2-T3-T4所示)。传输的第一个域是设备地址
。可以使用的传输字符是十六进制的0...9,A...F。
2、网络设备不断侦测网络总线,包括停顿间隔时间内。当第一个域(地址域)接收到,每个设备都进行解码以判断是否发往自己的。在最后一个传输字符之后,一个至少3.5个字符时间的停顿标定了消息的结束。一个新的消息可在此停顿后开始。
3、整个消息帧必须作为一连续的流转输。如果在帧完成之前有超过1.5个字符时间的停顿时间,接收设备将刷新不完整的消息并假定下一字节是一个新消息的地址域。
4、如果一个新消息在小于3.5个字符时间内接着前个消息开始,接收的设备将认为它是前一消息的延续。这将导致一个错误,因为在最后的CRC域的值不可能是正确的。
//串行链路bit格式
8位二进制,十六进制数0...9,A...F
消息中的每个8位域都是一个两个十六进制字符组成
每个字节的位
1个起始位
8个数据位,最小的有效位先发送
1个奇偶校验位,无校验则无
1个停止位(有校验时),2个Bit(无校验时)
CRC(循环冗长检测)
三、modus设备地址与功能码
3.1、设备地址域
消息帧的地址域包含两个字符(ASCII)或8Bit(RTU)。可能的从设备地址是0...247 (十进制)。单个设备的地址范围是1...247。主设备通过将要联络的从设备的地址放入消息中的地址域来选通从设备。当从设备发送回应消息时,它把自己的地址放入回应的地址域中,以便主设备知道是哪一个设备作出回应。地址0是用作广播地址,以使所有的从设备都能认识。当Modbus协议用于更高水准的网络,广播可能不允许或以其它方式代替。
3.2、数据域起始地址
1、PLC地址和协议地址区别
PLC地址可以理解为协议地址的变种,在触摸屏和PLC编程中应用较为广泛。
2、寄存器PLC地址
寄存器PLC地址指存放于控制器中的地址,这些控制器可以是PLC,也可以使触摸屏,或是文本显示器。PLC地址一般采用10进制描述,共有5位,其中第一位代码寄存器类型。PLC地址例如40001、30002等。
3、寄存器协议地址
寄存器协议地址指指通信时使用的寄存器地址,例如PLC地址40001对应寻址地址0x0000,40002对应寻址地址0x0001,寄存器寻址地址一般使用16进制描述。再如,PLC寄存器地址40003对应协议地址0002,PLC寄存器地址30003对应协议地址0002,虽然两个PLC寄存器寄存器通信时使用相同的地址,但是需要使用不同的命令访问,所以访问时不存在冲突。
PLC每个块其实寄存器起始地址从1开始,一般看手册上说读某一地址的数据,给某一地址写数据,该地址指的都是寄存器的地址,并不是modbus报文中的数据的起始地址。modbus应用协议的中数据的起始地址从0开始。
3.3、功能码
参考文档:https://blog.csdn.net/lakerszhy/article/details/68927178?locationNum=4&fps=1
功能码:通讯传送的第二个字节。ModBus通讯规约定义功能号为1到127。本仪表只利用其中的一部分功能码。作为主机请求发送,通过功能码告诉从机执行什么动作。作为从机响应,从机发送的功能码与从主机发送来的功能码一样,并表明从机已响应主机进行操作。如果从机发送的功能码的最高位为1(比如功能码大与此同时127),则表明从机没有响应操作或发送出错。
3.3.1、Modbus寄存器
3.3.2、Modbus寄存器数据类型
数据名称 | 数据说明 | 数据类型 | 读写状态 | 应用举例 |
---|---|---|---|---|
线圈状态 | DI数字量输出 | 位变量 | 只读 | 电磁阀输出,MOSFET输出,LED显示等 |
离散输入状态 | DI数字量输出 | 位变量 | 读写 | 拨码开关,接近开关等 |
保持寄存器 | AO模拟量输出 | 16-bit类型 | 只读 | 模拟量输出设定值,PID运行参数,变量阀输出大小,传感器报警上限下限 |
输入寄存器 | AO模拟量输入 | 16-bit类型 | 读写 | 模拟量输入 |
3.3.3、Modbus寄存器数据类型
Modbus中常用的功能码有8个,可以分为位操作和字操作两类,如表2.1所示:
附录一、CRC校验与LRC校验
附录二、功能码
功能码 名称 作用
1 读取线圈状态 取得一组逻辑线圈的当前状态(ON/OFF)
2 读取输入状态 取得一组开关输入的当前状态(ON/OFF)
3 读取保持寄存器 在一个或多个保持寄存器中取得当前的二进制值
4 读取输入寄存器 在一个或多个输入寄存器中取得当前的二进制值
5 强置单线圈 强置一个逻辑线圈的通断状态
6 预置单寄存器 把具体二进值装入一个保持寄存器
7 读取异常状态 取得8个内部线圈的通断状态,这8个线圈的地址由控制器决定
8 回送诊断校验 把诊断校验报文送从机,以对通信处理进行评鉴
9 编程(只用于484) 使主机模拟编程器作用,修改PC从机逻辑
10 控询(只用于484) 可使主机与一台正在执行长程序任务从机通信,探询该从机是否已完成其操作任务,仅在含有功能码9的报文发送后,本功能码才发送
11 读取事件计数 可使主机发出单询问,并随即判定操作是否成功,尤其是该命令或其他应答产生通信错误时
12 读取通信事件记录 可是主机检索每台从机的ModBus事务处理通信事件记录。如果某项事务处理完成,记录会给出有关错误
13 编程(184/384 484 584) 可使主机模拟编程器功能修改PC从机逻辑
14 探询(184/384 484 584)可使主机与正在执行任务的从机通信,定期控询该从机是否已完成其程序操作,仅在含有功能13的报文发送后,本功能码才得发送
15 强置多线圈 强置一串连续逻辑线圈的通断
16 预置多寄存器 把具体的二进制值装入一串连续的保持寄存器
17 报告从机标识 可使主机判断编址从机的类型及该从机运行指示灯的状态
18 (884和MICRO 84) 可使主机模拟编程功能,修改PC状态逻辑
19 重置通信链路 发生非可修改错误后,是从机复位于已知状态,可重置顺序字节
20 读取通用参数(584L) 显示扩展存储器文件中的数据信息
21 写入通用参数(584L) 把通用参数写入扩展存储文件,或修改之
22~64 保留作扩展功能备用
65~72 保留以备用户功能所用
73~119 非法功能
120~127 保留 留作内部作用
128~255 保留 用于异常应答
其它参考文档
《MODBUS软件开发指南---杨更更》
https://blog.csdn.net/lakerszhy/article/details/68927178?locationNum=4&fps=1
https://blog.csdn.net/byxdaz/article/details/77892778
https://www.cnblogs.com/luomingui/archive/2013/06/14/Modbus.html