4. Modbus RTU主站配置:串口参数设置与报文超时重试
好,咱们今天聊聊Modbus RTU主站配置里最基础、也最容易踩坑的两个环节——串口参数和报文超时重试机制。说实话,我见过太多项目因为波特率没对上、超时时间设得太短,导致现场调试折腾好几天。其实说白了,这些参数就是主站和从站之间的“握手暗号”,对不上,啥都白搭。
4.1 串口参数设置:主从双方必须严丝合缝
Modbus RTU走的是RS-485物理层,串口参数必须主从一致。我个人的习惯是,拿到项目先确认从站设备的说明书,把波特率、数据位、校验位、停止位这四个参数记下来,再配置主站。
4.1.1 波特率(Baud Rate)
波特率决定了数据传输的速度。常见的有9600、19200、38400、115200等。数值越大,传输越快,但抗干扰能力会下降。
4.1.2 数据位、校验位、停止位
Modbus RTU固定使用8位数据位。校验位常见三种:无校验(None)、奇校验(Odd)、偶校验(Even)。停止位通常是1位,有时也用2位。
| 参数 | 常见值 | 说明 |
|---|---|---|
| 数据位 | 8 | Modbus RTU强制要求 |
| 校验位 | None / Even / Odd | 多数设备默认Even,建议优先尝试 |
| 停止位 | 1 或 2 | 校验位为None时,停止位需设为2 |
4.2 报文超时与重试机制
串口通信不像TCP有自动重传,Modbus RTU的超时和重试全靠主站自己实现。说白了,就是主站发完请求后,等多久没收到回复就算失败,失败后要不要再试一次。
4.2.1 报文超时时间(Response Timeout)
这个时间怎么设?我一般按这个公式估算:
超时时间 = (报文长度 * 10 / 波特率) * 3.5 + 安全余量
举个例子,波特率9600,报文长度8字节:
超时时间 = (8 * 10 / 9600) * 3.5 ≈ 0.029秒 ≈ 29毫秒
加上安全余量,我通常设100~200毫秒
嗯,这里要注意:如果从站是PLC或变频器,它们的响应时间可能比理论值长很多。我建议实际测试一下,用示波器抓一下从站回复的时间间隔,再调整。
4.2.2 帧间隔时间(Inter-Frame Delay)
Modbus RTU要求报文之间至少间隔3.5个字符时间。这个参数也很关键,设得太短,报文会粘包;设得太长,通信效率低。
帧间隔时间 = (3.5 * 10) / 波特率
例如9600波特率:
帧间隔 = 35 / 9600 ≈ 3.65毫秒
我一般把这个值设为4~5毫秒,留点余量。有些从站对帧间隔很敏感,尤其是老款设备,设短了它就不认。
4.2.3 重试机制(Retry Mechanism)
超时后要不要重试?重试几次?我个人的做法是:
- 重试次数: 通常2~3次。太多会加重总线负担,太少又容易误判故障。
- 重试间隔: 建议比正常超时时间稍长一点,比如超时200ms,重试间隔可以设300ms。
- 重试策略: 我习惯用“线性重试”,每次重试间隔固定。有些场景会用“指数退避”,但Modbus RTU场景下没必要搞那么复杂。
4.3 核心逻辑流程图
下面这张图是我自己总结的Modbus RTU主站串口配置与超时重试的核心流程,你一看就明白。
4.4 实战配置示例
假设我们要配置一个Modbus RTU主站,连接一个温控器从站。从站说明书上写着:波特率19200,8位数据位,偶校验,1位停止位。那么主站配置如下:
// 伪代码示例
ModbusMaster master;
// 串口参数配置
master.begin(19200); // 波特率
master.setDataBits(8); // 数据位
master.setParity(EVEN); // 校验位:偶校验
master.setStopBits(1); // 停止位
// 帧间隔时间(3.5字符时间)
// 19200bps下:3.5 * 10 / 19200 ≈ 1.82ms
master.setInterFrameDelay(2); // 设为2ms
// 报文超时时间
master.setResponseTimeout(150); // 150ms
// 重试机制
master.setRetryCount(3); // 重试3次
master.setRetryInterval(200); // 重试间隔200ms
好了,关于Modbus RTU主站的串口参数和超时重试机制,就聊到这儿。这些配置看起来简单,但每个参数背后都有实际场景的考量。你配置的时候多想想“如果现场干扰大怎么办”、“如果从站响应慢怎么办”,慢慢就有感觉了。