去年接手一个工业温控系统改造项目时,第一次深度使用三菱FX5U的RS485通信功能。原本以为这种基础通信应该开箱即用,结果在ASCII模式下硬是折腾了72小时才调通。本文将完整还原从硬件配置到软件调试的全过程,特别针对那些手册里没写但实际会要命的细节。
RS485通信在工业现场就像老电工的万用表——看似简单但处处藏着门道。FX5U系列作为三菱新一代PLC,其通信模块的配置逻辑与老款FX系列有显著差异。ASCII模式相比RTU模式更易调试(能直接看到原始报文),但对参数配置的要求也更为苛刻。
FX5U本体标配并没有RS485接口,必须通过扩展模块实现。项目中选用的是FX5-485ADP模块,这个火柴盒大小的设备藏着几个关键特性:
模块安装时要注意:
模块端子排定义如下表:
| 端子标记 | 功能说明 | 连接目标 | 线径要求 |
|---|---|---|---|
| SDA | 发送数据正极 | 设备A线 | 0.3-2.0mm² |
| SDB | 发送数据负极 | 设备B线 | 0.3-2.0mm² |
| RDA | 接收数据正极 | 悬空不接 | - |
| RDB | 接收数据负极 | 悬空不接 | - |
| SG | 信号地 | 设备GND | 必须连接 |
血泪教训:刚开始按FX3U的经验把RDA/RDB也接上,结果出现自发自收的"回声"现象。后来查证FX5-485ADP采用独立收发电路设计,与常规485芯片的收发使能控制逻辑不同。
新建工程时关键参数选择:
模块参数配置路径:
导航树 → 参数 → FX5-485ADP → 基本设置

完整通信初始化代码如下(带详细注释):
st复制// 通信配置数据结构体初始化
RS485Config := _RS485_CONFIG(
CHANNEL := 1, // 通道号(1-4)
BAUDRATE := 9600, // 波特率选择(实际使用19200更稳定)
DATABIT := 7, // ASCII模式必须7位数据位!
PARITY := 'EVEN', // 校验方式:EVEN/ODD/NONE
STOPBIT := 1, // 停止位长度
HEADER := '', // 报文前缀(如$等)
TERMINATOR := CR, // 结束符:CR/LF/CRLF
TIMEOUT := 100, // 接收超时(单位ms)
INTERCHAR := 5 // 字符间隔超时(单位ms)
);
// 端口开启函数
RS485_OPEN(RS485Config);
// 错误处理(必须添加)
IF RS485_STATUS() <> 0 THEN
_WEBLOG('端口打开失败,错误码:' + INT_TO_STRING(RS485_STATUS()));
// 此处添加故障处理逻辑
END_IF;
参数设置要点:
标准发送程序模板:
st复制// 构建查询指令(示例:读取温控器PV值)
Command := STRCONCAT(
'01', // 设备地址
'RDD', // 读数据指令
'0100', // 数据地址
CR // 结束符
);
// 发送指令
RS2_SEND(
CHANNEL := 1,
DATA := Command,
LENGTH := STRLEN(Command), // 自动计算长度
COMPLETE => SendDone // 发送完成标志位
);
// 等待发送完成(超时处理)
TIMER(IN := NOT SendDone, PT := T#500ms);
IF TIMER.Q THEN
_WEBLOG('发送超时!');
// 重发或报错处理
END_IF;
接收程序的完整异常处理方案:
st复制// 接收缓冲区定义
VAR
RecvBuffer : STRING(256); // 足够大的缓冲区
RecvLen : INT;
RetryCount : INT := 0;
END_VAR
// 接收逻辑
IF RS2_RECEIVE(
CHANNEL := 1,
DATA := RecvBuffer,
LENGTH := RecvLen // 返回实际接收长度
) THEN
// 成功接收处理
_WEBLOG('原始报文:' + RecvBuffer);
// 数据有效性检查(示例)
IF STRLEN(RecvBuffer) < 10 THEN
_WEBLOG('报文长度异常');
RETURN;
END_IF;
// 提取有效数据(示例格式:"01AAB+0234")
TempStr := STRMID(RecvBuffer, 5, 4); // 注意:STRMID从0开始索引!
_WEBLOG('温度原始值:' + TempStr);
// ASCII转浮点数
IF ASCII_TO_REAL(TempStr, RealValue) = 0 THEN
_WEBLOG('数据转换失败');
ELSE
PV := RealValue; // 更新过程值
END_IF;
RetryCount := 0; // 重置重试计数器
ELSE
// 接收失败处理
RetryCount := RetryCount + 1;
IF RetryCount > 3 THEN
// 触发报警
Alarm := TRUE;
END_IF;
END_IF;
USB转485调试器(推荐型号:FTDI USB-RS485-WE-1800-BT)
PLC内置诊断工具
示波器观测(关键故障时使用)
| 故障现象 | 可能原因 | 解决方案 |
|---|---|---|
| 接收数据全为乱码 | 波特率/校验位不匹配 | 用示波器测量实际波特率 |
| 偶尔丢失报文 | 电磁干扰 | 检查屏蔽层接地,增加磁环 |
| 发送成功但无响应 | 接线极性错误 | 交换A/B线测试 |
| 通信距离短 | 终端电阻未启用 | 末端设备启用120Ω终端电阻 |
| 特定字符传输错误 | 信号反射 | 降低波特率或缩短通信距离 |
超时参数调整:
通信协议优化:
程序结构改进:
经过这个项目的锤炼,总结出RS485通信的"三要素法则":
这套方案后续被成功应用到:
对于需要更高可靠性的场景,建议考虑:
调试通信就像医生问诊,需要系统性地排除各种可能性。记得第一次看到温控数据正确显示在HMI上时,那种成就感比当年毕业设计通过还强烈。工业通信的魅力就在于此——把物理世界的信号变成可操作的数字信息。