Modbus协议

1.前言

1.协议概述

为了保证单片机交互的统一性,内容的规范性,保证双方同时遵守,从而实现两者的通信

2.串口-RS

串口实际是一种电平标准(在工控中数据的而传输实际是一种物理的电平信号)

基本信号

  1. TXD (Transmit Data): 发送数据信号
  2. RXD (Receive Data): 接收数据信号

控制信号

SignalDescription
RTS (Request to Send)请求发送信号,由发送方产生,用于请求发送数据,通常用于硬件流控制
CTS (Clear to Send)清除发送信号,由接收方产生,指示发送方可以发送数据,通常与RTS信号配对使用
DSR (Data Set Ready)数据设备就绪信号,由调制解调器或其他数据终端设备产生,指示设备已准备好通信
DTR (Data Terminal Ready)数据终端就绪信号,由计算机或终端设备产生,指示设备已准备好通信
DCD (Data Carrier Detect)数据载波检测信号,由调制解调器产生,指示已检测到载波信号,表明可以进行通信
RI (Ring Indicator)振铃指示信号,由调制解调器产生,指示有来电

串口通信参数

  1. 波特率 (Baud Rate): 数据传输速度,表示每秒钟传输的比特数。常见的波特率有9600、19200、115200等
  2. 数据位 (Data Bits): 每个字符的数据位数,常见的有7位、8位
  3. 停止位 (Stop Bits): 每个字符结束时的停止位,通常为1位或2位
  4. 奇偶校验 (Parity): 一种错误检测机制,分为无校验 (None)、奇校验 (Odd)、偶校验 (Even)

串口通信标准

1.RS-232:

最常见的串口通信标准,使用单端信号传输,传输距离较短

  • 全双工
  • 逻辑1:-15V–5V
  • 逻辑0:+3V–+15V

2.RS-485:

使用差分信号传输,抗干扰能力强,传输距离较长,支持多点通信

image-20241122035157436
  • 半双工
  • 逻辑1:+2V~+6V
  • 逻辑0: -2V~ -6V
  • 注意485的电平指的是485-A和485-B两根传输线,两线间的电压差,不是传输线上的电压

RS-485电平标准确定传输过来的数据是0还是1,在此基础上,这些字节数据根据modbus通信协议来进行数据的交互传输

3.RS-422:

也是使用差分信号传输,但通常用于点对点通信,传输距离较长

3.Modbus协议概述

1.简要说明

是一个总线通信协议,不依赖于硬件的总线

2.特性优势

特性

  1. 开放标准: Modbus是一个开放的通信协议,任何人都可以使用
  2. 简单易用: 协议结构简单,容易理解和实现
  3. 多种传输方式: 支持串行通信(RS-232、RS-485)和网络通信(Modbus TCP/IP)
  4. 主/从架构: 一个主设备与多个从设备通信,主设备发起请求,从设备响应
  5. 功能码: 定义操作类型,如读写寄存器、线圈等

优势

  1. 广泛兼容: 几乎所有工业设备制造商都支持Modbus,设备间通信方便
  2. 便携性: 可以在不同物理层上工作,支持多种实现方式

3.应用

  • PLC(可编程逻辑控制器): PLC之间及与其他设备的通信
  • 远程监控和数据采集(SCADA): 远程终端单元(RTU)中使用
  • 智能仪表: 如电能表、流量计的数据传输
  • 建筑管理系统(BMS): 监控和控制楼宇设备

2.Modbus协议详解

Modbus协议中,主设备发起请求,从设备接收并响应。通信是半双工的,每次只有一个设备在总线上传输数据,即主设备发送请求,从设备应答

1.Mosdus通信流程

注意Modbus是一主多从的通信协议

Modbus通信中只有一个设备可以发送请求。其他从设备接收主机发送的数据来进行响应,从机是任何外围设备,如I/O传感器,阀门,网络驱动器,或其他测量类型的设备。从站处理信息和使用Modbus将其数据发送给主站

也就是说,不能Modbus同步进行通信,主机在同一时间内只能向一个从机发送请求,总线上每次只有一个数据进行传输,即主机发送,从机应答,主机不发送,总线上就没有数据通信。

从机不会自己发送消息给主站,只能回复从主机发送的消息请求

1.流程简述

  1. 主机发送请求

主机发起通信,向从机发送一个请求帧,请求帧包括设备地址、功能码、数据和错误校验(CRC)

  1. 从机接收请求

从机接收到请求帧后,解析帧内容。如果请求有效且地址匹配,从机执行相应的操作(如读写寄存器)

  1. 从机发送响应

从机根据主机请求执行操作后,生成响应帧。响应帧包括设备地址、功能码、数据和错误校验(CRC)

  1. 主机接收响应

主机接收到响应帧后,解析帧内容,检查是否存在错误,并读取响应数据

2.请求帧结构

设备地址:1字节,指定目标从机地址

功能码:1字节,指定操作类型(如读写寄存器)

数据:根据功能码的不同,数据长度和内容会有所不同

错误校验(CRC):2字节,用于检测传输错误

3.响应帧结构

设备地址:1字节,响应的从机地址

功能码:1字节,与请求中的功能码一致

数据:返回的操作结果(如寄存器值)

错误校验(CRC):2字节,用于检测传输错误

4.模拟通信

主机发送请求:

  • 设备地址:0x01
  • 功能码:0x03
  • 起始地址:0x0000
  • 寄存器数量:0x0002
  • CRC:0xXXXX(根据具体计算得出)

从机响应:

  • 设备地址:0x01
  • 功能码:0x03
  • 字节数:0x04
  • 寄存器值:0x1234 0x5678
  • CRC:0xXXXX(根据具体计算得出)

5.结构示意图

主机                      从机
|                       |
|--- 发送请求帧 -------->|
|                       |
|<--- 接收并处理请求帧 ---|
|                       |
|<--- 发送响应帧 --------|
|                       |
|--- 接收并处理响应帧 --->|

2.Modbus存储区

从机存储数据,所以这里的文件操作同样存在(w)和(wr)类型

存储类型:

布尔值:存储电平高低,开关灯等

16位寄存器:存储面膜,温度等其他数据

存储分区:

区号名称读写地址范围
0区输出线圈可读可写布尔量00001-09999
1区输入线圈只读布尔量10001-19999
3区输入寄存器只读寄存器30001-39999
4区保持寄存器可读可写寄存器40001-49999

主机向从机获取数据时,只需要告诉从机数据的起始地址,还有获取多少字节的数据,从机就可以发送数据给主机

!https://g1rffe.oss-cn-chengdu.aliyuncs.com/typora/image-20240713010111210.png

3.Modbus协议类型

Modbus RTU使用紧凑的十六进制格式和16位CRC校验,Modbus ASCII使用每个8位字节作为两个ASCII字符发送并采用LRC校验。通过以太网传输时使用Modbus TCP/IP,不使用额外校验,因为TCP协议本身提供可靠性

1. Modbus RTU (Remote Terminal Unit)

特点:使用二进制格式传输数据,效率高 应用:常用于RS-232或RS-485通信链路

帧结构:

  • 设备地址:1字节,标识目标设备
  • 功能码:1字节,表示请求的操作类型(如读写寄存器)
  • 数据:可变长度,根据功能码决定内容(如寄存器地址和数量)
  • CRC校验:2字节,用于错误检测。
+-------------+------------+----------+---------+
| 设备地址 (1) | 功能码 (1) | 数据 (N) | CRC (2) |
+-------------+------------+----------+---------+

实现步骤:

  1. 主设备构建请求帧,包含设备地址、功能码、数据和CRC校验
  2. 通过RS-232或RS-485链路发送请求帧
  3. 从设备接收请求帧,验证CRC校验,解析并执行请求
  4. 从设备构建响应帧,包含设备地址、功能码、数据和CRC校验
  5. 从设备发送响应帧,主设备接收并验证CRC校验

2. Modbus ASCII

特点:使用ASCII码传输数据,适合调试和显示 应用:常用于串行链路

帧结构:

  • 起始符:1字节,通常为冒号(:)
  • 设备地址:2个ASCII字符,表示16进制数
  • 功能码:2个ASCII字符,表示16进制数
  • 数据:可变长度,每个字节用2个ASCII字符表示
  • LRC校验:2个ASCII字符,用于错误检测
  • 结束符:2字节,通常为回车和换行(CR LF)
+-------+-------------+------------+----------+--------+-----+
| 起始符 | 设备地址 (2) | 功能码 (2) | 数据 (N) | LRC (2) | 结束符 |
+-------+-------------+------------+----------+--------+-----+
(:)         (0-9, A-F)   (0-9, A-F) (0-9, A-F) (0-9, A-F) (CR LF)

实现步骤

  1. 主设备构建请求帧,包含起始符、设备地址、功能码、数据和LRC校验
  2. 通过串行链路发送请求帧
  3. 从设备接收请求帧,验证LRC校验,解析并执行请求
  4. 从设备构建响应帧,包含起始符、设备地址、功能码、数据和LRC校验
  5. 从设备发送响应帧,主设备接收并验证LRC校验

3. Modbus TCP/IP

特点:基于以太网通信,数据通过TCP/IP网络传输 应用:适用于现代网络环境MBAP报文头字段详细描述

帧结构:

  1. Transaction Identifier(事务标识符)
    • 长度: 2字节
    • 事务标识符由客户端生成,用于匹配请求和响应。服务器会在响应中复制这个字段,以便客户端识别对应的请求
  2. Protocol Identifier(协议标识符)
    • 长度: 2字节
    • 用于标识使用的协议。Modbus协议的值为0
  3. Length(长度)
    • 长度: 2字节
    • 表示MBAP头之后数据的长度(包括Unit Identifier和PDU)。用于确定数据帧的结束
  4. Unit Identifier(单元标识符)
    • 长度: 1字节
    • 用于在多设备通信环境中标识具体设备。在简单的单设备网络中,这个值通常为0

MBAP报文头表格

字节偏移量字段名称长度(字节)描述
0-1Transaction Identifier2事务标识符,用于匹配请求和响应
2-3Protocol Identifier2协议标识符,0表示Modbus协议
4-5Length2剩余长度,表示MBAP头之后数据的长度(包括Unit Identifier和PDU)
6Unit Identifier1单元标识符,用于多设备通信环境中标识具体设备

Modbus TCP 数据帧示例

以下是一个示例Modbus TCP数据帧:

字节偏移量字段名称示例值(十六进制)描述
0-1Transaction Identifier0x00 0x01事务标识符,客户端生成,表示第一个事务
2-3Protocol Identifier0x00 0x00协议标识符,0表示Modbus协议
4-5Length0x00 0x06剩余长度,表示MBAP头之后的6个字节数据(包括Unit Identifier和PDU)
6Unit Identifier0x01单元标识符,表示设备地址
7Function Code0x03功能码,0x03表示读取保持寄存器
8-9Starting Address0x00 0x00起始地址,读取地址从0开始
10-11Quantity of Registers0x00 0x01寄存器数量,读取一个寄存器

这个示例表示一个读取保持寄存器的请求,从地址0开始,读取一个寄存器

结构图

+------------------------+----------------+----------+-------------+----------+----------+
| 事务处理标识符 (2) | 协议标识符 (2) | 长度 (2) | 单元标识符 (1) | 功能码 (1) | 数据 (N) |
+------------------------+----------------+----------+-------------+----------+----------+

实现步骤:

  1. 主设备构建请求帧,包含事务处理标识符、协议标识符、长度域、单元标识符、功能码和数据
  2. 通过TCP/IP网络发送请求帧
  3. 从设备接收请求帧,解析并执行请求
  4. 从设备构建响应帧,包含事务处理标识符、协议标识符、长度域、单元标识符、功能码和数据
  5. 从设备发送响应帧,主设备接收并处理响应

4. Modbus Plus (Modbus+)

特点:使用令牌传递机制的高性能网络协议,支持多主站和高速通信 应用:常用于工业自动化环境中的PLC和其他控制设备 传输介质:使用屏蔽双绞线进行通信,支持长距离传输和高数据速率

帧结构:

  • 起始字节:标识帧的开始
  • 目标地址:标识目标设备
  • 源地址:标识发送设备
  • 功能码:表示请求的操作类型
  • 数据:根据功能码决定内容
  • 校验码:用于错误检测
+-------------+-------------+------------+-----------+----------+--------+
| 起始符 (1) | 目标地址 (1) | 源地址 (1) | 功能码 (1) | 数据 (N) | CRC (2) |
+-------------+-------------+------------+-----------+----------+--------+

实现步骤:

  1. 主设备通过令牌传递机制获得发送权
  2. 主设备构建请求帧,包含起始字节、目标地址、源地址、功能码、数据和校验码
  3. 通过屏蔽双绞线发送请求帧
  4. 从设备接收请求帧,验证校验码,解析并执行请求
  5. 从设备构建响应帧,包含起始字节、目标地址、源地址、功能码、数据和校验码
  6. 从设备发送响应帧,主设备接收并验证校验码

4.Modbus的功能码

1.功能码汇总

功能码描述请求数据字段响应数据字段示例操作
01读线圈状态起始地址 (2字节)
读取数量 (2字节)字节计数 (1字节)
线圈状态 (N字节)读取指定地址范围的线圈状态
02读离散输入起始地址 (2字节)
读取数量 (2字节)字节计数 (1字节)
输入状态 (N字节)读取指定地址范围的离散输入状态
03读保持寄存器起始地址 (2字节)
读取数量 (2字节)字节计数 (1字节)
数据 (N字节)读取指定地址范围的保持寄存器值
04读输入寄存器起始地址 (2字节)
读取数量 (2字节)字节计数 (1字节)
数据 (N字节)读取指定地址范围的输入寄存器值
05写单个线圈地址 (2字节)
状态 (2字节)地址 (2字节)
状态 (2字节)将指定地址的单个线圈状态设置为开或关
06写单个保持寄存器地址 (2字节)
值 (2字节)地址 (2字节)
值 (2字节)将指定地址的单个保持寄存器的值设置为给定值
15写多个线圈起始地址 (2字节)
写入数量 (2字节)
字节计数 (1字节)
线圈状态 (N字节)起始地址 (2字节)
写入数量 (2字节)将指定地址范围内的多个线圈状态设置为开或关
16写多个保持寄存器起始地址 (2字节)
写入数量 (2字节)
字节计数 (1字节)
数据 (N字节)起始地址 (2字节)
写入数量 (2字节)将指定地址范围内的多个保持寄存器的值设置为给定值
17强制单个线圈状态地址 (2字节)
状态 (2字节)地址 (2字节)
状态 (2字节)强制将指定线圈设置为开或关状态(仅适用于某些设备)
18强制多个线圈状态起始地址 (2字节)
写入数量 (2字节)
字节计数 (1字节)
线圈状态 (N字节)起始地址 (2字节)
写入数量 (2字节)强制将指定地址范围内的多个线圈状态设置为开或关(仅适用于某些设备)
23读/写多个寄存器读寄存器地址 (2字节)
读寄存器数量 (2字节)
写寄存器地址 (2字节)
写寄存器数量 (2字节)
写数据 (N字节)读数据 (N字节)读取和写入指定寄存器的数据

2.功能码实现图示

读线圈状态 (01)

+-------------+------------+----------+---------+
| 设备地址   | 功能码     | 数据     | CRC     |
| (1字节)     | (1字节)   | (N字节)   | (2字节) |
+-------------+------------+----------+---------+

读离散输入 (02)

+-------------+------------+----------+---------+
| 设备地址   | 功能码     | 数据     | CRC     |
| (1字节)     | (1字节)   | (N字节)   | (2字节) |
+-------------+------------+----------+---------+

读保持寄存器 (03)

+-------------+------------+----------+---------+
| 设备地址   | 功能码     | 数据     | CRC     |
| (1字节)     | (1字节)   | (N字节)   | (2字节)

5.Modbus-CRC校验

1.CRC校验概述

CRC(循环冗余校验)是一种用于检测数据传输错误的算法。它通过将数据与生成多项式进行数学运算来生成一个短的、固定长度的校验码(CRC码),用于确保数据在传输过程中没有发生错误

2.CRC校验流程

  1. 选择生成多项式(Polynomial):
    • 选择一个适当的生成多项式来进行CRC计算。常见的生成多项式包括 CRC-16、CRC-32 等(Modbus RTU中使用的生成多项式为 0x8005(CRC-16-CCITT))
  2. 初始化CRC寄存器:
    • 将CRC寄存器初始化为一个预设值。对于Modbus RTU,CRC寄存器通常初始化为 0xFFFF
  3. 逐位处理数据:
    • 将待检数据的每一位从数据帧的第一个字节到最后一个字节逐位处理,并与CRC寄存器中的值进行异或运算
  4. 进行多项式除法运算:
    • 每次将CRC寄存器的最高位与生成多项式进行异或运算,移位处理以完成多项式除法的计算
    • 当最高位为1时,执行CRC多项式的除法运算(即CRC寄存器异或生成多项式),然后左移一位
  5. 继续处理数据位:
    • 对数据中的每一位进行相同的操作,直到所有数据位都处理完成
  6. 完成CRC计算:
    • 将CRC寄存器中的值作为校验码附加到数据帧中

3.CRC计算实例详解

1. 选择生成多项式

选择一个生成多项式 0x8005(即 x^16 + x^15 + x^2 + 1)

2. 初始化CRC寄存器

初始化CRC寄存器为0xFFFF

3. 逐字节处理数据

对于每一个字节的数据:

  • 将数据字节与CRC寄存器的当前值进行异或
  • 对字节进行逐位处理,逐步移位,并根据最高位的值决定是否进行异或操作

4. 处理示例数据

计算数据 0x01, 0x03, 0x00, 0x00, 0x00, 0x01 的CRC

  1. 初始化CRC寄存器:CRC = 0xFFFF
  2. 第一个字节 0x01
    • 0x01 与 CRC 寄存器的高位进行异或
    • 进行多项式除法运算
    • 结果更新CRC寄存器的值
  3. 继续处理每个字节
    • 将下一个字节与CRC寄存器进行异或,并重复步骤2中的运算
  4. 处理完所有数据字节
    • 完成计算后,CRC寄存器中的值即为CRC校验码

5. CRC校验码示例计算

计算完成后,CRC值为 0x4B37。在Modbus RTU中,这个值会附加在数据帧的末尾进行传输。

CRC计算流程图

以下是CRC计算流程图的简化表示:

+-------------------------+
| 初始化 CRC 值为 0xFFFF |
+-----------+-------------+
|
v
+-----------+-------------+
| 对于数据块中的每一个字节 |
+-----------+-------------+
|
v
+-----------+-------------+
| 将当前字节与 CRC 当前值进行异或 |
+-----------+-------------+
|
v
+-----------+-------------+
| 对于每一个比特(0 到 7) |
+-----------+-------------+
|
v
+-----------+-------------+
| 检查 CRC 的最低有效位 (LSB) |
| 如果 LSB 为 1 |
| 将 CRC 右移一位 |
| CRC 与多项式进行异或 |
| 否则 |
| 仅将 CRC 右移一位 |
+-----------+-------------+
|
v
+-----------+-------------+
| 处理下一个字节 |
+-----------+-------------+
|
v
+-----------+-------------+
| 完成所有字节后 |
| 将 CRC 的高低字节交换 |
+-----------+-------------+
|
v
+-----------+-------------+
| 输出 CRC 值 |
+-------------------------+

CRC校验算法伪代码

以下是CRC校验算法的伪代码,展示了如何对每个字节的数据进行CRC计算:

Function CRC16(data):
CRC = 0xFFFF // 初始化CRC寄存器
For each byte in data:
CRC = CRC XOR byte // 与数据字节异或
For 8 bits:
If (CRC & 0x8000) == 0x8000:
CRC = (CRC << 1) XOR 0x8005 // 进行多项式除法
Else:
CRC = CRC << 1 // 左移一位
Return CRC

CRC校验实用工具

  • CRC计算器:在线CRC计算工具可以帮助验证CRC计算的正确性
  • CRC算法代码:常用编程语言中的CRC计算代码示例:
    • Python: crc16 = crcmod.predefined.Crc('xmodem')
    • C/C++: uint16_t crc16(uint16_t crc, const uint8_t \*buf, size_t len)

常见的CRC多项式

CRC类型生成多项式 (Hex)生成多项式 (Binary)描述
CRC-160x80051000 0000 0000 0101常用在Modbus RTU中
CRC-16-CCITT0x110210001 0001 0000 0010 0001标准CRC-16多项式
CRC-320x04C11DB70000 0100 1100 0001 0001 1101 1011 0111常用于网络传输,如ZIP文件
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇