Modbus是什么
Modbus是一种串行通信协议,由Modicon公司(现为施耐德电气)于1979年开发,主要用于工业自动化系统中连接电子设备(如PLC、传感器、仪表等)。它因其简单性、开放性和易用性成为工业领域应用最广泛的通信协议之一。简单来说就是一种应用层协议,它定义了发送数据的格式和应答的机制,它可以基于串口(232或者485)发送出去,也可以基于网络(TCP)发送出去。
Moubus怎么学
modbus协议很简单,发展了那么多年,已经固化了,也没有太多可以研究的,简单学习掌握一下就行,作为开发的话,使用也很简单,前辈们造了很多轮子,我们只需要用就行了,多余的时间用在更加重要的事情或者复杂的知识点就行了,C/C++的话就用libmodbus,python就用modbus_tk。做了这么多年了,我还没用到过Modbus TCP,所以掌握Modbus RTU就够用了,我个人觉得,如果使用了TCP网络了,那直接上http或者mqtt这些上层协议不是更加灵活和方便吗,还使用Modbus TCP干嘛。Modbus TCP感觉就是维护存量的设备。
Modbus特性
- 主从架构(Master-Slave)
- 仅允许一个主设备(Master)发起请求,多个从设备(Slave)响应。
- 从设备地址范围:1-247(地址0用于广播)。
- 数据传输格式
- Modbus RTU:基于二进制传输,效率高,适用于RS-485/RS-232物理层。
- Modbus ASCII:基于ASCII字符传输,可读性强,效率较低。
- Modbus TCP:基于TCP/IP协议,适用于以太网,封装为TCP报文(默认端口502)。
- 开放标准
- 协议规范公开,无版权限制,支持跨厂商设备互联。
Modbus协议结构
- 数据帧格式(以Modbus RTU为例)
- 地址域:1字节,标识从设备地址。
- 功能码:1字节,定义操作类型(读/写)。
- 数据域:可变长度,包含寄存器地址、数据值等。
- 错误校验:2字节CRC校验(RTU)或LRC校验(ASCII)。
- Modbus寄存器类型
寄存器类型 | 地址范围 | 访问权限 | 功能说明 |
---|---|---|---|
线圈(Coils) | 0xxxx | 读/写 | 布尔量(如开关状态) |
离散输入(Inputs) | 1xxxx | 只读 | 布尔量(如传感器输入) |
保持寄存器(Holding) | 4xxxx | 读/写 | 16位整数或浮点数 |
输入寄存器(Input) | 3xxxx | 只读 | 16位整数或浮点数 |
- 常用功能码
功能码 | 操作类型 | 说明 |
---|---|---|
01 | 读线圈 | 读取多个线圈状态(0x0000-0xFFFF) |
02 | 读离散输入 | 读取多个离散输入状态 |
03 | 读保持寄存器 | 读取多个保持寄存器的值 |
04 | 读输入寄存器 | 读取多个输入寄存器的值 |
05 | 写单个线圈 | 设置单个线圈状态(ON/OFF) |
06 | 写单个保持寄存器 | 写入单个保持寄存器的值 |
15 | 写多个线圈 | 批量设置线圈状态 |
16 | 写多个保持寄存器 | 批量写入保持寄存器的值 |
Modbus RTU 报文速查表(主站→从站),假设从站地址为0x01。
功能码 | 操作类型 | 请求报文(Hex) | 响应报文(Hex) | 关键说明 |
---|---|---|---|---|
01 | 读线圈 | 01 01 00 00 00 0A BD CC | 01 01 02 55 01 4D 8F | 读地址0x0000开始的10(0A)个线圈,响应2字节(0x55=01010101,0x01=00000001) |
02 | 读离散输入 | 01 02 00 00 00 08 B9 F9 | 01 02 01 0F 60 4D | 读地址0x0000的8个离散输入,响应1字节(0x0F=00001111) |
03 | 读保持寄存器 | 01 03 00 6B 00 03 76 87 | 01 03 06 12 34 56 78 9A BC 05 6F | 读地址0x006B开始的3个寄存器,返回3个16位值(0x1234, 0x5678, 0x9ABC) |
04 | 读输入寄存器 | 01 04 00 00 00 02 70 0B | 01 04 04 00 FF 01 00 10 3A | 读地址0x0000的2个输入寄存器,返回2个值(0x00FF, 0x0100) |
05 | 写单个线圈 | 01 05 00 03 FF 00 7C 3A | 01 05 00 03 FF 00 7C 3A | 写地址0x0003的线圈为ON(FF00=ON),响应与请求一致 |
06 | 写单个保持寄存器 | 01 06 00 01 00 FF 98 04 | 01 06 00 01 00 FF 98 04 | 写地址0x0001的保持寄存器为0x00FF,响应与请求一致 |
0F | 写多个线圈 | 01 0F 00 00 00 0A 02 55 01 8E 55 | 01 0F 00 00 00 0A 92 05 | 写10个线圈(数据字节0x55=01010101,0x01=00000001) |
10 | 写多个保持寄存器 | 01 10 00 01 00 02 04 00 0A 01 2C 47 0F | 01 10 00 01 00 02 C1 91 | 写地址0x0001的2个寄存器(0x000A, 0x012C) |
异常响应 | (功能码+0x80) | 01 83 02 C0 F1 | 01 83 02 C0 F1 | 功能码0x03读寄存器异常(错误码0x02=地址无效) |
关于我
抖音:嵌入式石小星
csdn:嵌入式石小星
微信公众号:嵌入式石小星