S7-1200跨项目双边通讯实战:TSEND_C/TRCV_C组态与调试指南
1. 项目背景与核心需求解析
最近在做一个产线改造项目,现场有两台西门子S7-1200 PLC,一台负责控制上料机械手,另一台负责控制下料传送带和码垛单元。这两台设备物理上隔了十几米,但工艺上要求它们必须“协同作战”——机械手抓取工件后,需要实时通知传送带启动,同时传送带上的传感器检测到工件到位后,也要反馈给机械手PLC,以便其准备下一次抓取。这种场景下,两台独立的S1200之间建立稳定、可靠的数据交换通道,就成了项目成败的关键。这就是典型的S7双边通讯需求,而且这两台PLC的程序是分别集成在两个独立的TIA Portal项目文件里的,这就涉及到跨项目的组态和设置。
很多刚接触西门子PLC通讯的朋友,一听到“S7通讯”、“双边”这些词可能就有点发怵,觉得是不是要写一堆复杂的程序、配置一堆看不懂的参数。其实不然,S7-1200之间的S7通讯,尤其是双边通讯,在TIA Portal里已经做得相当“傻瓜化”了,核心思想就是“组态为主,编程为辅”。你不需要去深究底层复杂的网络协议,TIA Portal的硬件组态和网络视图帮你把大部分脏活累活都干了。这个内容的核心价值在于,它能让你在分布式控制系统中,以极低的编程成本,实现PLC间稳定、周期性的数据交换,特别适合那些需要共享状态、命令或过程数据的多机协同场景。
那么,谁需要看这个内容呢?如果你是一名自动化工程师、电气工程师,或者设备维护人员,正在面临多台S7-1200 PLC需要数据交互的问题,或者你的项目结构就是多个独立的TIA项目,那么这篇从硬件组态到程序编写,再到调试排坑的完整指南,就是为你准备的。我会假设你已经有TIA Portal的基本操作经验,比如创建项目、添加设备、编写简单的逻辑块,但即使你是个新手,跟着步骤一步步来,也能把这条路走通。
2. S7通讯技术选型:为什么是“S7双边”?
在动手之前,我们得先搞清楚,为什么在这个场景下要选择“S7双边通讯”(S7 communication with bidirectional connection)。西门子S7-1200支持多种通讯方式,比如TCP、UDP、ISO-on-TCP、Modbus TCP等。每种方式都有其适用场景。
TCP/UDP通讯:更灵活,可以和非西门子设备通讯,但需要你手动编写大量的通讯程序(TSEND_C/TRCV_C等),处理连接建立、数据打包、错误处理等,编程工作量较大,更适合对通讯协议有定制化需求或与第三方设备交互的场景。
S7通讯:这是西门子自家设备之间的一种优化协议,它基于ISO-on-TCP(RFC 1006),但由TIA Portal底层自动管理。它的最大优势就是“组态即通讯”。你只需要在硬件和网络组态中正确建立连接,并在两边PLC中创建好对应的“通讯块”(如PUT/GET,或更现代的TSEND_C/TRCV_C配合S7协议),数据交换就能自动、周期性地进行,无需反复调用指令去建立连接。它简化了编程,提高了可靠性。
而“双边”指的是通讯双方在逻辑上是平等的,都需要主动配置和编程。与之相对的是“单边”通讯,比如一台S7-1200通过GET指令去读取另一台S7-1500的数据,只需要在发起读操作的一方编程和组态,另一方几乎无需额外设置(只需允许PUT/GET访问)。但在我们两台S1200都需要向对方发送数据的场景下,“双边”配置是最自然、最对称的方式。它意味着两台PLC各自都需要定义连接、各自都需要调用发送和接收指令来交换数据。
这里有一个关键点需要明确:虽然我们常说“S7双边通讯”,但在TIA Portal V16及以后版本,更推荐使用TSEND_C和TRCV_C指令来替代传统的PUT/GET指令进行S7通讯。TSEND_C/TRCV_C功能更强大,集成了连接管理,状态反馈更清晰,是西门子主推的方式。所以,我们接下来的实战也将基于这对指令展开。
3. 跨项目组态:硬件与连接配置详解
这是整个设置中最核心、也最容易出错的一环。因为我们的两台PLC位于两个独立的TIA项目中,你无法像在同一个项目里那样,直接拖拽设备到网络视图里自动生成连接。我们需要采用“手动组态连接”的方式。
3.1 准备工作:收集关键参数
在打开TIA Portal之前,请先准备好以下信息,最好用笔记下来:
- PLC_1(例如上料机械手PLC):
- 设备型号(如:CPU 1214C DC/DC/DC)
- IP地址(如:192.168.0.10)
- PROFINET设备名称(如:plc-station-01)
- PLC_2(例如下料码垛PLC):
- 设备型号(如:CPU 1214C DC/DC/DC)
- IP地址(如:192.168.0.20)
- PROFINET设备名称(如:plc-station-02)
- 子网掩码(通常为255.255.255.0)
- 为S7连接分配一个连接ID,这是一个在每台PLC内唯一的数字,用于在程序中标识这个连接。我们假设两边都使用连接ID=1。
3.2 在项目A中组态PLC_1并建立连接
首先,打开包含PLC_1的那个TIA项目。
- 添加与配置PLC_1:在项目树中,确保已正确添加了PLC_1的硬件设备,并为其设置了上述准备好的IP地址和设备名称。
- 进入网络视图:在项目树中双击“设备和网络”,打开网络视图。
- 添加未指定的PLC_2作为通讯伙伴:
- 在右侧“硬件目录”中,导航到“控制器” -> “SIMATIC S7-1200” -> 选择与PLC_2型号完全一致的CPU,将其拖拽到网络视图的空白处。这时,它会显示为一个“未分配”的设备。
- 右键点击这个新添加的、代表PLC_2的设备,选择“属性”。
- 在“属性”窗口的“常规”选项卡下,找到“PROFINET接口[X1]”,在这里手动输入PLC_2的IP地址(192.168.0.20)和子网掩码。注意:这里不要设置设备名称,因为设备名称是在其自身项目中定义的,我们在此仅作IP地址的引用。
- 创建S7连接:
- 在网络视图左上角的“连接”下拉框中,选择“S7连接”。
- 先单击网络视图中的PLC_1的PROFINET接口(绿色小方块),然后按住鼠标不放,拖拽到代表PLC_2的设备的PROFINET接口上再松开。这时会弹出一个“创建S7连接”的对话框。
- 配置连接参数:
- 在“创建S7连接”对话框中,你会看到“本地ID”(Local ID)。这个就是连接ID,我们填写“1”。这个ID非常重要,后续编程指令需要引用它。
- 确保“伙伴”一侧正确显示了PLC_2的IP地址。
- 在“地址详细信息”中,你可以看到“本地TSAP”和“伙伴TSAP”(TSAP: Transport Service Access Point,传输服务访问点)。对于S7-1200之间的S7通讯,通常采用默认的TSAP即可(例如03.00, 03.01),除非有特殊路由需求。我们保持默认。
- 点击“确定”,一条绿色的S7连接线就会出现在两台设备之间。
- 编译并下载:保存项目,对PLC_1的硬件配置进行编译。如果没有错误,将硬件配置下载到实际的PLC_1中。
关键经验:很多人在这一步出错,是因为在项目A中添加PLC_2时,试图去设置它的设备名称或下载硬件配置。请牢记,在项目A中,PLC_2只是一个“影子”,我们只关心它的IP地址,用于建立网络连接指向。它的真实硬件配置存在于项目B中,并由项目B的硬件组态和程序下载管理。
3.3 在项目B中组态PLC_2并建立连接
现在,关闭项目A(或另开一个TIA Portal实例),打开包含PLC_2的TIA项目。接下来的操作与3.2节完全对称,只是角色互换。
- 在项目B中,确保PLC_2的硬件已正确组态,IP地址和设备名称设置正确。
- 在网络视图中,添加一个代表PLC_1(型号、IP为192.168.0.10)的“未指定”设备。
- 创建一条从PLC_2到PLC_1的S7连接。这里有一个至关重要的细节:这条连接的“本地ID”(在PLC_2侧的连接ID)也必须设置为“1”。也就是说,在PLC_1眼里,到PLC_2的连接ID是1;在PLC_2眼里,到PLC_1的连接ID也是1。它们在各自项目内的标识是一致的。
- 同样,检查TSAP地址,保持默认。
- 编译并下载项目B的硬件配置到实际的PLC_2中。
至此,硬件层面的双向连接通道就建立好了。你可以把它理解为在两个项目里,各自画了一张地图,地图上都标注了“从我家(本机)到你家(伙伴)有一条编号为1的秘密通道”。双方的地图合在一起,通道才真正连通。
4. 编程实现:使用TSEND_C与TRCV_C进行数据交换
连接建立后,我们需要在两边PLC的程序中调用指令来收发数据。我们将使用TSEND_C(建立连接并发送)和TRCV_C(建立连接并接收)这一对指令。它们成对使用,分别放在通讯的两端。
4.1 定义发送与接收数据区
在编程之前,先规划好要交换的数据。例如:
- PLC_1需要发送给PLC_2的数据(存放在PLC_1的DB块里,如
DB1):Hand_Finished(Bool):机械手完成一次抓取,信号置位。Workpiece_ID(Int):工件编号。Position_Data(Real):当前位置坐标。
- PLC_2需要发送给PLC_1的数据(存放在PLC_2的DB块里,如
DB1):Conveyor_Ready(Bool):传送带准备就绪。Pallet_Full(Bool):码垛满信号。Sensor_Count(Int):传感器计数。
建议为通讯数据创建单独的全局数据块(DB),并将“优化的块访问”选项取消勾选(即使用“标准”访问方式),这样能确保数据在块中的绝对偏移地址是固定的,便于调试时监控。当然,使用优化访问也可以,但监控时需要知道符号名。
4.2 在PLC_1中编写通讯程序
在PLC_1的项目中,打开主循环组织块OB1(或其他你使用的周期性OB)。
- 发送数据到PLC_2:
- 从指令列表的“通讯” -> “开放式用户通信”中,拖拽
TSEND_C指令到程序段中。 - 配置其背景数据块(如
DB2)。 - 填写引脚参数:
REQ:使用一个上升沿触发发送,例如用M0.0的上升沿。CONT:设置为True(1),保持连接持续打开。LEN:发送数据的字节长度。如果你发送的是整个DB1,且DB1长度为10个字节,这里就填10。也可以填0,表示发送DATA引脚所指向区域的全部长度。CONNECT:指向我们在硬件组态中创建的S7连接。这里需要填写一个指向“TCON_IP_v4”或“TCON_S7”类型连接结构的指针。最简单的方法是:在项目树中,展开PLC_1设备下的“在线和诊断”->“连接”,找到ID=1的S7连接,将其拖拽到CONNECT引脚上,TIA会自动生成一个连接描述符(如"S7_Connection_1")。DATA:指向要发送的数据区,例如P#DB1.DBX0.0 BYTE 10,表示从DB1的第0.0字节开始,共10个字节。
- 从指令列表的“通讯” -> “开放式用户通信”中,拖拽
- 接收来自PLC_2的数据:
- 在同一个OB1中,再拖放一个
TRCV_C指令。 - 配置其背景数据块(如
DB3)。 - 填写引脚参数:
EN_R:设置为True(1),始终使能接收。CONT:设置为True(1)。LEN:期望接收的数据字节长度,应与PLC_2发送的长度一致,例如8个字节。CONNECT:必须指向同一个连接描述符,即"S7_Connection_1"。DATA:指向接收数据区,例如P#DB4.DBX0.0 BYTE 8,用于存放从PLC_2来的数据。
- 在同一个OB1中,再拖放一个
4.3 在PLC_2中编写通讯程序
在PLC_2的项目中,进行完全对称但方向相反的操作。
- 发送数据到PLC_1:
- 使用
TSEND_C,连接ID(CONNECT)同样指向其在项目B中组态的、ID=1的连接描述符(如"S7_Connection_1")。 DATA指向PLC_2的发送DB(如DB1)。
- 使用
- 接收来自PLC_1的数据:
- 使用
TRCV_C,连接ID同样指向同一个连接描述符。 DATA指向PLC_2的接收DB(如DB5)。
- 使用
核心对称性总结:
- 连接ID对称:两边项目中,指向对方的S7连接,其“本地ID”必须相同(我们都用了1)。
- 指令角色对称:PLC_1用
TSEND_C发数据,PLC_2就必须用TRCV_C收这部分数据;反之,PLC_2用TSEND_C发数据,PLC_1就必须用TRCV_C来收。两边的TSEND_C和TRCV_C是成对交叉工作的。 - 数据长度对称:发送方
TSEND_C的LEN(或DATA区域长度)应与接收方TRCV_C的LEN(或DATA区域长度)匹配。
5. 下载、调试与关键问题排查链路
配置和编程完成后,分别将两个项目的硬件配置和程序下载到对应的PLC中。下载后,PLC会自动尝试建立S7连接。
5.1 连接状态监控
这是判断通讯是否成功的第一步。在TIA Portal的“在线和诊断”视图中,查看“连接”选项卡:
- 你应该能看到一条类型为“S7连接”、状态为“已建立”的连接。如果显示“已断开”或“错误”,说明连接未成功建立。
- 可以查看连接详细信息,包括伙伴IP地址、TSAP等,确认与组态一致。
5.2 指令状态位分析
TSEND_C和TRCV_C提供了丰富的状态位,是调试的利器:
TSEND_C:BUSY:为1表示正在发送。DONE:为1表示上一次由REQ上升沿触发的发送已完成。注意:DONE只在完成时一个周期内为1。ERROR/STATUS:如果ERROR为1,查看STATUS字,里面有详细的错误代码。常见错误如“连接无法建立”、“伙伴不可达”等。
TRCV_C:BUSY:为1表示正在接收。NDR(New Data Received):为1表示接收到新数据。这是判断数据是否成功送达的关键信号。通常用NDR的上升沿来触发接收数据的后续处理。ERROR/STATUS:接收错误指示。
5.3 典型问题排查链路
如果通讯失败,可以按照以下链路逐步排查:
物理层与基础网络:
- 检查网线:两台PLC是否通过网线连接到同一个交换机?网线是否完好?交换机指示灯是否正常?
- Ping测试:在连接了编程电脑的网络上,用电脑ping两台PLC的IP地址(192.168.0.10和192.168.0.20)。必须确保都能ping通。如果ping不通,检查IP地址设置、子网掩码、网关(如有)、以及PLC的物理连接。
硬件组态一致性:
- IP地址核对:分别在线查看两台PLC的实际IP地址,是否与两个项目中组态的“伙伴IP地址”完全一致?这是最常出错的地方,特别是在项目A中组态的PLC_2的IP地址,必须等于实际PLC_2的IP地址。
- 连接ID核对:确认两台PLC程序中
TSEND_C/TRCV_C的CONNECT参数指向的连接描述符,其底层的连接ID是否都是1。 - TSAP检查:99%的情况下用默认TSAP即可。但如果修改过,必须确保连接两端的TSAP配对正确(本地TSAP与伙伴TSAP是交叉对应的)。
指令编程与调用:
- 触发条件:检查
TSEND_C的REQ引脚是否确实有上升沿信号?可以用一个定时器或按钮产生一个脉冲测试。 - 连接管理:
CONT引脚是否设置为1(保持连接)?对于S7通讯,通常需要设置为1。 - 数据区匹配:发送和接收的
DATA区域长度和数据类型是否匹配?例如,发送方发送一个Int和一个Real(共6字节),接收方也必须准备至少6字节的区域来接收,并且知道前2字节是Int,后4字节是Real进行解析。 - 背景DB独占性:确保
TSEND_C和TRCV_C的背景数据块是独立的,没有与其他指令共用。
- 触发条件:检查
防火墙与安全设置:
- 如果PLC配备了CP卡或具有防火墙功能,检查是否禁用了S7通讯所需的端口(TCP 102)。S7-1200本体集成的PN口通常无需此设置。
一个实用的调试技巧:先让通讯单向跑通。例如,暂时只调试PLC_1发送到PLC_2。在PLC_1侧,强制一个发送触发信号,并监控TSEND_C的DONE和ERROR。在PLC_2侧,监控TRCV_C的NDR和接收数据区。单向成功后再加上反向的通讯,可以简化问题定位。
6. 性能优化与高级应用注意事项
当基本通讯功能实现后,可以考虑以下方面来优化和深化应用:
6.1 通讯性能与数据一致性
- 发送触发机制:避免在每个扫描周期都触发
TSEND_C发送。这会产生不必要的网络流量和CPU负载。应该只在数据确实发生变化时发送。例如,使用NE(不等于)指令比较当前发送数据区和上一次发送的数据副本,仅在发生变化时产生一个发送脉冲。 - 数据打包:将相关的多个变量打包在一个DB中一次性发送,比每个变量单独建立一次通讯要高效得多。这减少了协议开销和连接管理负担。
- 扫描周期影响:S7通讯处理需要CPU时间。如果交换数据量很大或频率很高,需要注意它是否会影响主程序的扫描周期。可以在CPU属性中查看通讯负载情况。
- 一致性:
TRCV_C的NDR信号表示一组完整的新数据已就绪。在接收方,务必使用NDR的上升沿来将接收数据区的数据一次性复制到你的应用数据区中,这样可以保证你读到的是一个完整、一致的数据快照,而不是在接收过程中被更改的中间状态。
6.2 错误处理与连接恢复
- 连接中断处理:网络闪断或伙伴PLC重启会导致连接断开。
TSEND_C/TRCV_C在CONT=1时,会自动尝试重新建立连接。你需要监控ERROR位和STATUS代码。对于非致命错误(如临时中断),可以记录报警但无需人工干预;对于持续错误,则需要触发停机或安全流程。 - 心跳检测:除了业务数据,可以定期(如每秒)发送一个“心跳”信号(例如一个递增的计数器)。接收方监控这个心跳,如果超过一定时间没有更新,则认为连接异常,即使
ERROR位可能还没报错。这提供了更上层的连接健康状态判断。
6.3 跨项目管理的工程实践
- 文档记录:在两个项目的设计文档中,清晰记录S7连接的参数:伙伴IP、连接ID、TSAP、交换的数据结构(DB编号、变量布局)。这对于后续维护和团队协作至关重要。
- 变量命名规范:为发送和接收DB内的变量使用清晰的命名,如
TX_to_Station02_HandFinish,RX_from_Station01_ConveyorReady,提高程序可读性。 - 仿真测试:在项目初期,可以充分利用TIA Portal的PLC仿真功能(PLCSIM),创建两个仿真实例,分别加载两个项目的程序,在虚拟环境中测试S7通讯逻辑,提前发现组态或编程问题,节省现场调试时间。
通过以上从原理到组态、从编程到调试、从基础到进阶的完整梳理,你应该能够独立完成两台S7-1200 PLC在独立项目间的S7双边通讯设置了。这套方法的核心在于理解“跨项目组态”的本质是对伙伴设备的“引用”,以及编程中连接与数据交换的“对称性”。在实际操作中,耐心和细致的检查往往比技术本身更重要,尤其是在核对IP地址、连接ID这些基础参数时。
