简介这份资源面向工业自动化工程师与TwinCAT开发者聚焦倍福PLC与ZAPI控制器之间基于CAN2.0协议的通信实现解决两类设备在分布式控制系统中报文交换、指令下发与状态回传的配置难题。压缩包共79个文件约9.13MB以compiled-library库文件、tcdut与tcpou程序单元、plcproj工程文件、xml配置及docx说明文档为主另含sln解决方案与tmc等TwinCAT工程配套文件便于直接导入或参考搭建。文档部分讲解TwinCAT中CAN通道配置、波特率匹配通常500kbps、报文格式定义与错误处理程序示例则演示如何调用ZAPI通信库发送和接收CAN消息实现电机速度或位置控制。已有480人学习适合需要快速理解通信流程、复用工程模板并排查物理层与逻辑层问题的开发者参考。1. 倍福PLC与ZAPI控制器CAN2.0通信从接线到收发一套可复现的落地路径一台AGV或电动叉车上倍福BeckhoffPLC 负责整车逻辑调度ZAPI 控制器负责电机驱动与液压动作两者之间靠 CAN2.0 总线交换数据。现场最常见的诉求就一句话PLC 能不能稳定读到 ZAPI 的电池电压、电机转速、故障码同时把速度给定和使能指令发下去。这个标题对应的就是这套通信链路的文档与程序实现。它适合正在做工业车辆电控集成的工程师也适合第一次接触 ZAPI 私有 CAN 协议、手里只有 TwinCAT3 和一台 ZAPI 控制器的人。下面按“总线怎么接、报文怎么定、TwinCAT3 怎么配、程序怎么写、坑在哪”的顺序讲透。2. CAN2.0 物理层与 ZAPI 报文结构先搞清楚帧里装的是什么2.1 CAN2.0A 与 CAN2.0B 的选型边界CAN2.0 分两个版本CAN2.0A 用 11 位标识符CAN2.0B 用 29 位标识符。ZAPI 控制器在工业车辆上普遍走 CAN2.0B 扩展帧因为它的报文 ID 需要携带节点地址和功能码信息。倍福的 CAN 端子模块如 EL6751、CX 系列内置 CAN 口两种帧格式都支持但配置时必须和 ZAPI 侧一致否则会出现“总线有波形、PLC 收不到数据”的玄学现象。选型上如果 ZAPI 控制器手册标注的是 29 位 IDTwinCAT3 里就必须把 CAN 口设为扩展帧模式。常见做法是在 TwinCAT3 的 CAN 设备树里勾选“Extended Frame”而不是靠程序里判断。这个设置错了后面所有报文解析都是白费功夫。2.2 ZAPI 报文的组成与字节序ZAPI 的 CAN 报文遵循 CANopen 风格但并非标准 CANopen它有自己的 PDO 映射。一条典型报文包含29 位 ID、数据长度码 DLC通常 8 字节、以及 8 字节数据区。数据区里每个字节或每两个字节对应一个物理量比如电池电压、电机温度、转速给定。字节序是第一个大坑。ZAPI 多数参数用大端Motorola格式而倍福 PLC 的变量默认是小端Intel。如果直接把两个字节拼成一个 INT数值会完全不对。常见做法是在 PLC 程序里用移位和掩码手动重组或者调用 TwinCAT3 的字节交换函数。参数字节位置数据类型字节序物理量换算电池电压Byte0-1UINT16大端0.1V/bit电机转速Byte2-3INT16大端1rpm/bit电机温度Byte4INT8单字节1℃/bit故障码Byte5UINT8单字节查表状态字Byte6-7UINT16大端位定义这张表是通用参考具体偏移要以 ZAPI 控制器型号对应的手册为准。不同型号的 PDO 映射可能不同但字节序和换算逻辑是相通的。2.3 总线终端电阻与波特率CAN2.0 总线两端各需要 120Ω 终端电阻中间节点不能加。现场经常遇到“短距离能通、长距离丢帧”十有八九是终端电阻只焊了一端或者用了不带屏蔽的双绞线。波特率方面ZAPI 常用 250kbps 或 500kbps倍福侧必须设成一样。TwinCAT3 里改波特率在 CAN 设备的“General”标签页改完要重新激活配置。提示用万用表测 CAN_H 和 CAN_L 之间的电阻断电状态下应该是 60Ω 左右两个 120Ω 并联。如果测到 120Ω说明只接了一个终端电阻。3. TwinCAT3 侧配置从扫描设备到映射变量3.1 新建 CAN 设备与波特率设置在 TwinCAT3 的 I/O 配置里右键“Devices”添加 CAN 设备。如果是 EL6751 端子模块它会自动出现在 EtherCAT 树下。添加后双击 CAN 设备在“General”里设置波特率在“CAN Settings”里勾选扩展帧。这一步没有代码但参数错了后面全错。配置完成后激活配置TwinCAT3 会尝试扫描总线上的节点。如果 ZAPI 控制器已上电且接线正确扫描结果里能看到它的 CAN ID。如果扫不到先查终端电阻和波特率再查 ZAPI 是否处于 CAN 通信使能状态。3.2 用 PLC 变量链接 CAN 报文TwinCAT3 的 CAN 报文通过“CAN Rx/Tx”缓冲区与 PLC 变量链接。常见做法是建一个结构体变量把 8 字节数据区映射进去。下面是一个 ST 语言的变量声明示例TYPE ZAPI_RxData : STRUCT BatteryVoltage : UINT16; // 原始值需除以10 MotorSpeed : INT16; // 原始值单位rpm MotorTemp : INT8; // 单位℃ FaultCode : UINT8; // 故障码 StatusWord : UINT16; // 状态位 END_STRUCT END_TYPE这个结构体只是逻辑映射实际链接时要把 CAN 接收缓冲区的字节按偏移对应到结构体成员。TwinCAT3 的“Link Variables”功能可以手动指定偏移也可以写程序解析。手动链接适合报文固定的场景程序解析适合需要动态处理的场景。3.3 字节序转换的两种写法如果 ZAPI 用大端而 PLC 用小端必须转换。第一种写法用 TwinCAT3 内置函数nVoltage : SWAP16(wRawVoltage); // 16位字节交换第二种写法手动移位nVoltage : (wRawVoltage AND 16#00FF) * 256 (wRawVoltage AND 16#FF00) / 256;两种写法效果一样第一种更简洁。注意 SWAP16 只交换 16 位32 位要用 SWAP32。转换后再做物理量换算比如电压除以 10 得到实际伏特值。注意不要在 HMI 上直接显示原始值现场调试时容易误判。先换算成物理量再显示能省很多排查时间。4. ZAPI 侧参数与收发程序让数据真正跑起来4.1 ZAPI 控制器的 CAN 通信使能ZAPI 控制器出厂时 CAN 通信可能未使能需要用 ZAPI 的手持编程器或 PC 软件如 ZAPI Console进入参数菜单找到 CAN 相关配置项设置节点地址、波特率、以及 PDO 映射。节点地址决定了报文 ID 的偏移波特率必须和倍福侧一致。常见做法是先把 ZAPI 设成“CAN 通信使能”再设波特率最后确认 PDO 映射表。如果 ZAPI 侧有“CAN 超时”参数建议设成 500ms 以上避免倍福 PLC 启动慢导致 ZAPI 报通信故障。4.2 倍福 PLC 发送速度给定的程序发送方向PLC 要把速度给定和使能指令发给 ZAPI。下面是一个 ST 语言的发送程序片段// 速度给定0-3000rpm 映射到 0-30000 nSpeedSetpoint : REAL_TO_INT(nTargetSpeed * 10); // 使能位和方向位组合成控制字 wControlWord : 16#0001; // bit0使能bit1方向 IF bDirection THEN wControlWord : wControlWord OR 16#0002; END_IF // 填充发送缓冲区 abyTxBuffer[0] : INT_TO_BYTE(nSpeedSetpoint / 256); // 高字节 abyTxBuffer[1] : INT_TO_BYTE(nSpeedSetpoint MOD 256); // 低字节 abyTxBuffer[2] : INT_TO_BYTE(wControlWord / 256); abyTxBuffer[3] : INT_TO_BYTE(wControlWord MOD 256);这段代码把速度给定拆成高低字节按大端顺序放入发送缓冲区。控制字的 bit0 是使能bit1 是方向具体位定义要查 ZAPI 手册。发送周期建议 10ms 到 20ms太快没必要太慢响应迟钝。4.3 接收解析与故障码处理接收方向PLC 要解析 ZAPI 发来的状态报文。下面是一个解析程序片段// 从接收缓冲区重组电池电压 wRawVoltage : BYTE_TO_UINT(abyRxBuffer[0]) * 256 BYTE_TO_UINT(abyRxBuffer[1]); rBatteryVoltage : UINT_TO_REAL(wRawVoltage) / 10.0; // 重组电机转速有符号 nRawSpeed : BYTE_TO_INT(abyRxBuffer[2]) * 256 BYTE_TO_INT(abyRxBuffer[3]); nMotorSpeed : nRawSpeed; // 故障码 byFaultCode : abyRxBuffer[5]; IF byFaultCode 0 THEN bFaultActive : TRUE; END_IF解析时注意有符号数的处理。INT16 的负值在重组时要保证符号位正确否则会出现“电机反转时转速显示为正”的问题。故障码建议做一个查表功能块把常见故障码映射成文字描述方便 HMI 显示。提示接收程序里加一个超时计数器如果连续 500ms 没收到 ZAPI 报文置位通信故障标志。这个后悔药能帮你快速定位是总线断了还是 ZAPI 死机了。5. 避坑与排查CAN2.0 通信翻车现场实录5.1 总线能通但数据全是 0现象TwinCAT3 扫描到了 ZAPI 节点接收缓冲区有数据变化但解析出来的物理量全是 0。原因字节序搞反了或者 PDO 映射的偏移量不对。ZAPI 的报文 ID 对了不代表数据区偏移对了。解决先用 CAN 分析仪如周立功 CAN 卡抓原始报文对照 ZAPI 手册确认每个字节的含义。确认字节序后在 PLC 里加一个“原始值监视”变量逐步排查。5.2 短距离正常长距离丢帧现象台架上通信正常装车后超过 5 米就开始丢帧HMI 上数据跳变。原因终端电阻只接了一端或者线缆没用双绞屏蔽线或者波特率太高。解决断电测 CAN_H 和 CAN_L 之间电阻应为 60Ω。换双绞屏蔽线屏蔽层单端接地。如果还不行把波特率从 500kbps 降到 250kbps。5.3 ZAPI 报“CAN 超时”故障现象ZAPI 控制器报通信超时电机无法使能但倍福侧看总线负载正常。原因ZAPI 的 CAN 超时参数设得太短倍福 PLC 启动或重启期间没有及时发报文。解决把 ZAPI 的 CAN 超时参数从 100ms 改成 500ms 或 1000ms。同时在 PLC 程序里加一个“通信就绪”标志启动完成后才发使能指令。5.4 电机转速显示为负值但实际正转现象HMI 上电机转速显示为负但实际电机正转。原因INT16 重组时符号位处理错误或者 ZAPI 的转速定义和 PLC 的符号约定相反。解决检查重组代码确保高字节的 bit7 被正确识别为符号位。如果 ZAPI 定义正转为负值在 PLC 里取反即可。5.5 TwinCAT3 激活配置后 CAN 设备报错现象TwinCAT3 激活配置时 CAN 设备报“Device not found”或“Sync error”。原因EL6751 端子模块的固件版本和 TwinCAT3 版本不匹配或者 EtherCAT 总线没同步。解决检查 EL6751 的固件版本必要时用 TwinCAT3 的固件更新工具升级。确认 EtherCAT 主站和从站都处于 OP 状态后再激活 CAN 配置。6. 进阶技巧用示波器抓 CAN 波形验证通信质量6.1 为什么需要看波形CAN 通信的很多问题在软件层面看不出来比如信号反射、共模干扰、地电位差。示波器能直接看到 CAN_H 和 CAN_L 的差分波形判断信号质量。我一般会在现场调试时带一个便携示波器遇到“时通时不通”的问题先看波形再查代码。6.2 示波器设置与波形判读用双通道示波器CH1 接 CAN_HCH2 接 CAN_L两个通道都设成 5V/div时基设成 20us/div。触发方式选“正常”触发电平设在 2.5V 左右。正常的 CAN 波形应该是清晰的差分方波显性电平逻辑 0时 CAN_H 约 3.5V、CAN_L 约 1.5V隐性电平逻辑 1时两者都约 2.5V。如果波形出现振铃、过冲、或者上升沿变缓说明终端电阻不匹配或线缆太长。如果波形上有周期性尖峰说明附近有变频器或电机干扰需要检查屏蔽和接地。波形现象可能原因处理方式振铃明显终端电阻不匹配检查两端 120Ω上升沿变缓线缆过长或节点过多缩短线缆或加中继周期性尖峰电磁干扰检查屏蔽和接地差分幅值不足收发器供电不足检查 5V 供电6.3 用 CAN 分析仪做长期监测示波器适合短时排查长期监测建议用 CAN 分析仪。周立功的 CAN 卡配合上位机软件可以记录总线负载、错误帧、报文周期。我一般会在现场跑 24 小时监测看有没有偶发错误帧。如果错误帧计数持续增长说明物理层有问题软件再怎么改也没用。注意CAN 分析仪接入总线时如果分析仪自带终端电阻要确认总线总电阻是否变成 40Ω。有些分析仪可以关掉内部终端电阻记得关。6.4 一个我踩过的坑有一次现场调试PLC 和 ZAPI 通信时好时坏换了三根线、改了两版程序都没解决。最后用示波器一看CAN_H 和 CAN_L 的波形在电机启动瞬间完全塌陷差分幅值从 2V 掉到 0.5V。查了半天发现是 ZAPI 控制器的 CAN 收发器供电和电机控制器共用一路 5V电机启动时电压跌落导致收发器工作异常。后来给 CAN 收发器单独加了一路隔离电源问题彻底解决。这个血泪经验告诉我CAN 通信不稳定先查电源和地再查代码。电源问题在软件层面永远查不出来但示波器一看就明白。希望帮到你。本文还有配套的精品资源点击获取