2. Modbus协议基础:Modbus RTU vs TCP、功能码详解(01-06)、数据模型(线圈、寄存器)
好,咱们今天聊聊Modbus协议的基础。说实话,这玩意儿在工业现场太常见了。我刚开始做自动化那会儿,觉得协议这东西很神秘,后来发现Modbus其实挺朴实的。说白了,它就是一套让设备之间能「好好说话」的规则。
2.1 Modbus RTU vs TCP:两种最常见的「方言」
Modbus协议有两种主流实现方式:RTU和TCP。你想想看,一个走串口,一个走以太网,本质区别就在物理层。
| 对比项 | Modbus RTU | Modbus TCP |
|---|---|---|
| 物理层 | RS-232 / RS-485 | 以太网(TCP/IP) |
| 传输方式 | 串行,半双工 | 网络,全双工 |
| 地址范围 | 1-247(从站地址) | 无从站地址,用IP区分 |
| 校验方式 | CRC16(必须) | TCP/IP协议栈自带校验 |
| 典型距离 | 几十米到上千米(RS-485) | 100米(网线),可扩展 |
| 实时性 | 较高(无协议栈开销) | 受网络延迟影响 |
我个人习惯,在距离短、设备少的场景用RTU。比如一个控制柜里,PLC和变频器通信,用RS-485走RTU,稳定又便宜。但如果是跨车间、跨厂区,或者需要和上位机、数据库对接,那TCP是首选。
2.2 功能码详解(01-06):PLC的「指令集」
功能码就是Modbus的指令。主站发一个功能码,从站就知道要干什么。常用的01到06,我一个个说。
功能码01:读取线圈状态
读的是DO(数字量输出)或线圈。比如你PLC控制了一个继电器,上位机想知道继电器现在是通还是断,就用01功能码。
请求:01 01 00 00 00 0A BC 0D
解释:从站地址1,功能码01,起始地址0x0000,读取10个线圈
功能码02:读取离散输入
读的是DI(数字量输入)。比如一个按钮按下了没有,或者一个限位开关触发了没有。这个功能码只能读,不能写。
功能码03:读取保持寄存器
这个最常用。保持寄存器可以读也可以写,一般存模拟量数据,比如温度、压力、频率设定值。
请求:01 03 00 00 00 02 C4 0B
响应:01 03 04 00 0A 00 14 7A 5F
解释:读取地址0x0000开始的2个寄存器,返回0x000A(10)和0x0014(20)
功能码04:读取输入寄存器
读的是AI(模拟量输入)。比如一个4-20mA的传感器,读回来的原始值。这个只能读,不能写。
功能码05:写单个线圈
控制一个DO点。比如让一个继电器吸合或断开。
请求:01 05 00 00 FF 00 8C 3A
解释:写线圈地址0x0000为ON(0xFF00表示ON,0x0000表示OFF)
功能码06:写单个寄存器
设置一个保持寄存器的值。比如修改变频器的频率设定值。
请求:01 06 00 00 03 E8 48 0A
解释:写寄存器地址0x0000,值为0x03E8(1000)
2.3 数据模型:线圈、寄存器,到底是个啥?
Modbus的数据模型分四种,我画个图你就明白了。
说白了,线圈就是开关量输出,离散输入就是开关量输入。寄存器呢,存的是16位的数值,保持寄存器可以读写,输入寄存器只能读。
- 线圈和离散输入:1位(0或1),对应开关量
- 保持寄存器和输入寄存器:16位(0-65535),对应模拟量
- 每个数据对象都有唯一的地址,从0开始编号
- 同一个物理设备,可以同时支持多种数据模型
我记得有一次调试一个温控器,它把温度值放在保持寄存器里,但把报警状态放在线圈里。当时我光顾着读寄存器,忘了读线圈,结果温度数据拿到了,报警状态一直没更新。嗯,这就是对数据模型理解不够透彻的表现。
你想想看,Modbus协议其实不复杂。它就是把工业现场最常见的四种数据类型——DO、DI、AO、AI——用一套统一的指令封装起来。不管你是PLC、变频器、温控器还是智能仪表,只要支持Modbus,大家就能用同一套「语言」对话。
好了,这一节就到这里。记住:RTU适合短距离、低成本场景;TCP适合网络化、跨平台场景。功能码01-06是基本功,必须烂熟于心。数据模型是Modbus的骨架,理解了它,你就掌握了Modbus的精髓。