TwinCAT3 EL6021串口自由协议通讯实战:从配置到程序解析

1. 项目概述:当工业PLC遇上串口自由协议

在工业自动化现场,我们经常会遇到一个经典场景:你需要让一台高大上的倍福(Beckhoff)PLC,去和一台“不讲武德”的老旧设备或者一个简单的传感器模块对话。这台老旧设备可能只提供了一个RS232或RS485串口,通讯协议还是厂家自定义的、说明书上只有几行十六进制码的“自由协议”。这时候,TwinCAT3作为基于PC的控制平台,其灵活性就凸显出来了。EL6021串口模块正是为此而生,它就像给PLC这个“大脑”安装了一个标准的“嘴巴”和“耳朵”,专门负责说和听串口这门“方言”。

这个项目的核心,就是打通TwinCAT3通过EL6021模块与外部串口设备(这里用“串口调试助手”软件模拟)之间的数据通道。串口调试助手扮演了那个“老旧设备”的角色,我们可以用它任意发送数据来模拟设备上报,也可以接收数据来验证PLC下发的指令是否正确。整个过程不依赖任何特定的高层协议(如Modbus RTU),完全基于最底层的字节流收发,这就是所谓的“自由协议”通讯。掌握它,意味着你具备了与市面上绝大多数串口设备对接的能力,是工控工程师一项非常实用的基本功。

2. 硬件与软件环境搭建

2.1 核心硬件:EL6021模块详解

EL6021是倍福EtherCAT端子模块家族中的一员,是一个双通道的串行通讯接口模块。每个通道都可以独立配置为RS232或RS485标准,这为项目带来了很大的灵活性。

模块关键参数与选型考量:

  • 接口类型:支持RS232和RS485。如果你的通讯距离在15米以内,且是点对点通讯,RS232足够;如果距离更远,或者需要连接多个从站设备,则必须选择RS485。本项目以最常见的RS232为例。
  • 电气隔离:EL6021的串口通道与背板总线之间有电气隔离,这对于工业环境至关重要,能有效防止地线环路或现场干扰损坏PLC主板。
  • 接线端子:模块自带可插拔的接线端子,接线时务必参考手册。对于RS232,通常我们只使用三线制:TxD(发送数据)、RxD(接收数据)、GND(信号地)。接反了TxD和RxD会导致通讯失败,这是新手常犯的错误。

注意:在给EL6021和外部设备上电前,一定要先完成接线并检查。带电插拔串口线或端子是损坏端口的主要原因之一。

2.2 软件准备:TwinCAT3与串口调试助手

TwinCAT3开发环境:你需要安装完整的TwinCAT3 XAE开发环境。确保TwinCAT3 Runtime已经正确安装并激活。整个项目将在XAE环境内完成配置、编程和调试。

串口调试助手的选择与配置:串口调试助手是模拟外部设备的利器。市面上有很多选择,如SSCOM、AccessPort、格西烽火等,功能大同小异。选择的关键是稳定、能清晰显示十六进制数据。

  • 推荐使用SSCOM:它小巧、免费、历史悠久,功能足够。下载后无需安装,直接运行。
  • 关键配置点
    1. 串口号:在你的电脑上,EL6021模块会被识别为一个或多个COM口(通过EtherCAT主站映射)。你需要在设备管理器中确认这个COM口号(例如COM3)。
    2. 波特率、数据位、停止位、校验位:这些参数必须与TwinCAT3中EL6021的配置绝对一致。通常我们使用“9600,8,N,1”(波特率9600,8位数据,无校验,1位停止位)作为起始测试配置。
    3. 显示与发送格式:务必勾选“十六进制显示”和“十六进制发送”。因为自由协议通讯中,我们直接操作的就是字节(Byte)数组,十六进制格式最直观。

3. TwinCAT3侧工程配置全流程

3.1 添加设备与扫描模块

首先,在TwinCAT3 XAE中创建一个新的“TwinCAT Project”。

  1. 在“Solution Explorer”中,右键点击“Devices”,选择“Add New Item...”,添加一个“EtherCAT Master”设备。
  2. 右键点击新添加的EtherCAT主站,选择“Scan Devices”。确保你的倍福控制器(或运行TwinCAT的PC)已通过网线连接到EtherCAT网络,且EL6021模块已正确上电并接入。
  3. 扫描后,TwinCAT会自动识别网络上的EtherCAT从站。找到EL6021模块(通常显示为“Serial Interface”),将其拖放到主站下方,完成设备的添加。

3.2 深度配置EL6021模块参数

添加模块后,双击EL6021模块图标,进入其配置界面。这里有几个核心配置页签:

1. “Serial” 页签(核心配置):

  • Baud Rate:设置为9600。与串口调试助手保持一致。
  • Data Bits:8。
  • Stop Bits:1。
  • Parity:None。
  • Flow Control:None。在RS232三线制模式下,无需流控。
  • Operation Mode:选择“Free Run”。这是自由协议模式的关键。在此模式下,PLC程序将直接通过过程数据(Process Data)读写串口的收发缓冲区。

2. “Process Data” 页签(数据映射):这是理解EL6021工作原理的重点。模块会生成输入和输出过程数据。

  • Input(输入,PLC读):对应的是从串口接收到的数据。你会看到一个名为“SerialIn”的变量,其数据类型通常是“ARRAY [0..2047] OF BYTE”。这意味着EL6021为接收缓冲区分配了最多2048字节的空间。PLC通过读取这个数组来获取外部设备发来的数据。
  • Output(输出,PLC写):对应的是向串口发送的数据。你会看到一个名为“SerialOut”的变量,类型也是字节数组。PLC将需要发送的数据写入这个数组,EL6021模块会自动将其通过串口发送出去。

3. “Online” 页签(高级设置):

  • Buffer Settings:这里可以配置接收超时(Receive Timeout)和发送超时(Send Timeout)。例如,设置接收超时为100ms,意味着如果100ms内没有收到任何新字节,模块会认为一帧数据结束(这对于判断数据包边界有参考意义,但自由协议中帧的判断主要靠程序逻辑)。

配置完成后,点击“Apply”或“OK”,TwinCAT会自动在“POUs”文件夹下生成对应的IO映射变量,例如EL6021_SerialInEL6021_SerialOut。我们将在程序里直接使用这些变量。

3.3 编写自由协议解析程序

自由协议的核心在于程序逻辑。我们需要编写功能块(Function Block)来管理数据的发送和接收。

1. 发送功能块(FB_SendSerial):这个功能块负责将任意长度的字节数组发送出去。

FUNCTION_BLOCK FB_SendSerial VAR_INPUT bSendTrigger: BOOL; // 发送触发信号,上升沿有效 pData: POINTER TO BYTE; // 指向待发送数据数组的指针 nDataLen: UINT; // 待发送数据的长度 END_VAR VAR_OUTPUT bBusy: BOOL; // 发送忙标志 bDone: BOOL; // 发送完成标志 END_VAR VAR fbRTrig: R_TRIG; // 上升沿检测 nSendIndex: UINT := 0; // 发送索引 tSendDelay: TON; // 发送延时,用于控制字节间间隔(可选) END_VAR // 实现逻辑 fbRTrig(CLK:=bSendTrigger); IF fbRTrig.Q THEN // 触发发送,初始化状态 nSendIndex := 0; bBusy := TRUE; bDone := FALSE; END_IF IF bBusy THEN // 将数据逐个字节复制到EL6021的输出缓冲区 // 注意:这里假设EL6021_SerialOut数组足够大,且我们采用“覆盖式”发送。 // 更复杂的实现可以包含缓冲区状态检查。 IF nSendIndex < nDataLen THEN EL6021_SerialOut[nSendIndex] := pData^[nSendIndex]; nSendIndex := nSendIndex + 1; // 可以在此处添加小延时(如tSendDelay)来控制发送速率,避免缓冲区溢出 ELSE // 数据复制完毕 bBusy := FALSE; bDone := TRUE; // 在实际应用中,可能需要触发模块的“发送”命令(如果模块支持), // 但在Free Run模式下,数据写入输出缓冲区后,模块会自动发送。 // 清空发送完成标志(可选,取决于使用模式) // bDone := FALSE; END_IF END_IF

实操心得:在自由协议发送中,控制发送节奏很重要。如果一次性将大量数据写入EL6021_SerialOut,模块会以最高波特率连续发送。对于某些反应慢的设备,可能导致数据丢失。一种稳健的做法是使用定时器,每10-20ms发送一个字节,或者使用模块提供的“发送缓冲区空”标志位进行流控。

2. 接收与解析功能块(FB_RecvSerial):接收端更复杂,需要处理数据流的拼接和帧的识别。

FUNCTION_BLOCK FB_RecvSerial VAR_INPUT bEnable: BOOL; // 功能块使能 nMaxFrameLen: UINT := 256; // 预期最大帧长 tFrameTimeout: TIME := T#200ms; // 帧超时时间,用于判断一帧结束 END_VAR VAR_OUTPUT aReceivedFrame: ARRAY[0..255] OF BYTE; // 存储接收到的一帧数据 nFrameLen: UINT; // 接收到的帧长度 bNewFrame: BOOL; // 新帧到达标志(上升沿有效) END_VAR VAR aBuffer: ARRAY[0..511] OF BYTE; // 内部循环缓冲区,比最大帧长大 nBufferHead: UINT := 0; // 缓冲区头指针(写索引) nBufferTail: UINT := 0; // 缓冲区尾指针(读索引) tLastDataTimer: TON; // 上次收到数据的计时器 bInFrame: BOOL; // 是否正在接收一帧 END_VAR // 主逻辑:持续将EL6021输入缓冲区数据搬移到内部缓冲区 IF bEnable THEN FOR i := 0 TO 2047 DO // 遍历EL6021的输入缓冲区 IF EL6021_SerialIn[i] <> 0 THEN // 简单判断是否有新数据(0可能也是有效数据,此法不严谨,仅示例) aBuffer[nBufferHead] := EL6021_SerialIn[i]; nBufferHead := (nBufferHead + 1) MOD SIZEOF(aBuffer); // 复位超时计时器,表示收到了数据 tLastDataTimer(IN:=TRUE, PT:=tFrameTimeout); END_IF END_FOR // 清空EL6021输入缓冲区,防止重复处理(重要!) MEMSET(ADR(EL6021_SerialIn), 0, SIZEOF(EL6021_SerialIn)); END_IF // 帧提取逻辑:当超时发生,认为一帧数据结束 IF tLastDataTimer.Q THEN // 超时发生,帧结束 IF nBufferTail <> nBufferHead THEN // 缓冲区有数据 nFrameLen := 0; WHILE (nBufferTail <> nBufferHead) AND (nFrameLen < nMaxFrameLen) DO aReceivedFrame[nFrameLen] := aBuffer[nBufferTail]; nFrameLen := nFrameLen + 1; nBufferTail := (nBufferTail + 1) MOD SIZEOF(aBuffer); END_WHILE bNewFrame := TRUE; // 产生新帧信号 END_IF tLastDataTimer(IN:=FALSE); // 复位计时器 ELSIF NOT tLastDataTimer.Q THEN bNewFrame := FALSE; // 保持新帧信号为低 END_IF

注意事项:上述接收示例使用了“超时判帧”法,这在很多自定义协议中很常见。但这不是唯一方法。更可靠的方法是根据协议规范来判帧,例如:

  • 固定长度帧:收到指定数量的字节即为一帧。
  • 特定头尾字符:如以0xAA 0x55开头,以0x0D 0x0A结尾。程序需要在缓冲区中搜索这些标志。
  • 长度字节:帧的第一个或第二个字节代表后续数据长度。程序先读长度,再读取相应数量的字节。

你需要根据实际设备的协议文档,来实现对应的帧解析逻辑。

4. 实战:与串口调试助手进行联调

配置和编程完成后,进入最关键的联调阶段。

4.1 建立物理连接与软件链接

  1. 硬件连接:使用一根RS232串口线(或USB转RS232线),连接EL6021模块的Channel 1端口与电脑的COM口(或USB口)。确保TxD-RxD交叉连接,GND直连。
  2. TwinCAT激活配置:在TwinCAT XAE中,将配置下载到控制器(Ctrl + F7),然后激活Free Run模式(Ctrl + F8)。此时,EL6021模块的配置生效。
  3. 串口调试助手设置:打开SSCOM,选择EL6021映射到电脑的COM口(如COM3),设置波特率等参数与TwinCAT配置一致。点击“打开串口”。

4.2 数据收发测试与调试技巧

测试1:PLC发送,调试助手接收在PLC程序中,实例化FB_SendSerial,并准备一段测试数据,例如[0x01, 0x03, 0x00, 0x00, 0x00, 0x02, 0xC4, 0x0B](这是一个模拟的Modbus RTU读取命令)。触发bSendTrigger

  • 预期现象:在SSCOM的接收区,以十六进制形式看到这8个字节。
  • 问题排查:如果收不到,检查:1) 串口号是否正确;2) 波特率等参数是否一致;3) 接线(TxD/RxD是否接反);4) TwinCAT是否已激活;5) PLC程序是否运行。

测试2:调试助手发送,PLC接收在SSCOM的发送框中,输入一段十六进制数据,如[0x01, 0x03, 0x04, 0x00, 0x01, 0x00, 0x02, 0xXX, 0xXX](模拟回复),点击“发送”。

  • 预期现象:在PLC程序中,FB_RecvSerial功能块的bNewFrame信号会置位一次,aReceivedFrame数组中存储着接收到的数据,nFrameLen为发送的字节数。
  • 问题排查:如果PLC收不到,检查:1) EL6021的接收缓冲区EL6021_SerialIn在在线监控中是否有数据变化(这是最直接的诊断);2) 接收功能块的使能bEnable是否为TRUE;3) 帧超时时间tFrameTimeout是否设置过短,导致数据未收完就超时复位。

调试高级技巧:使用在线监控与示波器

  • TwinCAT Scope / Online Data:这是最强大的调试工具。你可以将EL6021_SerialIn/Out、接收功能块内部的缓冲区指针、状态标志等关键变量添加到监控表或Scope中,图形化地观察数据流动和状态变化,特别是对于判断帧边界和程序逻辑时序异常有帮助。
  • 逻辑分析仪或USB串口监听器:如果通讯问题非常棘手,可以在物理线路上并联一个USB串口监听工具,或者使用逻辑分析仪抓取RS232线路上的实际波形。这可以让你确认数据是否真的从一端发送到了线路上,以及线路上的信号质量(波特率是否精确、波形是否畸变)。

5. 常见问题与深度排查指南

自由协议通讯调试中,90%的问题集中在以下几个方面。这里提供一个速查清单和深度排查思路。

问题现象可能原因排查步骤与解决方案
完全无通讯1. 物理连接错误(线缆、端口)
2. 电源未接通
3. COM口被占用或选择错误
1. 使用万用表检查线缆通断,确认TxD/RXD交叉。
2. 检查EL6021模块电源指示灯和EtherCAT状态指示灯。
3. 关闭所有可能占用串口的软件(包括另一个串口助手、TwinCAT本身如果在线监控了COM口也会占用),在设备管理器中确认端口号。
能发送不能接收,或反之1. TxD/RxD接线接反
2. 地线(GND)未连接
3. 程序逻辑错误(如缓冲区未清空)
1.这是最高频错误!交换TxD和RxD线再试。
2. 确保发送端和接收端的GND可靠连接。
3. 对于接收,检查是否在读取EL6021_SerialIn后将其清空,否则会重复处理旧数据。
数据乱码或部分丢失1. 波特率、数据位、停止位、校验位不匹配
2. 电气干扰(RS485未接终端电阻)
3. 程序发送/接收过快,缓冲区溢出
1. 双端配置逐字核对,一个标点都不能错。
2. 对于RS485长距离通讯,在总线两端(仅两端)各接一个120Ω终端电阻。
3. 在发送端加入延时;在接收端检查EL6021模块的缓冲区大小,并确保PLC程序读取速度跟得上。
帧数据被拆散或合并1. 帧判断逻辑有误(超时时间不合理)
2. 发送端数据流中间有停顿
1. 调整tFrameTimeout。如果设备响应慢,就加长(如500ms);如果数据是连续burst,就缩短(如10ms)。
2. 使用协议规定的帧头、帧尾或长度信息进行判帧,这是最可靠的方式。
通讯不稳定,时好时坏1. 接地不良,引入共模干扰
2. 电源噪声大
3. 线缆质量差或过长(接近极限)
1. 改善接地,确保通讯双方共地良好。
2. 为设备使用稳压电源或加装滤波器。
3. 换用带屏蔽的优质双绞线,并确保屏蔽层单点接地。对于RS232,缩短距离;对于RS485,检查终端电阻。

深度排查心得:分层隔离法当遇到复杂问题时,不要眉毛胡子一把抓。采用分层隔离法:

  1. 硬件层:先用串口调试助手自发自收(短接TxD和RxD),排除电脑和软件问题。再用两台电脑互发,排除线缆和接口问题。最后接入EL6021和PLC。
  2. 配置层:确保TwinCAT中EL6021的配置与串口助手完全一致,包括所有高级选项(如流控)。
  3. 数据链路层:在TwinCAT在线监控中,直接观察EL6021_SerialInEL6021_SerialOut这两个最底层的变量。如果这里的数据都不对,问题肯定在配置或硬件。如果这里的数据正确,但你的应用程序读不到,问题就在你的程序逻辑。
  4. 应用层:单步调试你的发送和接收功能块,检查指针操作、循环逻辑、状态机切换是否正确。特别是处理字节数组时,边界条件(如数组越界)很容易导致程序跑飞。

最后,自由协议通讯的稳定性,很大程度上取决于你对协议本身的理解和对异常情况的处理。在工业现场,一定要在程序中加入完善的超时重发、数据校验(如CRC)、错误计数和报警机制。这样,当通讯偶尔受到干扰时,系统能够自我恢复,而不是彻底瘫痪。EL6021模块配合TwinCAT3提供的这套底层接口,给了工程师最大的灵活性去实现这些 robust 的设计,这也是它相比一些封装好的协议驱动更具价值的地方。