ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

Modbus RTU调试实战:波形、时序与CRC校验排查指南

Modbus RTU调试实战:波形、时序与CRC校验排查指南 1. 先理清楚这三点为什么决定Modbus RTU能不能跑通如果你手里正好有一台FX3U-485ADP-MB、一台欧姆龙E5CC或者任何支持Modbus RTU的温控器、变频器、仪表这篇笔记应该能帮你少熬几个晚上。先说结论Modbus RTU调试出问题十有八九不是“协议没配好”而是波形、时序、CRC这三件事里有至少一件踩偏了。波形不对信号到不了对方嘴里时序不对一帧完整的话被打成两截CRC不对对方即使收到也只会把你当噪音。Modbus RTU本质是个“主从问答”协议。主站发一帧请求从站收到、校验无误后再回一帧响应。如果从站没收到、收到的帧不完整、CRC校验不过它都不会响应。这个逻辑看起来简单但实际到现场就容易翻车有人拿万用表量电压有人凭肉眼看串口监视器还有人觉得“CRC不就是套个算法吗”结果从站就是纹丝不动。这篇笔记适合三类人参考用PLC做Modbus RTU主站的工程师正在写串口/Modbus从站程序的嵌入式开发者以及需要给设备做上位机通讯的手艺人。我会从物理波形讲起把485电平怎么看、一帧数据的时间怎么算、CRC到底怎么算才不出错以及怎么用ADPRW指令把E5CC这类温控器的数据读回来用踩坑实例的方式串一遍。先说一个我自己的判断Modbus RTU是一个“看着像串口直发、实际上有严格帧格式”的半双工协议。很多人栽跟头就是因为把它当成了纯粹的UART发送。UART只负责把一个字节一个字节搬到对方手里而Modbus RTU要负责把这些字节组装成“一句完整且可信的话”。组装逻辑全靠波形、时序、CRC这三层兜底。1.1 半双工总线本质是“点名问答”RS-485物理层是差分信号两根线A和B用A-B之间的电压差表示逻辑0和逻辑1。总线是半双工同一时刻只能有一个设备在发送。主站说完从站才能回话如果两个设备同时开口总线上就是一团乱波形谁的数据都废了。所以协议规定每个Modbus RTU报文必须严格按照下面的字段组装。字段长度说明从站地址1字节目标从站地址范围1~2470是广播地址从站收到广播不响应功能码1字节03读保持寄存器、04读输入寄存器、06写单寄存器、10写多寄存器等数据区N字节寄存器地址、寄存器数量、写入值或读取数据CRC校验2字节CRC-16/MODBUS低字节在前、高字节在后主站发完这一整帧后必须等从站响应。从站要做的第一件事不是“解析”而是先算CRCCRC不对直接扔掉。这就是为什么CRC错了表现出的症状和“没通讯上”几乎一模一样。1.2 为什么现场都爱用RTU模式而不是ASCII模式Modbus协议还有一个ASCII模式我也在旧设备上见过。ASCII模式把所有数据转成可见字符发送比如把十六进制0x01发成字符“0”和“1”占用字节数翻倍好处是方便人肉阅读和抓包。RTU模式则是直接发二进制字节效率高、报文短、实时性好工业现场绝大多数设备默认支持RTU模式。RTU模式效率高代价就是要求严。它对时间间隔非常敏感对校验算法的约定必须完全一致。ASCII模式因为字符间隔和校验都比较宽松反而对时序不那么挑。很多人刚开始玩RTU容易用ASCII的思维去调结果反复被timing打脸。后面第3章我会详细说这个事。1.3 波形、时序、CRC三个命门之间的关系我用一个生活类比把这三件事解释清楚。总线就是一条“对讲机信道”。波形是“你的嗓子能不能发出对方听得到的声音”时序是“一句话里每个词之间停顿多久才能让对方知道这是一句话而不是两句话”CRC则是“话说完了对方怎么确认你没有传错内容”。这三层是叠加关系。波形坏了后面两层做得再好也没用波形没问题、时序乱了同样白搭前两层都没问题、CRC算错了还是白搭。不少项目组排查到最后发现三个问题全有一开始只盯着其中一个查当然找不到根因。所以我的建议是排查顺序固定为“波形 → 时序 → CRC”一层层排除不要跳。2. 波形示波器才是Modbus RTU调试的第一现场我见过太多种“从站没响应”的情况第一反应是查从站参数、查PLC程序折腾一晚上最后用示波器一看主站压根没把数据发出去或者发了但电平幅度小得可怜。所以遇到通讯问题我从来都先抓波形。波形不会说谎它比任何调试软件的日志都更接近物理现实。2.1 485波形到底该怎么读RS-485用A、B两线之间的差分电压表示数据。常规接法下A高于B时为逻辑1A低于B时为逻辑0。空闲状态时总线保持逻辑1也就是A高B低A-B差分电压通常在2V~5V之间只要大于200mV接收端就能可靠识别。串口发送一个字节时波形结构是固定的起始位逻辑0 → 8个数据位LSB先行 → 停止位逻辑1。反映到差分波形上你会先看到一个下降沿因为总线从空闲的逻辑1跌到起始位的逻辑0然后是一串高高低低的脉冲代表数据位最后是一个上升沿回到逻辑1表示停止位。用示波器测485差分波形最推荐的方式是CH1接ACH2接B然后用数学通道MATH CH1 - CH2。这样直接看差分信号比分别看A、B对地电压直观得多。示波器探头地夹子如果是非隔离的注意不要在带电设备上乱夹避免形成接地环路。如果你看到波形整体是反的——空闲是负电压起始位反而是上升沿那基本可以断定A/B接反了。这个错误很常见换过来就行。还有一点要记住485芯片的TTL侧波形和总线侧波形不是一回事。你拿示波器在MAX485的RO/DI脚看到的TTL电平只能证明“芯片在工作”不能证明“总线上的信号对从站友好”。所以测就跑总线上测别偷懒只测TTL。2.2 示波器时间轴怎么设才看得清一帧Modbus RTU一帧报文的时长要看波特率。以9600bps、8N1格式为例一个字节的传输时间是1个起始位 8个数据位 1个停止位合计10位约1.04ms若带校验位就是11位约1.15ms。一个8字节的请求帧加上帧间隔整个发完大约8~10ms。示波器参数设置我的习惯是分两步先看整帧时基设为20ms/格触发方式选下降沿触发模式选单次或普通。这样能把主站请求、中间间隔、从站响应一起抓到屏幕上确认“有没有发、有没有回”。再看细节把时基放大到1ms/格或2ms/格看起始位下降沿是否干脆、数据位电平是否清晰、有没有回勾和振铃。如果你用的是自动触发模式且时基设置太小波形会一直快速滚动反而看不清完整帧结构。抓波形不是看电影而是拍照。单次触发在这个场景下非常好用。2.3 常见波形异常和它们的“长相”我把现场最容易见到的波形异常整理成一张表排查时对着看就行。现象可能原因处理方法完全没有波形主站没发数据、485转换器没供电、接线断开先确认主站侧发送引脚有没有电平变化波形幅度很小偏置电阻缺失、差分信号衰减、线缆过长检查A/B对地电压必要时加偏置电阻边沿明显变缓波特率太高、线太长、分布电容大降波特率或换成阻抗更匹配的屏蔽双绞线停止位后有回勾和振铃阻抗不匹配、星型接线用菊花链接线两端加120Ω终端电阻波形整体反向A/B接反对调A/B偶发丢字节共模干扰、地电位差、屏蔽层单端接地没做好检查共地屏蔽层单端接地这里多说一句终端电阻。120Ω终端电阻要加在总线物理两端不是你想加就加、不想加就不加。如果只有两台设备短距离调试不加可能也能工作一旦线长超过几十米或者接了好几台从站不加终端电阻波形反射带来的误码率会非常折磨人。2.4 我抓波形的几个实操心得第一探头尽量用差分探头。买不起差分探头的话就用CH1-CH2的数学通道这也是业内常用的替代方案。第二触发点要选下降沿因为Modbus RTU每帧的第一个电平平移就是起始位产生的下降沿。第三不要只看一帧。连续抓几十帧观察波形是否稳定一致。偶发性问题大概率藏在被忽略的“大部分时间正常”里。调试工具方面示波器用于看物理层逻辑分析仪用于看字节流和时序两者配合才是完整配置。纯靠示波器去解码Modbus报文会很累纯靠逻辑分析仪又看不到真正的信号质量。3. 时序Modbus RTU的隐形门槛波形正常不等于协议正常。Modbus RTU把报文是否结束的判断交给了时间间隔这是它和很多自定义串口协议最大的不同。自定义协议通常用帧头、帧尾或长度字段来分帧而Modbus RTU靠的是“静默时间”。3.1 t1.5和t3.5到底差在哪协议规定帧内两个字节之间的间隔不能超过1.5个字符时间。超过t1.5接收方就认为这一帧已经结束后面的字节会被当成新一帧的开头。帧与帧之间的间隔必须大于3.5个字符时间。只有静默超过t3.5接收方才认为前一帧彻底结束下一帧可以开始。这里说的“字符时间”指的是传输一个完整串口字符的时间包含起始位、数据位、校验位、停止位。为了保险我习惯按11位来计算字符时间这样算出来的t1.5和t3.5偏保守不容易踩线。以9600bps为例1位时间 1 / 9600 ≈ 104.17μs1字符时间 ≈ 104.17μs × 11 ≈ 1.146mst1.5 ≈ 1.146ms × 1.5 ≈ 1.718mst3.5 ≈ 1.146ms × 3.5 ≈ 4.007ms以19200bps为例1字符时间 ≈ 0.573mst1.5 ≈ 0.859mst3.5 ≈ 2.004ms3.2 这些时间间隔在实际中怎么考验人先看主站发送侧。如果你的主站是上位机或者单片机用串口发送函数一次性发送整帧一般没问题。但如果发送逻辑被系统调度切成好几段段与段之间间隔超过t1.5从站就会把一帧误判成多帧直接不响应。这时候你在上位机日志里看到数据是“发完了”的但波形上字节间隔已经超了。再看接收侧。单片机接收Modbus RTU一般是中断里一个字节一个字节收然后在定时器里判断“距离上次收字节的间隔是否超过t3.5”。如果定时器精度不够、处理太慢就可能把一帧拆成两段或者把连续两帧误判成一帧。还有一个常见坑是串口FIFO和DMA。接收时DMA可能把一帧拆成几段或者把多帧拼在一起这时候软件做帧解析就不能只靠“收完一次中断就算一帧”。我用过不少USB转485模块有些模块内部会自己缓冲、延迟转发导致字节间隔被改变让从站以为帧被拆开。这种情况在示波器上很难抓到因为问题出在转换器内部不是总线波形。3.3 主站轮询节奏怎么定主站发完请求从站需要时间处理然后才回响应。响应超时时间设置太短主站会误判“从站没响应”设太长整个轮询周期又变慢。我的经验值响应超时至少50ms推荐150ms~500ms。有些温控器内部要做滤波、运算响应会慢。轮询间隔主站收到响应后再等20~50ms再发下一帧给总线和从站一点喘息时间。多从站轮询每台从站分开计时不要一股脑连续发否则半双工总线上很容易发生冲突。在PLC里做轮询最忌讳的是“一个扫描周期内连续触发多帧”。PLC扫描周期本来就短如果程序里没有等上一帧的完成标志下一帧就发出去从站还没回完请求已经把总线占用了。正确结构是“每扫描周期查一次完成标志完成之后再启动下一帧”。3.4 梯形图里“发一帧等一帧”的流程怎么写对于FX3U系列485ADP-MBADPRW指令会自动按Modbus RTU格式组装报文并处理很多底层细节。但梯形图逻辑仍然要你自己搭。我在工程里常用的流程是这样的用一台从站的轮询定时器到点置位对应请求标志位。检测通讯空闲标志满足条件时调用ADPRW发出当前从站的请求。ADPRW执行完成后根据完成标志和异常标志分别处理。有响应则把数据存到对应的PLC寄存器没响应则计数连续几次无响应就报警。复位当前请求标志切换到下一台从站或者延迟一段时间后开始下一轮。用伪代码表示就是M0: 请求触发 M10: ADPRW完成标志 D200: 接收到的数据存放区 LD M0 AND M10 // 上一次已完成 ADPRW K1 H03 K0 K1 D200 // 从站1功能码03寄存器地址0读1个寄存器结果放D200具体操作数含义要以你用的GX Works版本帮助为准不同固件版本的表述会有差异。但“发一帧等一帧”这个骨架是通用的。你只要照着这个骨架画梯形图基本不会把时序搞崩。4. CRC最后一道防线也是最容易被算错的地方CRC全称是循环冗余校验。Modbus RTU用的是CRC-16/MODBUS两个字节挂在报文最后。它的作用是在物理层和时序层都没问题的基础上解决“数据传错了但看起来像对的”这种更隐蔽的问题。4.1 CRC-16/MODBUS参数和原理CRC-16/MODBUS的参数表是这样的多项式0x8005初始值0xFFFF输入反射是输出反射是结果异或值0x0000你可以把CRC理解成“指纹计算”发送方拿整帧数据算出一个16位余数附在帧尾接收方用同样的算法再算一遍如果结果一致说明数据大概率没被篡改。两种设备的参数只要有一个不同算出来的CRC就不一样从站就会静默丢弃。4.2 最通用的软件实现方式先给出只依赖基础运算的逐位计算版本这个版本虽然慢但最容易理解也方便验证。C语言代码如下#include stdint.h uint16_t crc16_modbus(const uint8_t *data, uint16_t len) { uint16_t crc 0xFFFF; while (len--) { crc ^ *data; for (uint8_t i 0; i 8; i) { if (crc 0x0001) crc (crc 1) ^ 0xA001; else crc 1; } } return crc; }注意这里用的0xA001是多项式0x8005经过反射后得到的反转多项式。如果你用非反射算法代码写法会不一样。工程上最常见的实现就是上面这个反射版本Modbus CRC计算器基本都用它。发送时CRC要低字节在前、高字节在后。举个例子uint16_t crc crc16_modbus(frame, frame_len); send_buffer[frame_len] crc 0xFF; // CRC低字节 send_buffer[frame_len 1] crc 8; // CRC高字节Python版同样可以直接用来做上位机或调试验证def crc16_modbus(data: bytes) - int: crc 0xFFFF for b in data: crc ^ b for _ in range(8): if crc 0x0001: crc (crc 1) ^ 0xA001 else: crc 1 return crc frame bytes.fromhex(01 03 00 00 00 01) crc crc16_modbus(frame) send frame bytes([crc 0xFF, crc 8]) print(send.hex().upper())我拿这个脚本和市面上的Modbus调试工具比对过很多次结果一致。你可以把它当成一个基准工具来用。4.3 查表法通信量大的时候必须用逐位计算在单片机定时器中断里虽然也能跑但占用CPU时间偏长。工业环境下我更推荐查表法速度快好几倍。查表法的思路是先把0~255所有单字节的“CRC位移结果”算好存表然后每处理一个新字节用“当前CRC高字节与数据字节的异或值”去查表把结果和CRC低字节移位组合。static uint16_t crc_table[256]; void crc_table_init(void) { for (uint16_t i 0; i 256; i) { uint16_t c i; for (uint8_t j 0; j 8; j) { if (c 0x0001) c (c 1) ^ 0xA001; else c 1; } crc_table[i] c; } } uint16_t crc16_modbus_fast(const uint8_t *data, uint16_t len) { uint16_t crc 0xFFFF; while (len--) { crc (crc 8) ^ crc_table[(crc ^ *data) 0xFF]; } return crc; }查表法占256×2字节的RAM或ROM对现代MCU完全不是事。如果设备上资源极其紧张可以只保留静态表运行时不再生成。4.4 我踩过的CRC相关的坑CRC的坑比很多人想象的要多而且一个比一个隐蔽。第一把CRC自己也算进去了。这是最常见的错误。CRC只覆盖“从站地址、功能码、数据区”这些原始字段计算时不能把帧尾已有的两个CRC字节再算进去。如果你在组帧的缓冲区里先放好CRC占位然后又对整包数据算CRC结果永远对不上。第二字节序搞反。Modbus RTU规定CRC低字节先发、高字节后发。有些设备手册会把校验序列标成“CRC_H CRC_L”如果你照着发从站就永远不回你。遇到这种问题把两个字节交换一下试试通常立刻就好。第三初始值错。CRC-16/MODBUS初始值是0xFFFF不是0x0000。用0x0000初始化的算法在某些报文中偶尔也对但换一个内容就不对属于间歇性故障特别坑。第四多项式混用。CRC-16有好多版本比如CRC-16/IBM、CRC-16/XMODEM、CRC-16/CCITT。参数差一点结果天上地下。核对设备手册或协议文档时要认准“CRC-16/MODBUS”以及0x8005/0xFFFF这些参数。第五从站带回的CRC不一定对。有一次我从站一直报错最后发现是某品牌的库封装里做了“先字节序反转后校验”的画蛇添足操作。所以如果你用的是第三方Modbus库不要迷信它是“标准实现”先用已知报文测一遍。4.5 怎么验证CRC算得对不对最笨也最可靠的方法是用已知报文对照。比如读寄存器请求“01 03 00 00 00 01”在CRC计算器里算出来的校验字节应为“84 0A”这种固定值。你先用系统计算器算几个标准报文再拿自己的代码验证结果符合了再去连从站。现场如果怀疑从站是CRC问题用串口监视工具抓主站发出的原始字节然后把抓到的帧里除最后两字节外的内容丢回自己的CRC脚本里重新计算跟抓到的最后两字节比对。比对不一致问题就锁定在主站侧或上位机库里了。5. 实测FX3U-485ADP-MB读写E5CC温控器理论讲完上点能直接抄作业的实战。我选FX3U-485ADP-MB欧姆龙E5CC这个组合因为这两个都是工业现场非常典型的设备一个PLC侧Modbus RTU主站一个温控器从站。把这条链路调通其他仪表设备基本是换个寄存器和功能码的事。5.1 硬件接线和通讯参数E5CC的Modbus端子一般是A和BFX3U-485ADP-MB也提供对应的485口。接线用屏蔽双绞线A对A、B对B屏蔽层单端接地。如果距离不远可以不加偏置电阻但超过几十米建议按RS-485规范处理。FX3U-485ADP-MBE5CCSDA / AASDB / B-BSGSG信号地通讯参数必须两端一致。E5CC要从面板菜单里把通讯协议设为Modbus RTU再核对从站地址、波特率、数据格式。我常用的基础参数是从站地址01波特率9600数据位8停止位1校验无8N1也有的项目用偶校验8E1只要两端一致就行注意“一致”不只是波特率一致停止位和校验位也必须一致。很多现场配置错误都是8N1和8E1混搭导致的间歇性失败。5.2 读E5CC的PV值报文拆解E5CC的当前温度PV值存放在保持寄存器0x0000用功能码03读取。请求报文格式01 03 00 00 00 01 CRC_L CRC_H含义拆开看01从站地址03读保持寄存器00 00寄存器起始地址0000即PV00 01读取寄存器数量1个CRC_L CRC_HCRC校验两字节假设当前温度是25.0℃E5CC回传的报文类似01 03 02 00 FA CRC_L CRC_H这里01是从站地址03是功能码回显02是数据字节数00 FA是PV的十六进制值。E5CC的温度分辨率通常是0.1℃所以0x00FA换算成十进制是250对应25.0℃。如果你用PLC做主站CRC由FX3U-485ADP-MB的ADPRW指令自动计算梯形图里不需要手算CRC但你要知道底层有这个环节排查时才不会漏掉这个可能性。5.3 ADPRW指令写PLC梯形图的逻辑骨架ADPRW可以理解成“PLC自动发一条Modbus请求并等待响应”的指令。梯形图不需要画得很花哨但逻辑必须严格。我推荐的结构是这样请求使能 ↓ 检查通讯空闲 ↓ 执行ADPRW发当前从站请求 ↓ 等待完成标志 ↓ 读取数据 / 处理异常 ↓ 复位请求延时进入下一轮用文字展开就是先用一个轮询定时器定时到点后把M0置位。程序检测到M0和通讯空闲标志都满足就执行ADPRW。ADPRW完成后根据完成标志把数据存到D区。如果多次异常置一个通讯故障位方便触摸屏或上位机报警。处理完以后复位M0延时一小段再开始下一台从站的请求。有一点必须反复强调ADPRW是异步通讯指令它执行后不会立刻得到结果。你必须在梯形图里等它的完成标志而不是发完就马上读数据。否则你读到的永远是上次缓存的数据。现场大量“读到的值不变”“偶发读不到”的案例都是这里没做好。5.4 上位机和板卡做法换成上位机或单片机做主站手里没有PLC的ADPRW帮你组帧就需要自己实现“组帧→计算CRC→发送→等待响应→超时判定→解析响应”的完整状态机。用Python做上位机调试流程是import serial ser serial.Serial( portCOM3, baudrate9600, bytesize8, parityN, stopbits1, timeout0.5 ) request bytes.fromhex(01 03 00 00 00 01) crc crc16_modbus(request) ser.write(request bytes([crc 0xFF, crc 8])) resp ser.read(20) print(resp.hex().upper())这种做法的重点是串口超时要设够不要只等10ms。我更推荐把“等一帧完整结束”的逻辑做成基于时间戳的方式收字节时记录最后一次接收时间一旦静默超过t3.5就认为帧结束再进入解析。不要单纯依赖串口返回长度。5.5 完整通讯流程中常见的组合拳真正稳定的Modbus RTU主站应该同时具备这几段逻辑发送前检查总线是否空闲不要在从站响应期间抢发下一帧。发送后启动响应超时定时器。接收时用帧间隔判断帧结束而不是每收到一个字节就解析。解析后校验地址、功能码、CRC。处理正常响应和异常响应功能码高位加1并返回异常码。这五段缺一个现场就会出一些“时而好、时而不行”的问题。尤其是在轮询多台从站的项目里总线上的一点点冲突都会放大成全部断连。6. 常见问题与排查技巧实录我把自己这些年踩过的、和帮别人排查过的高频问题整理成了一张速查表。建议你遇到问题先查表再动手比瞎换线有效率得多。6.1 现场问题速查表现象可能原因对策从站完全无响应A/B接反、地址错误、波特率不一致、主站没发数据先用示波器看主站是否发出再用串口工具确认从站能收到字节响应时有时无轮询间隔太短、总线冲突、终端电阻没加拉长轮询间隔规范485接线两端加120Ω电阻CRC错误频繁帧内容多算/少算、字节序反、校验参数不对用标准报文喂给CRC脚本和抓包结果比对单发正常连续轮询报错从站响应超时时间太短、请求切换太快每帧之间加20~50ms静默响应超时调到150ms以上波特率越高越容易错线太长、分布电容大、终端电阻不匹配降波特率换屏蔽双绞线缩短链路上位机调试正常PLC接上就不行上位机软件可能自动做了字节间隔控制PLC梯形图缺少完成标志等待检查PLC程序是否发完一帧马上发下一帧报文能看到但内容明显乱码停止位、校验位设置不一致核对8N1/8E1/8O1必须两端完全一致排查顺序还是那句老话先测波形再查时序最后验CRC。不要一上来就怀疑CRCCRC通常是你把前两层都确认没问题以后才会去动的。6.2 串口调试工具的选择和使用细节用USB转485模块做调试时我建议先用串口助手连上从站手动发一条标准请求确认从站能正常响应。这一步能快速隔离“PLC/上位机问题”和“从站问题”。抓包工具方面普通的串口助手只能看字节看不出帧与帧之间的实际时间间隔。想查时序问题用带时间戳的串口监视工具或者用逻辑分析仪解码。逻辑分析仪可以看到每一帧的起始时间、结束时间和字节间隔非常直观。另一个容易被忽略的点有些USB转485模块是“自动方向切换”但切换速度不够快或者在发送完一帧后没有立即释放总线会吞掉从站响应的第一个字节。如果遇到“从站明明正常主站就是收到不完整响应”换一块知名芯片的USB转485模块可能就解决了。这种硬件差异在波形不稳定时会特别明显。6.3 一个排查实例E5CC为什么偶尔不回有一次现场反馈FX3U-485ADP-MB读E5CC大多数时候正常偶尔某一次读不到重试几次又好了。我第一反应不是换设备而是抓波形。从波形上看到主站发完请求后从站并不是立刻响应中间间隔最大能到80ms。主站程序里响应超时设的100ms表面上看是够的但PLC扫描周期、逻辑开销一叠加某些时刻就卡在临界点所以“偶尔失败”。把响应超时从100ms改成300ms问题消失。这类案例很典型。Modbus RTU的时序问题不一定总是“帧间隔超了”也可能是“从站响应慢主站的等待窗口太紧”。改参数之前用示波器或者带时间戳的工具先量出真实的时间分布再决定怎么调远比拍脑袋改代码靠谱。6.4 还有一个常被忽视的从站侧参数很多温控器、变频器的Modbus从站侧除了地址、波特率还有一个“通讯等待时间”或者“响应延迟”参数。部分设备支持设置为0但设置为0并不代表它立刻响应芯片内部还是要跑完一个任务周期。遇到响应极慢或超时记得去查从站手册里的“最小响应时间”或“通讯间隔”。有些仪表在做了滤波、PID自整定之后Modbus响应时间会明显变长。做主站侧超时时间的时候别只按理想值算要给从站留够余量。最终我再补一句个人体会Modbus RTU这个协议难度不在“会不会发报文”而在“当现场不按文档走的时候你能不能一层层把问题定位出来”。波形、时序、CRC是三个互相咬合的齿轮。先把这三层工具练熟再复杂的现场也不会把你绕晕。
返回列表