当前位置: 首页 > news >正文

网络编程(5)Modbus

【1】Modbus

1. 起源

  • Modbus由Modicon公司于1979年开发,是全球第一个真正用于工业现场的总线协议
  • 在中国,Modbus 已经成为国家标准,并有专业的规范文档,感兴趣的可以去查阅相关的文件,详情如下:标准编号为:GB/T19582-2008文件名称:《基于 Modbus 协议的工业自动化网络规范》
  • Modbus通信协议具有多个变种,其中有支持串口,以太网多个版本,其中最著名的是Modbus RTU、Modbus ASCII和Modbus TCP三种,其中Modbus TCP是在施耐德收购Modicon后1997年发布的。

2. 分类

1)Modbus RTU

运行在串口上的协议,采用二进制表现形式以及紧凑的数据结构,通信效率较高,应用比较广泛

2)Modbus ASCII

运行在串口上的协议,采用ASCII码进行传输,并且每个字节的开始和结束都有特殊字符作为标志,传输效率远远低于Modbus RTU,一般只有通讯量比较少时才会考虑它。

3)Modbus TCP

是一种基于以太网的协议,使用 TCP/IP 协议栈进行通信。它使用以太网帧作为数据传输的封装,通过 IP 地址和端口号来标识设备

3. 优势

简单、免费、容易使用

4. 应用场景

Modbus协议是现在国内工业领域应用最多的协议,不只PLC设备,各种终端设备,比如水控机、水表、电表、工业秤、各种采集设备

问答

在面试中回答“Modbus 协议”相关问题时,可从协议定位、核心架构、传输方式、通信流程、实际应用、技术价值等维度组织内容,既体现全面性,又贴合工业/嵌入式场景:

一、协议定位与核心价值

Modbus 是工业自动化领域应用广泛的开源通信协议,旨在解决工业现场不同设备(PLC、传感器、执行器、网关等)间的“数据互通与指令协同”问题,让分散的设备能像“统一系统”一样工作,是工业物联网(IIoT)底层设备互联的核心协议之一。

二、核心架构:主从式通信

采用“一主多从”的主从架构:

  • 主设备(如 PLC、工业网关、上位机)主动发起通信请求;
  • 从设备(如温湿度传感器、电机驱动器、阀门控制器)仅响应主设备的请求,不主动发起通信。

这种架构简化了通信冲突处理,适合工业现场“中心控制+分散设备”的管理模式。

三、主流传输版本与差异

Modbus 针对不同“传输介质”衍生出 3 类核心版本,适配从“串口总线”到“以太网”的场景:

1. Modbus RTU(串行总线,如 RS - 485/RS - 232)

  • 数据格式:二进制紧凑传输,每个字节为 8 位,用 CRC(循环冗余校验) 保证数据完整性;

详述循环冗余校验CRC

一道题带你搞懂CRC循环冗余校验是如何纠错的

  • 传输效率:适合长距离、低带宽的工业现场(如车间产线设备互联),但通信速率受串口波特率限制(常见 9600bps、19200bps);
  • 典型场景:工厂产线的传感器(温湿度、压力)与 PLC 通信,单主设备可带最多 247 个从设备。

2. Modbus ASCII(串行总线)

  • 数据格式:ASCII 字符传输(每个字节拆为 2 个 ASCII 字符),用 LRC(纵向冗余校验)
  • 特点:可读性强(便于串口调试工具抓包分析),但传输效率低于 RTU(相同数据,ASCII 长度是 RTU 的 2 倍),多用于对“调试友好性”要求高的场景(如实验室设备联调)。

3. Modbus TCP(以太网)

  • 传输层:基于 TCP/IP 协议,把 Modbus 应用数据封装在 TCP 数据包中传输;
  • 特点:突破串口“距离与速率”限制,支持跨网络、高速通信(千兆以太网下可近实时传输);
  • 典型场景:工业物联网云平台与边缘网关通信、智能工厂多车间设备的跨区域集中管理。

四、通信流程(以“主设备读从设备数据”为例)

以 Modbus RTU 为例,核心流程分“请求 - 响应 - 错误处理”:

  1. 主设备请求:主设备发送“请求帧”,包含: 从设备地址(指定和哪个从设备通信);
    1. 功能码(如 0x03 表示“读保持寄存器”,0x01 表示“读线圈状态”);
    2. 数据地址(要读的寄存器/线圈起始地址);
    3. 数据长度(读多少个寄存器/线圈);
    4. CRC 校验(确保帧传输无错)。
  2. 从设备响应:从设备收到请求后,先校验地址和 CRC: 若匹配且能执行操作,返回“响应帧”:包含从设备地址、功能码、实际读取的数据、CRC 校验;
    1. 若出错(如地址不存在、功能不支持),返回“异常响应帧”:功能码最高位设为 1(表示异常),并附带“异常码”(说明错误原因,如 0x01 表示“不支持的功能码”)。
  3. 错误处理:主设备收到异常响应后,可根据异常码重试、切换从设备或报警。

五、在工业/嵌入式场景的典型应用

Modbus 是工业设备互联的“通用语言”,典型应用场景包括:

  • 设备数据采集:PLC 通过 Modbus 读取车间温湿度传感器、压力变送器的实时数据,为生产决策(如空调启停、产线速度调整)提供依据;
  • 设备远程控制:上位机通过 Modbus TCP 向边缘网关下发指令,网关再通过 Modbus RTU 控制车间电机转速、阀门开关;
  • 多系统集成:把采用不同通信协议的设备(如老产线的 Modbus 传感器、新系统的 Profinet 执行器)通过“Modbus 网关”桥接,实现跨协议协同。

六、技术优势(为什么工业领域广泛用 Modbus)

  • 开源免费:无授权费用,降低工业企业/嵌入式开发者的使用成本;
  • 易实现:协议格式简单,嵌入式端(如 STM32、Arduino)可通过串口库+CRC 校验库快速开发从设备/主设备;
  • 兼容性强:几乎所有工业设备厂商(西门子、施耐德、国产 PLC 等)都支持 Modbus,不同品牌设备能“即连即用”。

【2】Modbus TCP协议

1. 特点

  • 遵循主从问答协议 (主机 从机 主从问答:采集信息 控制)
  • (主机问---从机答247 1-247:从机 0:广播 248-255:保留 )
  • Modbus TCP协议是应用层协议,基于传输层TCP通信
  • Modbus TCP的默认端口号是502

2. 组成

Modbus TCP协议包含三部分:报文头、功能码、数据

报文头有7个字节,功能码有1个字节,Modbus TCP协议最大数据帧长度为260个字节,数据最多为252个字节。

2.1 报文头:7个字节

事务处理标识符:包的标识,没有什么限制,一般主机发什么从机回什么

协议标识符:0x0000 两个字节

长度:长度后面的字节个数,必须占2个字节

单元标识符:从机地址,从机ID

2.2 寄存器(存储数据) ******

Modbus TCP通过寄存器的方式存储数据。

一共有四种类型的寄存器,分别是:离散量输入寄存器、线圈寄存器、输入寄存器、保持寄存器。

1) 离散量和线圈其实就是位寄存器(每个寄存器数据占1字节),工业上主要用于控制IO设备。

线圈寄存器,类比为开关量,每一个bit都对应一个信号的开关状态。所以一个byte就可以同时控制8路的信号。比如控制外部8路io的高低。 线圈寄存器支持读也支持写,写在功能码里面又分为写单个线圈寄存器和写多个线圈寄存器。

对应的功能码也就是:0x01 0x05 0x0f

离散输入寄存器,离散输入寄存器就相当于线圈寄存器的只读模式,他也是每个bit表示一个开关量,而他的开关量只能读取输入的开关信号,是不能够写的。比如我读取外部按键的按下还是松开。

所以功能码也简单就一个读的 0x02

2) 输入和保持寄存器字寄存器每个寄存器数据占2个字节),工业上主要用于存储工业设备的值。

保持寄存器,这个寄存器的单位不再是bit而是两个byte,也就是可以存放具体的数据量的,并且是可读写的。比如我设置时间年月日,不但可以写也可以读出来现在的时间。写也分为单个写和多个写

所以功能码有对应的三个:0x03 0x06 0x10

输入寄存器,这个和保持寄存器类似,但是也是只支持读而不能写。一个寄存器也是占据两个byte的空间。类比我通过读取输入寄存器获取现在的AD采集值

对应的功能码也就一个 0x04

2.3 功能码(记住)

寄存器PLC地址和寄存器的对应关系:

线圈: 00001-09999

离散量输入:10001-19999

输入寄存器:30001-39999

保持寄存器:40001-49999

开灯:05

读温度传感器数据:03 04

具体协议分析:

总结

数据:

主机--》从机:

报文头(7字节)+功能码(1)+起始地址(2)+数量(2)

从机--》主机:

报文头(7)+功能码(1)+字节计数(1)+数据(?)

写数据:

写单个:

主机--》从机:

报文头(7)+功能码(1)+地址(2)+断通标志/数据(2)

(线圈:断通标志 0x0000:复位 0xff00:置位 保持寄存器:数据)

从机--》主机:

原文返回

对于读数据和写单个主机--》从机来说,报文头中字节长度固定为0x0006,(1个字节的单元标识符+1个字节的功能码+4个字节的数据)

多个:

主机--》从机:

报文头(7)功能码(2)+起始地址(2)+数量(2)+字节计数(1)+数据(?)

从机--》主机:

报文头(7)功能码(2)+起始地址(2)+数量(2)(原文返回)

练习

主机--》从机:

12 34 00 00 00 06 01 03 00 63 00 03

从机--》主机:

12 34 00 00 00 09 01 03 06 45 69 11 11 66 66

1.读传感器数据,读1个寄存器数据,写出主从数据收发协议。

主机--》从机:12 34 00 00 00 06 11 03 00 01 00 01

从机--》主机:12 34 00 00 00 05 11 03 02 12 34

2. 写出控制IO设备开关的协议数据,操作1个线圈,置1。

主机--》从机:12 34 00 00 00 06 01 05 00 63 ff 00

从机--》主机:12 34 00 00 00 06 01 05 00 63 ff 00

【3】工具使用

1.Modbus Slave、Poll安装

1)默认安装

2)破解:点击connection-》connect,输入序列号(序列号在SN.txt)

3)使用:

从机:Modbus Slave

先设置:

再连接:点击connection-》connect

主机:

先设置

再连接:(一定要先开启从机(salve端),再开启主机(poll端))

2. 网络调试助手

linux下编程

在虚拟机写程序实现poll端功能,编写客户端实现和Slave通信,实现03功能码。

uint8_t data[12]={0x00,0x00,0x00,0x00,0x00,0x06,0x01....};

主机要先建立连接---》发送协议(modbus tcp协议)---》接收数据(modbus tcp协议)--》打印数据

1. 功能码0x01(读线圈状态)

示例1:读取地址0x0000的两个线圈

主机->从机:00 01 00 00 00 06 01 01 00 00 00 02 
从机->主机:00 01 00 00 00 04 01 01 01 03 
# 解析:线圈0状态为1(ON),线圈1状态为1(ON),其余线圈状态无效

示例2:读取地址0x0003的四个线圈

主机->从机:00 02 00 00 00 06 01 01 00 03 00 04 
从机->主机:00 02 00 00 00 04 01 01 01 0F 
# 解析:二进制0F转换为十进制为15,即00001111,线圈3至6状态为1(ON)(有效位为1)

2. 功能码0x02(读离散输入)

示例1:读取地址0x0001的三个离散输入

主机->从机:00 03 00 00 00 06 01 02 00 01 00 03 
从机->主机:00 03 00 00 00 04 01 02 01 05 
# 解析:二进制05转换为十进制为5,即00000101,输入1状态为1(ON),输入3状态为1(ON)

示例2:读取地址0x0005的两个离散输入

主机->从机:00 04 00 00 00 06 01 02 00 05 00 02 
从机->主机:00 04 00 00 00 04 01 02 01 01 
# 解析:二进制01转换为十进制为1,即00000001,仅输入5状态为1(ON)

3. 功能码0x03(读保持寄存器)

示例1:读取地址0x0002的两个保持寄存器

主机->从机:00 05 00 00 00 06 01 03 00 02 00 02 
从机->主机:00 05 00 00 00 07 01 03 04 12 34 56 78 
# 解析:寄存器2的值为0x1234,寄存器3的值为0x5678

示例2:读取地址0x000A的一个保持寄存器

主机->从机:00 06 00 00 00 06 01 03 00 0A 00 01 
从机->主机:00 06 00 00 00 05 01 03 02 FF FF 
# 解析:寄存器10的值为0xFFFF(典型错误状态码)

4. 功能码0x04(读输入寄存器)

示例1:读取地址0x0000的三个输入寄存器

主机->从机:00 07 00 00 00 06 01 04 00 00 00 03 
从机->主机:00 07 00 00 00 09 01 04 06 00 64 01 F4 FF FF 
# 解析:寄存器0的值为100(0x0064),寄存器1的值为500(0x01F4),寄存器2的值为65535(0xFFFF)

示例2:读取地址0x0005的两个输入寄存器

主机->从机:00 08 00 00 00 06 01 04 00 05 00 02 
从机->主机:00 08 00 00 00 07 01 04 04 80 00 40 00 
# 解析:寄存器5的值为32768(0x8000),寄存器6的值为16384(0x4000)

5. 功能码0x05(写单个线圈)

示例1:开启地址0x0063的线圈

主机->从机:00 09 00 00 00 06 01 05 00 63 FF 00 
从机->主机:00 09 00 00 00 06 01 05 00 63 FF 00 
# 说明:0xFF00表示置ON,成功时返回相同数据

示例2:关闭地址0x001A的线圈

主机->从机:00 0A 00 00 00 06 01 05 00 1A 00 00 
从机->主机:00 0A 00 00 00 06 01 05 00 1A 00 00 
# 说明:0x0000表示置OFF

6. 功能码0x06(写单个寄存器)

示例1:写地址0x0003的寄存器值为0x55AA

主机->从机:00 0B 00 00 00 06 01 06 00 03 55 AA 
从机->主机:00 0B 00 00 00 06 01 06 00 03 55 AA 
# 成功时回显写入值

示例2:写地址0x0010的寄存器值为0x1234

主机->从机:00 0C 00 00 00 06 01 06 00 10 12 34 
从机->主机:00 0C 00 00 00 06 01 06 00 10 12 34 

7. 功能码0x0F(写多个线圈)

示例1:写地址0x0010的3个线圈为ON

主机->从机:00 0D 00 00 00 08 01 0F 00 10 00 03 01 07 
从机->主机:00 0D 00 00 00 06 01 0F 00 10 00 03 
# 解析:二进制07转换为十进制为7,即00000111,线圈16至18置ON
​​​​​​​

示例2:写地址0x0020的5个线圈(二进制10101)

主机->从机:00 0E 00 00 00 08 01 0F 00 20 00 05 01 15 
从机->主机:00 0E 00 00 00 06 01 0F 00 20 00 05 
# 解析:二进制15转换为十进制为15,即00010101,仅偶数位生效(线圈32、34、36置ON)

8. 功能码0x10(写多个寄存器)

示例1:写地址0x0004的2个寄存器(值0xAABB和0xCCDD)

主机->从机:00 0F 00 00 00 0B 01 10 00 04 00 02 04 AA BB CC DD 
从机->主机:00 0F 00 00 00 06 01 10 00 04 00 02 
# 数据部分以四字节表示两个寄存器的值

示例2:写地址0x0010的三个寄存器(十进制值100、200、300)

主机->从机:00 10 00 00 00 0D 01 10 00 10 00 03 06 00 64 00 C8 01 2C 
从机->主机:00 10 00 00 00 06 01 10 00 10 00 03 
# 数值转换:100转换为十六进制为0x0064,200转换为十六进制为0x00C8,300转换为十六进制为0x012C


文章转载自:

http://vh1TrbCn.xkjrq.cn
http://917oEpk9.xkjrq.cn
http://cQROY9EC.xkjrq.cn
http://JGaqIaSU.xkjrq.cn
http://dFqRqGpL.xkjrq.cn
http://xtgJuUNN.xkjrq.cn
http://55roSraD.xkjrq.cn
http://okGMYCbJ.xkjrq.cn
http://YS01Y2pF.xkjrq.cn
http://s8HH7Hw2.xkjrq.cn
http://w7BoqpSw.xkjrq.cn
http://MBtbwVXR.xkjrq.cn
http://zMrEwmqC.xkjrq.cn
http://aqnSPLvb.xkjrq.cn
http://PiGHPCTk.xkjrq.cn
http://X2abMdEo.xkjrq.cn
http://qIrotbQY.xkjrq.cn
http://pcVYAN2v.xkjrq.cn
http://4fu9uY65.xkjrq.cn
http://5VXBlXPc.xkjrq.cn
http://7jp4jUYQ.xkjrq.cn
http://NkDM3Evh.xkjrq.cn
http://M7L6zThl.xkjrq.cn
http://qKDLNnM2.xkjrq.cn
http://OdvLhSK4.xkjrq.cn
http://9NHDl9Gi.xkjrq.cn
http://Eq7GfG8Y.xkjrq.cn
http://KqRWd8OP.xkjrq.cn
http://a4r1l0d3.xkjrq.cn
http://94h89o2G.xkjrq.cn
http://www.dtcms.com/a/370403.html

相关文章:

  • 蓓韵安禧DHA纯植物藻油纯净安全零添加守护母婴健康
  • SAP二次开发指南:个性化与稳定性的平衡技巧
  • MAZANOKE与cpolar:打造安全可控的照片云端管理系统
  • 【YOLOv11】2.安装Anaconda3
  • Modbus通信的大端和小端字节序
  • 音视频技术全景:从采集到低延迟播放的完整链路解析
  • Playwright携手MCP:AI智能体实现自主化UI回归测试
  • 【目录-多选】鸿蒙HarmonyOS开发者基础
  • Qt UDP通信学习
  • Linux知识回顾总结----文件系统
  • 【完整源码+数据集+部署教程】农作物病害检测系统源码和数据集:改进yolo11-HSFPN
  • 计算机网络:调制解调器
  • solidity函数篇2
  • 【AI论文】ELV-Halluc:长视频理解中语义聚合幻觉的基准测评
  • v0.29.2 敏感词性能优化之基本类型拆箱、装箱的进一步优化的尝试
  • 提示词工程(Prompt Engineering)的崛起——为什么“会写Prompt”成了新技能?
  • 前端入门——案例一:登录界面设计(html+css+js)
  • MySQL的组复制(MGR)高可用集群搭建
  • 前端开发学习路径
  • JVM调优总结
  • 大模型API设计:如何用OpenAI兼容接口封装自定义模型?
  • 四个关于云属性的四个卫星数据集的介绍
  • WIN10+ubuntu22.04.05双系统装机教程
  • MCAP :机器人数据容器的全面实践指南
  • Pandas基础(安装、导入Pandas、读取数据、查看数据)
  • 【第四章:大模型(LLM)】10.微调方法与实战-(7)项目实战1:Llama3使用LoRA微调中文增强大模型
  • 没有深度学习
  • Redis-主从复制-哨兵模式
  • PPTist,一个完全免费的 AI 生成 PPT 在线网站
  • [水果目标检测5]AppleYOLO:基于深度OC-SORT的改进YOLOv8苹果产量估计方法