1. Modbus RTU 入门:10分钟实现基础读写
1.1 环境准备与硬件连接
在开始编写代码前,我们需要准备好硬件环境。典型的Modbus RTU系统需要:
- 一台支持RS485接口的工业设备(如PLC、传感器)
- USB转RS485转换器(推荐使用FTDI芯片的稳定型号)
- 双绞线缆(建议使用带屏蔽层的工业级线缆)
接线时需特别注意:
- A线(通常标为D+或T+/R+)接设备A端
- B线(通常标为D-或T-/R-)接设备B端
- 务必确保终端电阻设置正确(长距离通信时需要)
实际项目中,我曾遇到因接线反导致通信失败的情况。用万用表测量A-B间电压,正常应在-2V到+2V间波动,如果始终为0或固定值,很可能接线有误。
1.2 核心代码解析
让我们拆解这个最简实现的关键部分:
csharp复制using System;
using System.IO.Ports;
class Program
{
static void Main()
{
// 串口配置(需根据实际设备调整)
using var serial = new SerialPort("COM3", 9600, Parity.None, 8, StopBits.One);
serial.Open();
byte slaveId = 1; // 从站地址
参数选择背后的考量:
- 波特率9600是工业常见值,实际可根据设备支持选择(19200、38400等)
- 无校验(Parity.None)是Modbus RTU常见配置,也可用偶校验(Parity.Even)
- 数据位8、停止位1是标准配置
- 从站地址需要与设备配置一致,默认1,范围1-247
1.3 寄存器读取实现
读取保持寄存器的核心逻辑:
csharp复制// 构建读保持寄存器请求帧
byte[] request = BuildReadHoldingRequest(slaveId, 0, 4);
serial.Write(request, 0, request.Length);
// 接收响应(注意缓冲区大小)
byte[] response = new byte[9];
serial.Read(response, 0, response.Length);
// CRC校验(工业通信必备)
ushort calcCrc = Crc16Modbus(response, 0, response.Length - 2);
ushort recvCrc = (ushort)((response[^1] << 8) | response[^2]);
if (calcCrc != recvCrc) throw new Exception("CRC校验失败");
// 解析数据(大端序)
for (int i = 0; i < 4; i++) {
ushort value = (ushort)((response[3 + i*2] << 8) | response[4 + i*2]);
Console.WriteLine($"
