FX3U ADPRW指令485通讯调试:接线、D8120与轮询要点

柜子里那台 FX3U 的 485 指示灯闪了两下就灭了,程序里 ADPRW 指令写得整整齐齐,从站那边一个字节都没回。这种场面我碰上不止一次,最难受的不是不会写指令,而是指令明明写对了,却不知道问题出在接线、参数、地址还是时序上,只能一遍遍试。ADPRW 指令、FX3U、485 无协议通讯这几个词凑在一起,几乎是每个做小型自控柜的人都要跨过去的一道坎,跨过去之后你会发现它其实很省事——Modbus 帧的组包、CRC 校验、异常响应识别,固件全替你做了,你只需要把五个操作数填对,再把时序捋顺。

这篇内容面向的是已经能写基本梯形图、准备或正在用 FX3U 通过 485 挂第三方设备的人。下面讲的不是手册的复述,而是我在实际调试中沉淀下来的判断顺序和几个容易反复踩的点:为什么这条指令只能挂在通道 1 上、D8120 那 16 位到底怎么拼、寄存器地址那个“差 1”是怎么来的、多条指令为什么必须排队。看完之后你应该能做到:拿到一台支持 Modbus RTU 的从站,从接线到跑通读写在半天内完成。

1. 概念先掰正:ADPRW 跑的是 Modbus RTU,不是自由裸发

很多资料把 ADPRW 归到“485 无协议通讯”里讲,这个说法在工程现场已经约定俗成了,但严格论起来是错的,而这个错误理解会直接影响你排错的方向。把这件事说清楚,后面很多现象才好解释。

1.1 FX3U 上三种 485 通讯方式的分野

FX3U 走 485 大致有三条路。第一条是RS/RS2指令,这才是真正意义上的无协议通讯:你自己把要发的字节一个接一个塞进数据区,自己算 CRC,自己判断一帧收完了没有(靠结束符、固定长度或者超时),收到的字节也原样丢在数据区等你解析。灵活,什么奇葩协议都能对付,代价是代码量大、调试麻烦。

第二条就是本篇的主角ADPRW,它是固件内置的 Modbus RTU 主站指令。你告诉它“去 1 号站,用 03 功能码,从地址 0 开始读 10 个寄存器”,剩下的组帧、CRC 计算、等待响应、校验、异常码识别,它全包了。你拿到的就是干干净净的 10 个寄存器的值。第三条是“专用协议”,用于和同体系设备通讯,格式 1、格式 4 那几种,实际项目里用得越来越少,因为第三方设备基本都走 Modbus。

方式是否需要自己组帧是否算 CRC适用场景代码量
RS / RS2 指令需要需要非标协议、ASCII 协议、自定义帧大
ADPRW 指令不需要不需要标准 Modbus RTU 从站小
专用协议不需要不需要同体系设备互联小

1.2 为什么大家都管它叫“无协议通讯”

根源在 D8120。这个寄存器的第 8 位(b8)是协议选择位,0 表示无协议通讯,1 表示专用协议。使用 ADPRW 的时候,b8 保持 0 就行,因为指令自己会按 Modbus 的规则组帧,不需要 D8120 去声明“我现在跑的是 Modbus”。于是有人看到 b8=0,就顺口说这是“无协议”,传来传去就成了现在这个叫法。

这里有个实操提醒:b8 千万别设成 1。我见过有人为了让“协议生效”把这一位置 1,结果通道被切到专用协议模式,ADPRW 发出去的帧对端根本不认,表现为从站毫无反应,而 PLC 侧的错误代码还迟迟不报,非常折磨人。记住一句话:用 ADPRW,D8120 只负责“物理层参数”(波特率、数据位、校验、停止位),协议层交给指令本身。

1.3 决定用 ADPRW 之前,先确认这四件事

第一,从站必须是 Modbus RTU 从站,不是 Modbus ASCII,也不是厂家私有协议。第二,FX3U 在这条总线上必须是唯一的主站,不能出现两台主站抢总线的情况,否则会出现随机性的通讯失败,而且极难复现。第三,扩展模块必须落在通道 1 的物理位置上,这一条下一节展开。第四,每个从站的站号必须唯一且非 0,0 号是广播地址,写指令用广播等于“发出去不管有没有人应答”,读指令用广播则完全没有意义。

提示:如果从站手册写的是“支持 Modbus 协议”,一定要翻到具体章节确认是 RTU 还是 ASCII。有些设备两种都支持但要通过面板菜单切换,出厂默认可能是 ASCII,这时候 ADPRW 怎么调都不通。

2. 接线与通道:485 扩展最容易翻车的地方

通讯不上,先怀疑硬件,这话听起来像废话,但现场统计下来,接线和通道归属占了一半以上的故障。而且这两类问题的表现高度一致——PLC 发出去没回应,或者干脆连发都没发出去,很容易被误判成程序问题。

2.1 两线制接法:SDA-RDA、SDB-RDB 这两根短接线不能省

485 扩展的端子一般有五个:SDA、SDB、RDA、RDB、SG。四线制全双工时四个信号各接各的,但绝大多数 Modbus RTU 设备用的是两线制半双工,这时候必须在 PLC 侧把 SDA 和 RDA 短接、SDB 和 RDB 短接,然后从短接点引出两根线接到从站的 A(或 D+)和 B(或 D-)。

很多人图省事只接 SDA、SDB,或者只接 RDA、RDB,短接线省掉了。结果就是:发送的时候信号能出去(因为发送走 SDA/SDB),但收的时候差分接收端没接上,永远收不到回帧,现象就是“从站明明回了,PLC 说超时”。这个坑我至少在三个不同现场见过,其中一次排查了两个多小时才发现是端子排上少了一根一厘米长的短接线。

关于 A/B 极性,不同厂家的标注是反的,有的把 A 标成正、有的标成负。接反了不会烧设备,只会收不到数据,所以调试初期如果一切参数都对但就是没反应,把两根线对调一下,这是成本最低的验证动作。

2.2 终端电阻、屏蔽层和共地

总线长度超过几十米、或者波特率拉到 19200 以上时,终端电阻就必须考虑了。做法是在总线物理两端各并一个 110Ω 或 120Ω 的电阻,中间节点不要接。有些从站内部自带终端电阻,通过拨码开关或跳线启用,接线前先看手册,避免出现“两端各接一个、中间还接了俩”的情况,那样总线负载过重,波形直接被拉垮。

屏蔽层处理上,我的习惯是单点接地,一般接在柜内的接地排上,从站那一端悬空,避免两端接地形成地环路引入干扰。SG 端子是否要连,取决于两端的地电位差,如果距离近、同一路供电,连上更稳定;如果跨了配电区域,地电位差可能到几伏甚至更高,这时候连 SG 反而会把干扰引进来,这种情况我会选择不连 SG,靠屏蔽层和隔离来解决。

注意:变频器、伺服、大功率接触器这些干扰源和通讯线一定要分开走线,平行距离越短越好,实在要交叉就成 90 度。我遇到过一次通讯随机丢帧,最后查出来是通讯线和一台变频器的输出线在同一根线槽里并排走了六米。

2.3 通道归属:ADPRW 只能落在通道 1

这是 ADPRW 最硬的一条限制,也是新手最容易忽略的一条。ADPRW 指令固定使用通道 1,不能指定通道 2。而 FX3U 的 485 扩展有几个位置:通讯板(装在选件板接口上)占用通道 1;通讯适配器(装在左侧适配器位置)按安装顺序依次是通道 1、通道 2。

所以结论很明确:想用 ADPRW,485 扩展必须落在通道 1 的位置上。如果你为了多挂一路 485 装了两台适配器,第二台落在通道 2,那一路就只能用 RS 指令自己做,ADPRW 指挥不了它。这个限制没有变通办法,选型阶段就要规划好。

另外,同一时刻通道 1 上只能有一条通讯指令在执行。这意味着你不能写五个 ADPRW 让它们同时触发,必须做成排队轮询。后面第 5 节会给出具体的状态机写法。

3. D8120 那 16 位,值得花十分钟逐位算一遍

通讯格式不对的典型表现是“完全没反应”或者“偶尔通一次”,这两种现象都不像程序错误,很容易让人往硬件方向死磕。D8120 是通道 1 的通讯格式寄存器,用 M8002 在首次扫描时写入,它的每一位都有明确含义,与其抄别人现成的十六进制数,不如自己算一遍,算完你就再也不会记错了。

3.1 通讯格式不一致时的三种典型现象

第一种,波特率不一致:从站完全不应答,PLC 侧超时,错误码指向超时。因为从站按自己的波特率采样,收到的全是乱码,CRC 校验不过,直接丢弃,连异常响应都不会回。

第二种,数据位或校验位不一致:有时候能通、有时候不通,或者读回来的数据偶尔错位。校验位不一致是最阴的,因为帧结构还算接近,偶尔能侥幸校验通过,导致数据可信度极低。

第三种,停止位不一致:多数情况下表现为间歇性帧错误。停止位少一位,接收方可能把下一帧的起始位当成本帧的一部分,帧边界全乱。

3.2 逐位拼出你要的 D8120

以最常见的 9600、8 数据位、无校验、1 停止位为例,逐位推一遍:

位含义本例取值说明
b0数据长度10=7 位,1=8 位
b1-b2校验位0000=无,01=奇,10=偶
b3停止位00=1 位,1=2 位
b4-b7波特率10000011=300 … 1000=9600,1001=19200
b8协议0保持 0,不要设成 1
b9-b10起始符/结束符00无协议通讯才用到,ADPRW 不需要
b11-b12控制线00两线制不需要 RS/CS 控制
b13-b15校验和/协议000保持 0

把 b0 到 b7 拼起来就是二进制 1000 0001,即十六进制的 H0081。代码里写MOV H81 D8120或者MOV H0081 D8120都可以。

如果从站是 19200、8、偶校验、1 停止位,那就是 b0=1、b1b2=10、b3=0、b4-b7=1001,低字节是 1001 0101,即 H95;配上高字节的 0,得到 H0095。自己算的好处是:现场遇到任何参数组合,掏出手机算两分钟就能改,不用翻手册找现成的例子。

3.3 D8129 超时设定与 D8063 错误码

D8129 是通道 1 的通讯超时判定时间,单位是 10ms。设 K30 就是 300ms。这个值的设定原则是:比从站最坏情况下的响应时间再大一倍以上。多数仪表的响应在 10~50ms 之间,设 300ms 已经很宽裕;但如果从站做了大量内部运算,或者挂了中继器、转换器,链路延时会被放大,这时候要往上调。

超时设得太小,会出现“其实通讯成功了但 PLC 判超时”的假故障;设得太大,一旦从站真的掉线,你的轮询周期会被拖得很长,影响整条总线的实时性。我的习惯是先设 K50(500ms)把通讯跑通,观察稳定后再往小压,压到不出现偶发超时为止,再回退一档。

D8063 是通道 1 的错误代码,配合 M8063(通道 1 通讯错误标志)一起用。通讯出错时 M8063 接通,D8063 里是对应的代码。不同代码指向的方向不一样,大致可以这样理解:

D8063 常见值大致指向优先排查方向
0正常——
超时类代码从站没回或回得太慢接线极性、站号、波特率、从站是否上电
校验/帧错误类代码收到了但内容不对校验位、停止位、数据位设置
命令类代码指令参数不被接受S2 功能码是否支持、S3 地址是否越界

具体数值以手册的错误代码表为准,我建议调试时把 D8063 拖到监控窗口里常驻,出问题先看它,比盲猜快十倍。

提示:错误一旦产生,需要用 RST M8063 清除错误标志,否则后续的通讯请求可能被直接拒绝。程序里我一般会做一个手动复位按钮,串在 RST 指令前,方便现场处理。

4. ADPRW 五个操作数,每个都埋着一个坑

指令的写法看起来简单:ADPRW S1 S2 S3 S4 D。五个操作数,填完就完事。但我见过的通讯失败案例里,将近一半是这五个位置里有某个填错了含义,尤其是 S3 和 S4,因为手册上的一句话描述很容易被读漏。

4.1 S1 站号:范围是 1 到 247,0 是广播

S1 填从站站号,有效范围 1~247。填 0 表示广播,广播的特点是“发出去不管有没有人应答”,只有写指令用广播才有意义(比如同时给多个从站下发同一个设定值),读指令用广播毫无意义,因为你不知道回的是谁。

现场常见错误是从站出厂默认站号不是 1。有些仪表默认是 1,有些默认是 0,有些默认是 247,还有的需要通过面板菜单进去改。第一次接线时,务必先从从站面板上确认站号,不要假设。

4.2 S2 功能码:03 和 04 读的不是同一块区域

这是最容易让人误判的一个点。Modbus 把数据分成四个区:线圈(可读写位)、离散输入(只读位)、输入寄存器(只读字)、保持寄存器(可读写字)。对应的功能码是 01、02、04、03。

很多仪表的测量值放在输入寄存器区,用 04 功能码读;而设定值放在保持寄存器区,用 03 读,用 06 或 10 写。如果你用 03 去读一个只在输入寄存器区有数据的地址,从站会返回异常响应(非法数据地址),表现出来就是“地址明明对着手册填的,就是读不到”。

功能码作用读写方向常见用途
H01读线圈读读继电器状态
H02读离散输入读读开关量输入
H03读保持寄存器读读设定值、参数
H04读输入寄存器读读测量值、实时数据
H05写单个线圈写控制单个继电器
H06写单个寄存器写改单个参数
H0F写多个线圈写批量控制
H10写多个寄存器写批量下发参数

调试时我的顺序是:先拿设备的官方调试工具或者串口助手,把 03 和 04 各试一遍,确认数据到底在哪个区,再回来写 PLC 程序。省下来的时间远超折腾串口助手的那十分钟。

4.3 S3 地址:40001 到底是 H0000 还是 H0001

Modbus 的地址表示法有两套:协议地址(从 0 开始)和文档地址(从 1 开始,还带区号前缀)。设备手册上写的“40001”是文档地址,指的是保持寄存器的第一个,它对应的协议地址是 0。所以 S3 应该填 H0000,不是 H0001。

如果是六位表示法,比如“400101”,减去 400001 得到 100,协议地址就是 100,S3 填 H0064。同理,输入寄存器区的“30001”对应协议地址 0。

这个“差 1”是所有 Modbus 调试里出现频率最高的坑,而且它的表现和功能码选错几乎一样——读不到数据或者数据全 0。我的经验是:手册上的地址先减掉区号基址,再看手册有没有明确说“地址从 0 开始”。有些国产仪表在手册里直接给协议地址,标着“寄存器地址 0x0000”,这种就不用减,直接填。遇到模棱两可的,就两个都试一遍,能读到数据的那个就是对的。

4.4 S4 和 D:点数与数据区预留

S4 在读的时候是读取点数,在写的时候是写入点数。读 10 个寄存器,S4 填 K10,数据会依次存进 D 起始的 10 个连续软元件里。写的时候同理,D 起始的 N 个软元件内容会被依次发出去。

这里有两个细节要注意。第一是数据区预留要够,读 10 个就要留出 D100~D109,如果程序里 D105 已经被别处占用,通讯一跑起来就会把别人的数据冲掉,而且这种 bug 极难查,因为现象是“某个无关的参数莫名其妙变了”。第二是注意掉电保持区的设置,FX3U 的 D 区默认有一部分是保持的,如果你把通讯数据放在保持区里,上电后看到的是上次掉电前的旧值,容易误判成“通讯没刷新”。

还有一点,单次读取的点数不要贪多。Modbus 规范里 03 功能码单次最多读 125 个寄存器,但实际工程中我建议一条指令控制在几十个字以内。原因很简单:一次读的点数越多,帧越长,单次通讯耗时越长,一旦出错重试的代价也越大。分几条指令读,出错时还能定位到具体是哪一段。

4.5 M8029 与驱动条件:为什么必须做握手

ADPRW 从驱动到完成需要若干个扫描周期,完成时 M8029 会接通一个扫描周期,这就是“本次通讯结束”的信号。关键在于:如果驱动条件一直保持接通,指令会不断地发起新的通讯请求,通道被它独占,其他通讯指令永远插不进去。

所以标准写法必须做成握手:置位一个中间继电器发起请求,用 M8029 的上升沿把请求复位。写出来大概是这样:

LD X0 SET M10 LD M10 ADPRW K1 H03 H0000 K10 D100 LD M10 AND M8029 RST M10

用脉冲执行型ADPRWP也可以,但我更推荐上面这种带中间继电器的写法,因为后面要扩展到多从站轮询时,这个 M10 可以直接换成一个步序号,改起来更顺。

注意:ADPRW 执行期间,如果同一通道上有别的通讯指令被触发,会直接报错。所以程序里最好维护一个“通道忙”标志,所有通讯请求都要先判断这个标志。

5. 一套能直接落地的程序骨架

光讲指令不讲结构,看完还是不会写。这一节给出一个完整可跑的骨架,包含初始化、单次读写、多从站轮询和数据解析四部分,你可以直接照着改站号和地址。

5.1 初始化段:只在首次扫描执行一次

LD M8002 MOV H0081 D8120 ; 9600, 8, N, 1 MOV K50 D8129 ; 超时 500ms MOV K0 D100 ; 清数据区(按实际点数清)

初始化只做两件事:写通讯格式、写超时时间。注意 D8120 的写入必须在通讯开始前完成,用 M8002 首次扫描脉冲是最稳的时机。清数据区这一步不是必须的,但能避免上电瞬间读到旧值造成误判,我习惯加上。

5.2 单条读写的握手写法

读一段保持寄存器,读到 D100 开始的 10 个字:

LD X10 ; 手动触发读 SET M10 LD M10 ADPRW K1 H03 H0000 K10 D100 LD M10 AND M8029 RST M10 SET M20 ; 读完成标志

写两个寄存器到从站的地址 100:

LD M20 SET M11 LD M11 ADPRW K1 H10 H0064 K2 D200 LD M11 AND M8029 RST M11 RST M20

注意写多个寄存器用 H10 功能码,S4 填写入点数 K2,数据取自 D200、D201。如果只写一个寄存器,用 H06 更简单,S4 填 K1。

5.3 多从站轮询:用步序号管理

挂了三台从站的时候,不能三条指令一起触发,必须做成流水线。最土但最可靠的办法是用一个整数寄存器当步序号:

; 步 0:读 1 号站 LD M8000 AND= D300 K0 SET M30 AND M30 ADPRW K1 H03 H0000 K6 D100 AND M30 AND M8029 RST M30 INC D300 ; 步 1:读 2 号站 LD M8000 AND= D300 K1 SET M31 AND M31 ADPRW K2 H04 H0000 K4 D110 AND M31 AND M8029 RST M31 INC D300 ; 步 2:读 3 号站 LD M8000 AND= D300 K2 SET M32 AND M32 ADPRW K3 H03 H0010 K8 D120 AND M32 AND M8029 RST M32 MOV K0 D300

这里用一个 D300 做步序号,跑完一圈回到 0,形成无限循环。每个步都用独立的中继(M30、M31、M32)做握手,互不干扰。

这套写法有个隐患:如果某一台从站掉线,超时发生后 M8029 不动作,步序号就卡在那一步不动了,整条总线停摆。所以必须加超时保护,让错误发生时也能强制推进:

LD M30 AND M8063 ; 通道 1 通讯错误 RST M30 INC D300 RST M8063

一旦某一步报错,就跳过它进入下一步,同时记一个错误计数用于报警。这样单台从站故障不会拖垮整条总线,这是我在实际项目里必须加的一段。

5.4 数据解析:16 位、32 位、缩放

读回来的数据是 16 位无符号整数,但实际含义往往不是。常见的有三种情况。

第一种是带小数的工程量,比如温度值 253 表示 25.3℃,需要除以 10。这种直接用浮点指令:FLT D100 D400把整数转成浮点,再DEMUL或者用定点运算DEDIV乘以系数。16 位运算需要注意溢出,超过 32767 的值要用 32 位指令处理。

第二种是 32 位整数或者 32 位浮点,占两个连续的寄存器。这里有个字序问题:FX3U 的 32 位数据是低字在前、高字在后(D100 存低 16 位,D101 存高 16 位),而有些从站发的是高字在前。如果直接拼,读出来会是一个荒谬的巨大数值。处理办法是交换两个字:

MOV D101 D110 ; 高字放到低地址 MOV D100 D111 ; 低字放到高地址

之后以 D110 作为 32 位数据的起始,再用DFLT转成浮点。是不是要交换,取决于从站手册对数据格式的说明,没有说明就拿一个已知值(比如设备面板上显示的当前值)反推一下。

第三种是位组合,一个寄存器里的 16 个位分别代表不同的状态或报警。这种用AND或者BAND配合移位指令拆,建议在注释里把每一位的含义写清楚,不然三个月后自己都不认识。

数据形态占用寄存器处理方式
无符号整数1直接用
带 1 位小数1除以 10,用浮点指令避免溢出
32 位整数2注意字序,必要时交换
32 位浮点2字序确认后用 DFLT 系列指令
位组合状态1按位与拆解,逐位注释

6. 不通的时候,按这个链路查

通讯故障最怕没有章法,东试一下西试一下,时间全耗在反复重启上。我现在的固定动作是从物理层往上逐层验证,每一层确认通过了再往上走,基本能在半小时内定位到问题层。

6.1 从接线到程序的四层排查

层次验证方法通过标准
物理层万用表测 A/B 间电阻、量终端电阻两端各约 60Ω(并联后)
链路层用串口助手接在总线上抓包能看到完整的请求和响应帧
参数层核对站号、波特率、校验、停止位与从站面板设置完全一致
应用层监控 D8063、核对功能码和地址错误码为 0,数据合理

第一步,断电量电阻。两端终端电阻都接好的情况下,A/B 之间应该是 60Ω 左右(两个 120Ω 并联)。量出来无穷大说明断路或者终端电阻没接,量出来接近 0 说明短路,量出 40Ω 说明多接了一个终端电阻。这一步两分钟,能排掉一大半硬件问题。

第二步,如果手头有 USB 转 485 的工具,直接并在总线上抓包。看不到任何帧,说明 PLC 没发出去,问题在 PLC 侧(通道、D8120、指令有没有被触发);能看到请求但看不到响应,说明从站没回,问题在站号、参数或从站本身;能看到响应但 PLC 报错,说明 PLC 收到的帧有问题,重点查校验和停止位。

第三步,参数核对。这一步没有技巧,就是一项一项对,站号、波特率、数据位、校验位、停止位,五项全部一致。

第四步,程序侧。监控 D8063 看看错误码,核对功能码和地址。

6.2 三个印象比较深的现场

第一个案例是某台仪表的测量值怎么读都是 0。功能码用的 03,地址按手册的 40001 填的 H0000,参数全对。折腾很久之后发现,这台仪表的测量值放在输入寄存器区,要用 04 功能码读,03 读的那块区域虽然地址合法但从来没被写过,所以全是 0。换成 H04 之后立刻正常。

第二个案例是偶发丢帧,一天几次,没有规律。最后查出来是通讯线和一台变频器的输出线在同一线槽里并排走了几米,变频器加速的瞬间干扰最大。把通讯线单独走桥架之后彻底消失。这类问题最难查,因为它符合“时好时坏”的特征,容易被归咎于“设备质量不行”。

第三个案例是写完参数后读回来发现被改了。原因是写入用的 06 功能码,写的是保持寄存器,但这台设备的参数需要先写一个“解锁”寄存器才能被修改,否则写进去的值会被内部逻辑覆盖。这种属于设备自身的设计,只能靠读手册发现。所以写完一定要读回来验证,这是我在所有通讯程序里都会加的一步。

6.3 轮询周期怎么估算

很多人不关注这个数,等到从站数量上来之后发现数据刷新慢得离谱,才回头优化。其实估算很简单,按字节算就行。

以 9600bps、8 数据位、无校验、1 停止位为例,每个字节占 10 个位(1 起始 + 8 数据 + 1 停止)。读 10 个保持寄存器,请求帧是 8 个字节,响应帧是 1+1+1+20+2 = 25 个字节,合计 33 个字节,也就是 330 个位,传输时间约 34ms。再加上帧间静默(3.5 个字符时间,两处约 7ms)和从站的处理延时(典型 10~20ms),单次通讯的实际耗时约 55~60ms。再算上 PLC 扫描周期和握手逻辑占用的一两个扫描周期,实际轮询间隔在 60~80ms 比较合理。

三台从站轮一圈就是 200ms 左右,对于大多数监控场景够用了。如果不够,优化方向有三个:提高波特率(19200 能让传输时间减半)、减少单次读取的点数(把不需要的点砍掉)、合并地址连续的读取(一次读 20 个比读两次 10 个快,因为省掉了帧头和帧间静默)。

提示:把波特率从 9600 提到 19200 之前,先确认总线长度和线材质量撑得住。线长超过几十米、又是普通屏蔽双绞线的情况下,19200 反而更容易出错,宁可降低点数也不要盲目提速。

最后再分享一个我在实际操作中的体会:这套东西真正花时间的从来不是写指令,而是确认从站到底怎么定义它的寄存器和数据格式。程序骨架十分钟就能搭完,剩下的时间基本都在翻手册、试功能码、用已知值反推数据格式。所以我的习惯是,第一次接触一个新品牌的从站,先用串口工具把要用的几个寄存器全部读一遍、写一遍、读回来验证一遍,确认清楚了再动 PLC 程序,这样返工最少。