Modbus RTU实战笔记:波形、时序、CRC,一个都别踩偏

📅 发布时间:2026/8/24 14:19:34
Modbus RTU实战笔记:波形、时序、CRC,一个都别踩偏 干自动化这些年Modbus RTU是绕不开的基本功。RS485一拉双绞线一拧心里就得有数——这活儿看着简单但现场跑起来干扰、时序、字节序、CRC哪一样都能让你折腾到半夜。今天不整虚的纯实战角度把RTU这事儿掰开揉碎说清楚。先定个调Modbus RTU不是协议是帧格式。跟ASCII比RTU紧凑、高效、CRC校验结实工业现场99%用这个。ASCII那是给老古董备着玩的帧长翻倍效率砍半除非你是给上世纪九十年代的设备做兼容否则别碰。一、物理层RS485是亲爹别搞反了RTU跑在RS485上两线制差分信号半双工。A、B别接反反了就是收不到数据或者乱码。终端电阻必须加120欧末端两个节点各一个。不加的话长距离信号反射能把波形干得一塌糊涂示波器一看全是振铃CRC死活过不去。节点数量理论32个但现场别贪超过20个建议加中继器。手拉手拓扑别搞星型星型接法在485上就是找抽信号质量差到你想哭。二、串口参数四件套错一个就凉凉波特率、数据位、停止位、校验位。9600、8、N、1是默认共识但别想当然。我碰到过一台德国来的流量计默认是19200、7、E、1手册里写了但没加粗结果折腾了两个小时才反应过来。那次以后我养成习惯拿到设备先读手册的串口参数页别靠猜。校验位这块无校验N最省事但工业现场变频器一开干扰上来全是毛刺偶校验E能挡掉一部分误码。性能损失忽略不计建议上E。三、帧格式3.5字符间隔是命门RTU的帧边界靠静默间隔来判断标准是3.5个字符时间。这个得算清楚——波特率9600时1个字符约1ms含起始位停止位3.5字符就是3.5ms。用单片机软实现时定时器精度不够或者中断优先级没设好间隔判断偏了帧头帧尾就分不清数据全乱。帧结构就这几样地址1字节 功能码1字节 数据N字节 CRC2字节。地址0是广播从站收到只执行不回别把设备地址设成0那是自己坑自己。四、功能码常用的就四个01读线圈DO位操作02读离散输入DI位操作03读保持寄存器Holding Register16位可读可写04读输入寄存器Input Register16位只读03和04最容易搞混记住一句话保持寄存器是PLC能写的输入寄存器是现场传感器只读的。现场接线前先把设备地址映射表搞清楚不然发03去读04的地址返回全是0x00还得怀疑自己程序写错了。五、字节序大端还是小端搞反就翻车Modbus RTU是大端Big-Endian高字节在前低字节在后。比如寄存器值0x1234发出来就是0x12、0x34。但很多MCU是ARM或x86小端模式。你要是用指针直接强转取数据高低字节就颠倒了读出来是0x3412。这坑我见过不下二十次新人必踩。解决办法就两条要么用位移拼要么写个swap宏别偷懒。六、CRC校验按位算比查表更稳妥CRC-16-Modbus多项式0x8005初始值0xFFFF。网上代码一堆但建议用按位计算虽然慢点但代码量小、移植方便不占ROM。查表法快是快但碰到不同平台字节序问题容易翻车。注意CRC的发送顺序低字节在前高字节在后。比如算出来是0x1234先发0x34再发0x12。很多人算对了但顺序反了从站校验失败直接不回包查半天查不出原因。七、超时与重试实战出来的经验值串口通信没有握手主站发完请求就得等回复。超时时间怎么设轮询周期短比如50ms以内超时设200ms轮询周期长比如1秒以上超时设500ms~1秒别设太短有些老设备响应就是慢尤其带液晶显示或者内部要做浮点运算的几百毫秒正常。设太短导致频繁超时重试总线上一堆垃圾帧反而拖垮整个网络。重试次数建议2~3次连续超时就报故障别死磕总线可能已经物理断线了。八、工程应用里的几条铁律第一不要高频轮询同一个从站。见过有人把某个流量计设成10ms轮询一次从站CPU直接跑满响应延迟飙升连带其他站都受影响。工业现场100ms周期足够没必要卷那几十毫秒。第二报文长度注意上限。RTU单帧最大256字节其中数据部分最多252字节。批量读寄存器时一次最多读125个因为每个寄存器2字节。别贪多有些老设备缓冲区就那么大发超了直接不回。第三收发切换要有死区。RS485是半双工从发到收需要时间一般加2~3ms延时再切到接收状态。有些廉价转换器切换慢不加延时前面的回复就收不全。九、调试工具别靠猜抓包是王道串口调试助手只是看数据真正干活得用逻辑分析仪或者带波形显示的串口监控。看波形能判断A/B线有没有接反、终端电阻够不够、波特率对不对。Wireshark抓TCP好使但串口层面还得靠硬件工具。我包里常年备着一个带隔离的USB转485带指示灯那种。收发光一闪大概就知道总线有没有在跑数据。肉眼判断虽然不精确但现场抢修时比开电脑抓包快得多。十、最后说个真实案例去年帮一个水厂改系统新旧设备混用新设备波特率115200老设备只支持9600。没办法只能加协议转换器做隔离两个波特率各自跑。如果当初选型时就统一参数根本不用多花这冤枉钱。所以经验就一句选型时把串口参数定死写在技术协议里设备到场逐台核对少一步后面都是坑。Modbus RTU就这么个东西不难但细。波形、时序、CRC、字节序哪一环松了都跑不起来。动手接两根线抓一帧报文比看十篇文章都管用。