Modbus 存储区 功能码 报文 解析 RTU /TCP
存储区
输出线圈 0区 地址范围 000001--065536 (实际用不到 所以有个短地址) 00001-09999
输入线圈 1区 地址范围 100001--165536 10001-19999
输入寄存器 3区 地址范围 300001--365536 30001-39999
输出寄存器 4区 地址范围 400001--465536 40001-49999
功能码
读取输出线圈 0x01 读线圈状态
读取输入线圈 0x02 读离散输入状态
读取输出寄存器 0x03 (读保持寄存器)
读取输入寄存器 0x04 读输入寄存器
写入单个线圈 0x05 那么只能是 输出线圈
写入单个寄存器 0x06 那么只能是 输出线圈
写入多个线圈 0x0F 那么只能是 输出寄存器
写入多个寄存器 0x10 那么只能是 输出寄存器
ModbusRTU 报文
读
发送 接收(解析)
0x01 01 01 00 00 00 0A BC 0D 01 01 02 00 00 B9 FC 发送: 01--站点, 01--功能码(读输出线圈), 00 00 从哪个地址开始读 ,00 0A 表示读几个,BC 0D CRC校验 接收 01--站点, 01--功能码(输出线圈),02 线圈数量(线圈是布尔所以用 bit表示 02 表示 2*8 16位 实际只有10 bit,可根据 发送的报文 读的个数000A 表示 10个 那么 返回 2个bit)
0x02 01 02 00 05 00 05 A8 08 01 02 01 15 60 47 发送:从 01站点功能码 0x02的输入线圈 中读取 ,起始位 0005 开始读 读00 05 个 就是读5个 A808 CRC校验 返回:01站点 功能码 0x02 ,01表示 1位(8bit 实际还没有8bit 因为只读了5个 所以是5bit ),15返回的结果(转2进制 00010101 前面3位不够0补齐)60 47 校验 和读取输出线圈一样
0x03 01 03 00 0F 00 05 B5 CA 01 03 0A 2A F8 00 00 00 37 00 00 00 04 92 3F 发送: 01--站点, 04--功能码(读输出寄存器), 00 00 从哪个地址开始读 ,00 0A 表示读几个,B5 CA CRC校验 接收:01--站点 03-读输出寄存器 0A 读取字节计数 ,那么中间那段表示10个字节 的数据 也就是前面发送要读5*2个 ,92 3F CRC校验
0x04 01 04 00 0F 00 05 00 0A 01 04 0A 2A F8 00 00 00 37 00 00 00 04 67 F4 和 读取输出性寄存器 一模一样
写 线圈
0x05 01 05 00 00 FF 00 8C 3A 01 05 00 00 FF 00 8C 3A 发送和返回时一样的 01表示站点 05 表示 写单个线圈, 00 00 表示起始地址,FF 00 表示写的数据 1 表示 True ,00 00 表示写 0 false
0x0F 01 0F 00 0A 00 0A 02 25 01 3E C2 01 0F 00 0A 00 0A F5 CE 发送:01--站点, 0F 写多个线圈状态码 ,00 0A 起始地址 10 ,00 0A 表示写的个数10 ,02 表示计数统计 就是 写入2个字节(2个字节),25 01 实际写入数据 转换成二进制 0010 0101 和 0000 0001 这个时候注意要从低位往高位读 1010 0100 1000 0000 在去10 个就是 1010 0100 10 因为写入10位 ,最后校验 3E C2. 返回:前面都一样 只是少了写入数据 在加一个 校验
写寄存器
0x06 01 06 00 00 00 64 88 21 01 06 00 00 00 64 88 21 读写返回的数据时一样的 01--站点。 06--功能码(写单个输出寄存器) 。 00 00 表示 写入的地址。 00 64 表示写入的实际数据 (16进制数)。 88 21 校验
0x10 01 10 00 05 00 06 0C 00 01 00 02 00 03 00 04 00 05 00 06 86 DB 01 10 00 05 00 06 50 0A 发送 :01--站点。10--功能码(写单个输出寄存器) 。00 05 起始地址。00 06 写入个数 。0C 写入字节计数 12个。中间表示具体写入的数据
86 DB校验。 返回: 就是少了具体写入数据 和 换了一个 校验 其余一样
Modbus TCP(和modbus r'tu 的功能码一样)
读 输出线圈 / 输入线圈 (区别就是功能码不一样 01和02 其余都一样)
发送
00 29 00 00 00 06 01 01 00 11 00 11 00 29 交互标识, 00 00 交互协议 ,00 06 后面报文长度 ,01 站点 ,01 功能码(如果是输入线圈就是02),00 11 起始 地址,00 11 线圈个数
(交互标示和交互协议)
返回
00 29 00 00 00 06 01 01 03 CD 00 00 00 29 交互标识, 00 00 交互协议 ,00 06 后面报文长度 ,01 站点 ,01 功能码(如果是输入线圈就是02),03 字节计数(因为17/8=2点几那么就需要3个字节),CD 00 00 (16进制)返回的具体数据 转换成二 进制所对应的就是线圈具体数据
读 输入/输出 寄存器 (就是 功能码不一样 一个04 一个03)
发送
03 39 00 00 00 06 05 03 00 15 00 05 03 39 交互标识 ,00 00交互协议, 00 06 后面报文长度, 05 站点,03功能码, 00 15 起始地址,00 05 读取个数
返回
03 39 00 00 00 0D 05 03 0A 04 4C 00 00 00 00 00 C8 00 00 03 39 交互标识 ,00 00交互协议, 00 0D 后面报文长度, 05 站点,03功能码,0A字节计数,04 4C 00 00 00 00 00 C8 00 00 具体数据 每个2字节 显示一个数据
写单个线圈 / 写多个线圈 功能码 05 / 0F
单个
发送
05 9A 00 00 00 06 05 05 00 0A FF 00 05 9A 交互标识 ,00 00交互协议, 00 06 后面报文长度, 05 站点,05功能码, 00 0A 绝对地址 ,FF 00 (FF 00表示1,00 00 表示0)
返回
05 9A 00 00 00 06 05 05 00 0A FF 00 返回一样的数据
多个
发送
07 F8 00 00 00 09 05 0F 00 08 00 09 02 AD 01 07 F8交互标识,00 00 交互协议,00 09 后面报文长度,05站点,0F功能码,00 08 起始地址,00 09 写入个数,02字节计数,AD 01 具体数据(每个16进制转换2进制 从低位 读高位 就是 具体 0 和1)
返回
07 F8 00 00 00 06 05 0F 00 08 00 09 07 F8交互标识,00 00 交互协议,00 06 后面报文长度,05站点,0F功能码,00 08 起始地址,00 09 写入个数. 返回一样就是 没有具体数据 和 后面报文长度的的变化
写多个寄存器 功能码 10
0B BA 00 00 00 11 05 10 00 06 00 05 0A 00 01 00 02 00 03 00 04 00 05 0B BA交互标识,00 00 交互协议,00 11 后面报文长度,05站点,10功能码,00 06 起始地址,00 05 写入个数,0A 字节计数,具体数据 00 01 00 02 00 03 00 04 00 05
0B BA 00 00 00 06 05 10 00 06 00 05 0B BA交互标识,00 00 交互协议,00 06 后面报文长度,05站点,10功能码,00 06 起始地址,00 05 写入个数
写单个寄存器 (和写多个寄存器一样很少用) 功能码06
0A C9 00 00 00 06 05 06 00 06 00 C8 00 C8 具体数据
0A C9 00 00 00 06 05 06 00 06 00 C8
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南