Modbus RTU通信实战手记:当ModbusPoll“收不到”HMI响应时,你在和谁较劲?
上周五下午三点,产线停机。操作员指着HMI上跳变的温度值说:“这数字自己在动。”工程师连上ModbusPoll,读40001——Timeout。换波特率、改地址、查接线……两小时后发现,问题不在RS-485线缆,而在HMI固件里一个被注释掉的CRC重计算逻辑。
这不是个例。在上百次现场调试中,我逐渐意识到:Modbus RTU通信失败,90%不是“不通”,而是“双方对‘一帧’的理解根本不同步”。
ModbusPoll是协议教科书的忠实执行者;而HMI,是嵌入式资源受限世界里的务实工程师——它不追求绝对合规,只求“在主频80MHz、RAM仅64KB的ARM Cortex-M3上,把按钮点下去那一刻,画面能亮”。
下面,我把这些踩过的坑、抓过的波形、比对过的寄存器,揉进一次真实的调试流。不讲定义,只讲你按下“Read”键之后,线上到底发生了什么。
一帧RTU报文,在空中真正长什么样?
先抛开手册里那些“地址域、功能码、数据域”的术语。打开ModbusPoll日志,看到这一行:
Tx: 01 03 00 00 00 0A C4 0B Rx: 01 03 14 00 01 00 02 00 03 00 04 00 05 00 06 00 07 00 08 00 09 00 0A 4E 7C你以为这就是全部?错。这只是ModbusPoll“认为”它发出去和收到的东西。真实RS-485总线上的电平变化,远比十六进制更诚实。
关键真相一:T3.5不是“等待时间”,而是“帧终结判决器”
Modbus RTU没有起始位、停止位来标记一帧边界。它靠的是线路静默。
标准规定:若线路上连续空闲时间 ≥ 3.5个字符时间(T3.5),则前一帧结束,新帧开始。
T3.5 = 3.5 × (10位 ÷ 波特率)