简介
Modbus诞生于1979年 莫迪康公司 后来被施耐德电气公司收购。Modbus提供通用语言用于彼此通信的设备和设备。Modbus 协议是应用于电子控制器上的一种通用语言。通过此协议,控制器相互之间、控制器经由网络(例如以太网)和其它设备之间可以通信。它已经成为一通用工业标准。有了它,不同厂商生产的控制设备可以连成工业网络,进行集中监控。简单的说,Modbus就是一个总线通信协议,像IIC SPI这种,但是他不依赖于硬件总线。
Modbus协议的优点
- 简单易用:Modbus协议结构简单,容易理解和实现,适合快速开发和集成。
- 开放标准:Modbus是开放协议,没有许可费用,广泛应用于工业自动化设备中。
- 设备兼容性好:由于广泛使用,很多设备都支持Modbus协议,方便不同厂商设备之间的通信。
- 多种传输方式:支持串行通信(RTU、ASCII)和以太网通信(TCP/IP),适应不同应用场景。
- 稳定可靠:Modbus协议已在工业领域使用多年,经过充分验证,稳定性和可靠性都很高。
- Modbus协议支持多种电气接口:包括RS232、RS485、TCP/IP等,还可以在各种介质上传输,如双绞线、光纤、红外、无线等
Modbus通信过程
Modbus协议是一种应用层报文传输协议,协议本身并没有定义物理层,定义了控制器能够认识和使用的消息结构,不管它们是经过何种网络进行通信的。 所以能够适应多种电气接口,因此使用非常广泛。Modbus是一主多从的通信协议。Modbus通信中只有一个设备可以发送请求。其他从设备接收主机发送的数据来进行响应,从机是任何外围设备,如I/O传感器,阀门,网络驱动器,或其他测量类型的设备。从站处理信息和使用Modbus将其数据发送给主站。总线上每次只有一个数据进行传输,即主机发送,从机应答,主机不发送,总线上就没有数据通信。
Modbus存储区
既然从机存储数据,那么肯定要有一个存储区,那就需要文件操作,我们都知道这文件可以分为只读(-r)和读写(-wr)两种类型,并且存储的数据类型可以分为 :布尔量 和 16位寄存器
布尔量比如IO口的电平高低,灯的开关状态等。
16位寄存器比如 传感器的温度数据,存储的密码等。
Modbus协议规定了4个存储区 分别是0 1 3 4区 其中1区和4区是可读可写,1区和3区是只读。
区号 | 名称 | 读写 | 地址范围 |
---|---|---|---|
0区 | 输出线圈 | 可读可写布尔量 | 00001-09999 |
1区 | 输入线圈 | 只读布尔量 | 10001-19999 |
3区 | 输入寄存器 | 只读寄存器 | 30001-39999 |
4区 | 保持寄存器 | 可读可写寄存器 | 40001-49999 |
Modbus数据模型规定了具体的地址范围,每一个从机,都有实际的物理存储,跟modbus的存储区相对应,主机读写从机的存储区,实际上就是对从机设备对应的实际存储空间进行读写。
并且Modbus还给每个区都划分了地址范围 主机向从机获取数据时,只需要告诉从机数据的起始地址,还有获取多少字节的数据,从机就可以发送数据给主机。
Modbus通信模式
Modbus协议支持多种通信模式,其中最常用的有两种:
- Modbus RTU(Remote Terminal Unit):
- 传输方式:基于串行通信,通常使用RS-232或RS-485接口。
- 数据格式:十六进制格式,数据紧凑,传输效率高。
- 帧结构:包含地址、功能码、数据和CRC校验码。
- 通信速度:通常为9600bps,但也支持更高的速度。
- Modbus ASCII:
- 传输方式:同样基于串行通信,但数据以ASCII码表示。
- 数据格式:每个字节用两个ASCII字符表示,易于人类阅读,但效率低于Modbus RTU。
- 每个8Bit 字节都作为两个ASCII字符发送的表示方式。
- 帧结构:以冒号“:”开始,以回车和换行结束。
- Modbus TCP/IP:
- 传输方式:基于以太网,使用TCP/IP协议栈。
- 数据格式:数据以标准TCP/IP数据包的形式传输,适合在局域网或广域网中使用。
- 帧结构:与Modbus RTU类似,但没有CRC校验码,因为TCP/IP已经包含了数据校验。
Modbus协议使用串口传输时可以选择RTU或ASCII模式,并规定了消息、数据结构、命令和应答方式并需要对数据进行校验。ASCII 模式采用LRC校验,RTU模式采用16 位CRC校验。通过以太网传输时使用TCP,这种模式不使用校验,因为TCP协议是一个面向连接的可靠协议。
Modbus-RTU协议
Modbus报文帧结构
一个报文就是一帧数据,一个数据帧就一个报文: 指的是一串完整的指令数据,本质就是一串数据。
Modbus报文是指主机发送给从机的一帧数据,其中包含着从机的地址,主机想执行的操作,校验码等内容
Modbus协议在串行链路上的报文格式如下所示:
从站地址 | 功能码 | 数据 | CRC/LRC |
---|---|---|---|
1 byte | 1 byte | N bytes | 2 bytes |
帧结构 = 从机地址 + 功能吗 + 数据 + 校验
从机地址: 每个从机都有唯一地址,占用一个字节,范围0-255,其中有效范围是1-247,其中255是广播地址 (广播就是对所有从机发送应答) 功能码: 占用一个字节,功能码的意义就是,知道这个指令是干啥的,比如你可以查询从机的数据,也可以修改从机的数据, 所以不同功能码对应不同功能. 从机地址: 每个从机都有唯一地址,占用一个字节,范围0-255,其中有效范围是1-247,其中255是广播地址 (广播就是对所有从机发送应答) 数据: 根据功能码不同,有不同功能,比方说功能码是查询从机的数据,这里就是查询数据的地址和查询字节数等。 校验: 在数据传输过程中可能数据会发生错误,CRC检验检测接收的数据是否正确。
Modbus功能码
Modbus规定了多个功能,那么为了方便的使用这些功能,我们给每个功能都设定一个功能码,也就是指代码。
Modbus协议同时规定了二十几种功能码,但是常用的只有8种,用于对存储区的读写,如下表所示:
功能码 | 功能说明 |
---|---|
01H | 读取输出线圈 |
02H | 读取输入线圈 |
03H | 读取保持寄存器 |
04H | 读取输入寄存器 |
05H | 写入单线圈 |
06H | 写入单寄存器 |
0FH | 写入多线圈 |
10H | 写入多寄存器 |
用的最多的就是03和06 一个是读取数据,一个是修改数据。
CRC校验样么直接用计算器转换,样么使用带自动添加CRC的调试软件:SerialPro
主机对从机读操作
从站地址 | 功能码 | 起始(高) | 起始(低) | 数量(高) | 数量(低) | 校验 |
---|---|---|---|---|---|---|
0x01 | 0x03 | 0x00 | 0x01 | 0x00 | 0x01 | 0xD5 0xCA |
0x01:从机的地址
0x03:查询功能,读取从机寄存器的数据
0x00 0x01: 代表读取的起始寄存器地址.说明从0x0001开始读取.
0x00 0x01: 查询的寄存器数量为0x0001个 Modbus把数据存放在寄存器中,通过查询寄存器来得到不同变量的值,一个寄存器地址对应2字节数据; 寄存器地址对应着从机实际的存储地址
0xD5 0xCA: 循环冗余校验 CRC
从机回复
从站地址 | 功能码 | 字节计数 | 字节1 | 字节2 | 字节n | 校验 |
---|---|---|---|---|---|---|
0x01 | 0x03 | 0x02 | 0x00 | 0x17 | 0x01 | 0xD5 0xCA |
0x01:从机的地址
0x03:查询功能,读取从机寄存器的数据
0x02: 返回字节数为2个 一个寄存器2个字节
0x00 0x17:寄存器的值是0017
0xD5 0xCA: 循环冗余校验 CRC
主机对从机写操作
从站地址 | 功能码 | 数据地址(高) | 数据地址(低) | 数据(高) | 数据(低) | 校验 |
---|---|---|---|---|---|---|
0x01 | 0x06 | 0x00 | 0x01 | 0x00 | 0x17 | 0x98 0x04 |
0x01:从机的地址
0x06:修改功能,修改从机寄存器的数据
0x00 0x01: 代表修改的起始寄存器地址.说明修改0x0000-0x0001的存储内容
0x00 0x17: 要修改的数据值为0017
0x98 0x04: 循环冗余校验 CRC
从机回复
从站地址 | 功能码 | 数据地址(高) | 数据地址(低) | 数据(高) | 数据(低) | 校验 |
---|---|---|---|---|---|---|
0x01 | 0x06 | 0x00 | 0x01 | 0x00 | 0x17 | 0x98 0x04 |
0x01:从机的地址
0x06:修改功能,修改从机寄存器的数据
0x00 0x01: 代表修改的起始寄存器地址.说明是0x0000
0x00 0x17:修改的值为0017
0x98 0x04: 循环冗余校验 CRC
比较全的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/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 | 保留 | 留作内部作用 |
其中常用的功能码有8个(01、02、03、04、05、06、15、16),可以分为位操作和字操作两类,其中,位操作的是线圈和离散输入,两者区别在于,线圈是可读可写的,而离散输入是只读。字操作的是保持寄存器和输入寄存器,两者区别在于,保持寄存器是可读可写的,而输入寄存器是只读的。