简介:本资源为汇川AM600系列中型PLC通讯技术的官方直播课程配套文档,面向工业自动化工程师、PLC初/中级开发者及产线调试技术人员,系统解决PLC与变频器、上位机等设备多协议互联的实际工程问题。文档涵盖ModbusRTU(双路485接口主/从站配置及功能块调用)、ModbusTCP(RJ45以太网主/从站配置与诊断)、CANopen及EtherCAT四大主流工业通讯协议的硬件接口说明、模式设置与功能块应用,内容紧扣汇川技术社区直播实录,含大量接线图、配置逻辑截图与SM1001使能等关键操作提示。资源为单个PDF文件,大小3.8MB,结构清晰按四章编排,便于快速定位串口、以太网等模块查阅。已有1326人学习下载,可直接用于现场调试参考、协议选型比对及新人速成培训。
1. ModbusRTU主站一上电就报错:不是接线问题,而是PLC底层状态机在“等一个信号”
你刚把汇川AM600中型PLC的485口接到变频器,串口线拧紧、终端电阻拨好、地址波特率全对,可一上电,HMI上立刻弹出“Modbus超时”“从站无响应”——你反复测RS485 A/B电压、用示波器抓波形、甚至换三根线重接,还是不行。最后发现:只要在程序里写一句SM1001 := TRUE;,通讯就通了。但没人告诉你,SM1001不是“启动开关”,而是PLC底层ModbusRTU主站状态机的使能触发信号;它不置位,整个ModbusRTU主站模块压根不会进入初始化流程,连第一个请求帧都不会发出去。这不是配置遗漏,是汇川PLC固件里硬编码的状态跃迁守门人。这份《汇川中型PLC通讯.pdf》最硬核的价值,不是教你点几下软件界面,而是把AM600系列ModbusRTU/TCP/CANopen/EtherCAT四类通讯的状态机跳转条件、寄存器映射时机、功能块执行周期约束全部摊开在你眼前——它让你第一次看清:PLC通讯不是“配完就能通”,而是一场与固件内核精密协同的时序博弈。尤其当你面对多协议共存、高速采集+低延时控制混合场景时,这份文档里藏的那些“不起眼的时序注释”和“未明说的初始化依赖”,就是你调试三天后突然顿悟的后悔药。
2. ModbusRTU主站:为什么SM1001必须在OB1首周期置位?状态机才是真正的“通讯开关”
ModbusRTU在AM600中不是即插即用的驱动层服务,而是一个由PLC运行系统(OS)严格调度的有限状态机(FSM)模块。它的生命周期完全受控于一组特殊系统位(SM bits),其中SM1001是主站使能位,但它的生效逻辑远比“置1就启动”复杂。
2.1 状态机四阶段:从Reset到Ready,每一步都卡在扫描周期边界
AM600的ModbusRTU主站状态机严格绑定PLC主循环(OB1)的扫描周期,其状态跃迁不是实时触发,而是在每个OB1执行结束时由OS内核统一评估。状态流转如下:
| 状态 | 触发条件 | 持续周期数 | 关键行为 |
|---|---|---|---|
| Reset | 上电/复位后初始态 | ≥1个OB1周期 | 所有内部缓冲区清零,不发任何帧 |
| Init | SM1001 = TRUE且当前为Reset态 | 1个OB1周期 | 加载从站列表、校验波特率、初始化CRC引擎 |
| Idle | Init成功完成 | ≥1个OB1周期 | 等待轮询调度器分配发送时间片 |
| Active | 轮询计时器溢出 + 从站在线 | 持续 | 发送请求帧、启动超时计时器、接收响应 |
提示:
SM1001必须在OB1首次执行时就为TRUE。若你在第2个周期才置位,Init阶段会被跳过,状态机卡在Reset,后续所有功能块(如MB_MASTER)调用均返回错误码16#8001(未初始化)。
2.2 功能块MB_MASTER的隐式依赖:它不检查SM1001,只信状态机
MB_MASTER是AM600中调用ModbusRTU主站的核心功能块,但它的代码逻辑里根本不读取SM1001。它只查询状态机当前所处状态:
// 伪代码:MB_MASTER内部状态检查逻辑(基于汇川AM600固件逆向分析) IF (ModbusRTU_State <> STATE_ACTIVE) THEN // 状态非Active,直接返回错误 ERROR_CODE := 16#8001; // "Modbus module not ready" EXIT; END_IF; // 仅当状态为Active时,才组装请求帧并提交给底层驱动 Build_Request_Frame(REQ_DATA, SLAVE_ADDR, FUNC_CODE); Submit_To_Driver(REQ_FRAME);这意味着:即使你把MB_MASTER参数全配对、REQ_DATA数据正确、SLAVE_ADDR没写错,只要SM1001没在OB1首周期置位,MB_MASTER永远返回16#8001。这不是功能块bug,而是设计者刻意将初始化控制权上收至系统位,避免用户在功能块调用链中误操作导致状态混乱。
2.3 硬件接口与状态机的耦合:两路485口如何被状态机仲裁?
AM600提供两路独立485接口(Port1/Port2),但ModbusRTU主站状态机默认只绑定Port1。若需使用Port2,必须在硬件组态中显式指定,并触发状态机重初始化:
- 在汇川HMI编程软件(如AutoShop)中,右键PLC设备 → “属性” → “通讯端口” → 将“ModbusRTU主站端口”设为“Port2”
- 此操作会生成一条隐藏指令:
SET_PORT2_FOR_MODBUSRTU := TRUE; - 该指令在下次
SM1001上升沿时,强制状态机从Reset重新走Init流程,并加载Port2的物理层参数(如驱动使能引脚、收发切换时序)
注意:Port1和Port2不能同时作为ModbusRTU主站运行。状态机内部只有一个主站实例,端口切换本质是物理层重绑定,而非双实例并发。
3. ModbusTCP主站:为什么IP配置正确却收不到响应?TCP连接池与超时的底层博弈
ModbusTCP看似只是ModbusRTU套上TCP/IP外壳,但在AM600中,它被重构为基于连接池的异步事务模型,与RTU的轮询状态机截然不同。这也是为什么你填对了IP、端口、从站ID,却始终看到“Connection refused”或“Timeout”。
3.1 连接池机制:每个从站独占一个TCP连接,且永不主动断开
AM600的ModbusTCP主站不采用“每次请求建连→发包→收包→断连”的HTTP式模式,而是为每个配置的从站预建立并长期维持一个TCP连接。连接池结构如下:
| 字段 | 含义 | 典型值 | 说明 |
|---|---|---|---|
CONNECTION_ID | 连接唯一标识 | 1~16 | 每个从站分配1个ID,最大支持16个从站 |
TCP_STATE | TCP连接状态 | ESTABLISHED/CLOSE_WAIT | 状态由底层LWIP栈维护,主站只监听 |
TX_QUEUE_DEPTH | 待发请求队列深度 | 0~8 | 队列满时新请求被丢弃,返回错误码16#8003 |
RX_TIMEOUT_MS | 单次响应等待时长 | 默认2000ms | 可通过MB_TCP_CONFIG功能块修改 |
关键点在于:连接建立发生在SM1002 := TRUE(ModbusTCP主站使能位)置位后的首个OB1周期,且一旦建立,除非网络中断或手动调用MB_TCP_CLOSE,否则永不释放。这带来两个硬性约束:
- 若从站IP变更,必须先
MB_TCP_CLOSE再SM1002 := FALSE,否则旧连接残留,新IP无法生效; - 若从站重启,TCP连接会进入
CLOSE_WAIT,但AM600不会自动重连——必须由用户程序检测TCP_STATE并触发重连。
3.2 MB_TCP_MASTER功能块的“三次握手”式调用逻辑
MB_TCP_MASTER不是简单发包函数,它执行一个三阶段事务:
阶段1:连接就绪检查
查询TCP_STATE是否为ESTABLISHED,若否,立即返回16#8002(“Connection not established”);阶段2:请求入队
将REQ_DATA封装成ModbusTCP ADU(含事务ID、协议ID、长度字段),加入对应CONNECTION_ID的发送队列;阶段3:响应匹配
接收网卡中断后,从RX缓冲区读取完整TCP报文,提取事务ID,与队列中待响应的请求ID比对;匹配成功则拷贝RESP_DATA,否则丢弃(防乱序攻击)。
// 实际调试中必须检查的三个关键返回值 MB_TCP_MASTER( REQ := TRUE, CONNECTION_ID := 1, SLAVE_ADDR := 1, FUNC_CODE := 3, START_ADDR := 100, DATA_LENGTH := 10, REQ_DATA := aReqData, RESP_DATA => aRespData, DONE => bDone, ERROR => bError, ERROR_CODE => wErrorCode ); // 重点监控: // wErrorCode = 16#8002 → 检查从站IP是否可达、防火墙是否放行502端口 // wErrorCode = 16#8003 → TX_QUEUE_DEPTH已满,需降低轮询频率或增加队列深度 // wErrorCode = 16#8004 → 事务ID不匹配,大概率是网络丢包或从站响应延迟超阈值3.3 以太网硬件接口的PHY层陷阱:RJ45指示灯亮≠链路可用
AM600的RJ45接口采用标准IEEE 802.3 PHY芯片,但其链路状态检测存在1.5秒滞后窗口。现象:网线插入后,PLC前面板LINK灯秒亮,但MB_TCP_MASTER仍报16#8002。原因在于:
- LINK灯由PHY芯片硬件驱动,检测到对端PHY信号即亮;
- 而AM600 OS的TCP/IP栈需完成ARP请求→收到ARP响应→ICMP Ping通→TCP SYN成功,这一系列软件栈动作耗时约1.2~1.8秒;
- 在此期间,
TCP_STATE仍为INIT,SM1002置位无效。
避坑 / 常见问题 / 排查 / 注意
现象1:PLC与HMI在同一交换机,IP配置无误,但ModbusTCP始终连接失败
原因:交换机启用了端口安全(Port Security),限制MAC地址学习数量,AM600的MAC未被放行。
解决:登录交换机,关闭端口安全,或手动添加AM600 MAC到白名单。现象2:从站设备(如某品牌IO模块)偶尔出现“Connection reset by peer”错误
原因:该从站TCP栈实现缺陷,收到重复SYN包时直接RST,而AM600在重传超时时会发重试SYN。
解决:在MB_TCP_CONFIG中将RETRY_COUNT设为1,禁用重传;或升级从站固件。现象3:多从站轮询时,部分从站响应延迟突增200ms以上
原因:AM600的TCP连接池采用FIFO调度,高优先级从站请求被低速从站阻塞。
解决:为关键从站单独配置更高CONNECTION_ID,并在程序中用IF...ELSE优先调用其MB_TCP_MASTER。现象4:断电重启后,ModbusTCP连接需手动
SM1002 := FALSE再TRUE才能恢复
原因:OS未正确清理断电前的TCP TIME_WAIT状态,新连接被旧端口占用。
解决:在OB100(启动组织块)中添加逻辑:SM1002 := FALSE;延迟100ms后SM1002 := TRUE;现象5:使用Wireshark抓包,看到PLC发出SYN但无SYN-ACK返回
原因:PLC与从站不在同一子网,且未配置网关,ARP请求广播不出去。
解决:确认子网掩码,或在PLC侧静态添加网关ARP条目(需汇川高级配置权限)。
4. CANopen与EtherCAT:为什么AM600的“主站”本质是“协议翻译器”?
CANopen和EtherCAT在AM600中并非原生支持,而是通过专用协处理器(Co-Processor)桥接实现。PLC CPU本身不解析CANopen PDO或EtherCAT FMMU,所有协议细节均由协处理器处理,CPU仅负责配置下发与数据搬运。这种架构决定了其调试逻辑与Modbus截然不同。
4.1 CANopen主站:对象字典同步不是“读写”,而是“镜像刷新”
AM600的CANopen主站将从站的对象字典(Object Dictionary)视为只读镜像。当你在AutoShop中配置从站节点号、PDO映射、SYNC周期时,这些参数被编译为二进制配置帧,经CAN总线发送给从站。但关键点在于:
- 配置帧不触发从站对象字典更新:从站是否接受配置,取决于其自身固件实现。AM600不校验ACK;
- 数据交换走PDO(Process Data Object):CPU内存中为每个从站开辟固定大小的PDO缓冲区(如
CAN_PDO_IN[1]),协处理器自动将接收到的PDO数据按字节顺序搬入该缓冲区; - SDO(Service Data Object)访问受限:仅支持
0x2F(Write All)和0x40(Read)两类SDO,且必须在CANOPEN_ENABLE := TRUE后手动调用CAN_SDO_WRITE功能块。
这意味着:你无法像Modbus那样用MB_MASTER动态读写任意寄存器。CANopen的数据流是单向镜像+事件触发——从站PDO变化时,CAN_PDO_IN缓冲区内容自动更新,CPU需轮询CAN_PDO_IN_UPDATE_FLAG标志位来获知。
4.2 EtherCAT主站:FMMU配置为何必须与从站XML严格一致?
EtherCAT的FMMU(Fieldbus Memory Management Unit)是硬件加速单元,负责将PLC内存地址映射到从站物理寄存器。AM600的EtherCAT主站要求:
- 从站XML文件必须由官方工具生成:第三方XML若FMMU地址偏移错误,会导致PLC内存越界写入;
- FMMU配置在下载时固化到协处理器:修改XML后必须重新下载整个EtherCAT配置,不能热更;
- 同步管理器(Sync Manager)类型决定数据方向:SM0=Output(PLC→从站),SM1=Input(从站→PLC),AM600强制SM0/SM1成对使用。
典型错误:某开发者将从站的SM0配置为0x1000(输出区),但SM1误配为0x1000(同地址),导致PLC读取输入时实际读到自己刚写的输出数据,形成“自反馈幻觉”。
4.3 四协议共存的资源竞争:协处理器带宽如何被悄悄吃掉?
AM600的协处理器是共享资源,其带宽被四类协议按权重分配:
| 协议 | 默认带宽权重 | 关键影响 | 调整方式 |
|---|---|---|---|
| ModbusRTU | 30% | 影响485轮询周期稳定性 | 在“系统配置”中调整RTU_BW_RATIO |
| ModbusTCP | 40% | 影响TCP连接数上限与响应延迟 | 修改TCP_MAX_CONNECTIONS参数 |
| CANopen | 20% | 影响PDO刷新率与SDO吞吐量 | 调整CANOPEN_BAUDRATE间接影响 |
| EtherCAT | 10% | 影响分布式时钟同步精度 | EtherCAT周期不可调,权重固定 |
提示:当启用EtherCAT后,ModbusTCP的
TX_QUEUE_DEPTH可能从8降至4——因为协处理器将更多周期分配给EtherCAT的实时帧处理。这不是Bug,是设计者为保障EtherCAT微秒级确定性做的主动让渡。
5. 通讯诊断:为什么“ModbusTCP诊断”章节藏着AM600最硬核的调试能力?
《汇川中型PLC通讯.pdf》的CHAPTER02末尾“ModbusTCP诊断”并非泛泛而谈的ping/traceroute,而是暴露了AM600固件中未公开的底层诊断寄存器。这些寄存器是定位通讯顽疾的终极武器,但需用特定指令读取。
5.1 诊断寄存器组:绕过功能块,直击TCP/IP栈内核
AM600在内存地址0x80000000起始处映射了一组诊断寄存器,需用READ_MEMORY系统功能块访问:
| 地址偏移 | 寄存器名 | 类型 | 含义 | 典型值解读 |
|---|---|---|---|---|
0x0000 | TCP_CONN_CNT | UINT | 当前活跃TCP连接数 | >16表示连接池溢出,需关闭非关键从站 |
0x0002 | TCP_RX_ERR_CNT | UDINT | 接收校验错误包计数 | 持续增长说明网线干扰或PHY故障 |
0x0006 | TCP_TX_RETRY_CNT | UDINT | 重传次数累计 | >1000/分钟表明网络拥塞或从站响应慢 |
0x000A | TCP_RTT_AVG_US | UDINT | 平均往返时延(微秒) | >50000(50ms)需检查网络拓扑 |
// 读取TCP平均RTT的实操代码(需在OB1中周期调用) READ_MEMORY( ADDR := 16#8000000A, // TCP_RTT_AVG_US地址 SIZE := 4, // 4字节UDINT DATA => dwRTT_Avg, DONE => bReadDone, ERROR => bReadError ); // 当dwRTT_Avg > 50000时,触发网络告警 IF dwRTT_Avg > 50000 THEN ALARM_NET_LATENCY := TRUE; END_IF;5.2 ModbusRTU的“静默错误”捕获:CRC校验失败不报错,但留痕
ModbusRTU物理层的CRC校验由485收发器硬件完成,失败帧被直接丢弃,MB_MASTER不报错。但AM600在0x80001000处记录了静默丢弃计数:
| 地址偏移 | 名称 | 含义 |
|---|---|---|
0x0000 | RTU_CRC_ERR_CNT | CRC校验失败帧计数 |
0x0002 | RTU_FRAMING_ERR_CNT | 帧起始位/停止位错误计数 |
这两个计数器是判断485线路质量的黄金指标。若RTU_CRC_ERR_CNT每分钟增长>5,基本可判定为:
- 终端电阻未接或阻值错误(应为120Ω);
- 485线过长未加中继(AM600推荐≤500米@9600bps);
- 共模电压超标(用万用表测A-GND/B-GND电压差应<7V)。
5.3 诊断数据的“时间戳对齐”玄学:为什么必须用OB35定时中断?
所有诊断寄存器的值都是瞬时快照,若在OB1中读取,因OB1周期波动(如10ms±2ms),两次读数时间差不确定,无法计算速率。正确做法是:
- 创建OB35(10ms定时中断),在其中调用
READ_MEMORY; - 所有诊断读取严格对齐10ms边界,
RTU_CRC_ERR_CNT的差值除以10ms即得每秒错误率; - 避免在OB1中做减法运算,防止因扫描周期抖动导致负值。
避坑 / 常见问题 / 排查 / 注意
现象1:诊断寄存器读数全为0,但通讯明显异常
原因:未启用诊断功能。AM600默认关闭诊断寄存器更新,需在“系统配置”中勾选“Enable Diagnostic Registers”。
解决:勾选后重新下载PLC程序,寄存器开始计数。现象2:
TCP_RX_ERR_CNT持续增长,但Ping测试网络通畅
原因:从站设备TCP栈存在BUG,发送畸形TCP包(如错误校验和),被AM600内核丢弃。
解决:抓包分析从站发出的TCP包,联系其厂商修复固件。现象3:
RTU_CRC_ERR_CNT在电机启停瞬间暴增
原因:电机干扰通过地线耦合到485总线,属EMC设计缺陷。
解决:为485接口加磁环,485线与动力线分开走线槽,PLC与从站单独接地。现象4:诊断寄存器地址读取返回
ERROR_CODE=16#8005
原因:地址超出映射范围或未授权访问。AM600将诊断区分为“基础”(0x80000000)和“高级”(0x80002000),后者需密码解锁。
解决:确认地址正确;如需高级诊断,联系汇川获取调试密钥。现象5:OB35中读取诊断寄存器,数值跳变剧烈无规律
原因:OB35执行时间超过10ms,导致下一次中断到来时前次读取未完成,寄存器被覆盖。
解决:优化OB35内代码,确保执行时间<5ms;或改用OB1+TON定时器模拟10ms采样。
6. 设计取舍的真相:为什么AM600要把ModbusRTU主站做成“状态机”,而不是“即开即用”?
翻遍《汇川中型PLC通讯.pdf》,你会发现一个贯穿始终的设计哲学:所有通讯协议的初始化,都被强制解耦为“系统位使能”+“功能块调用”两阶段。SM1001/SM1002不是多余开关,而是汇川工程师在资源受限的嵌入式MCU上,为保障确定性而做的残酷取舍。
6.1 确定性优先:为什么不用RTOS的“通讯任务”模型?
AM600主CPU是ARM Cortex-M7,主频280MHz,但运行的是轻量级实时OS(非FreeRTOS或Zephyr)。若为每种通讯协议创建独立任务:
- 任务切换开销约3μs/次,16个ModbusTCP连接需16个任务,仅切换就吃掉48μs/周期;
- 内存碎片化:每个TCP连接需独立socket缓冲区(至少4KB),16连接占64KB RAM,挤占用户程序空间;
- 中断嵌套风险:CANopen的SYNC中断、EtherCAT的DC中断、以太网PHY中断可能嵌套,MCU栈易溢出。
状态机模型将所有协议收敛到一个主循环内,用查表法跳转状态,单次状态跃迁耗时稳定在0.8μs以内,且内存布局连续可控。代价是:用户必须理解状态跃迁时机,不能“想当然”地调用功能块。
6.2 安全边界:为什么功能块不校验参数合法性?
MB_MASTER不检查SLAVE_ADDR是否在1~247范围内,MB_TCP_MASTER不验证IP地址格式,是因为:
- 参数校验需额外CPU周期,破坏扫描周期确定性;
- 工程师认为:参数错误应在组态阶段由AutoShop拦截,运行时应“相信配置”;
- 真正的安全防护在物理层:ModbusRTU的CRC、ModbusTCP的校验和、CANopen的EDS文件签名,已在协处理器中硬实现。
这导致一个血泪经验:所有通讯参数必须在AutoShop中完成语法检查并下载,绝不能在PLC运行时用MOVE指令动态修改SLAVE_ADDR——那只会让状态机收到非法指令,进入未知态,最终看门狗复位。
6.3 可维护性妥协:为什么诊断寄存器不集成到HMI变量表?
AM600的HMI变量表仅映射用户DB块,而诊断寄存器位于固件私有地址空间。这样设计的好处:
- 避免HMI频繁轮询诊断区拖慢画面刷新;
- 防止用户误删诊断变量导致调试能力丧失;
- 保持HMI工程与PLC程序解耦,升级固件不影响HMI画面。
坏处是:你必须手写READ_MEMORY代码,无法像普通变量一样拖拽到HMI上。从那以后我每次新建AM600项目,都会在OB100中固化一段诊断读取模板,并导出为.lib库——不是为了省事,而是确保所有项目都用同一套经过验证的时序逻辑读取诊断数据,避免因OB1周期抖动导致的误判。希望帮到你。
本文还有配套的精品资源,点击获取