当前所在位置:首页 > 技术知识 > CANopen

【CANopen实战】如何实现PDO数据变化即刻发送(事件触发模式详解)

发布时间:2026-05-28

      摘要:在 CANopen 通讯开发中,我们经常遇到这样的需求:当 TPDO 映射的对象字典(OD)数值发生变化时,从站需要即刻发送该 PDO 数据。本文将结合 CiA301 标准,详细解析“事件触发(Event-driven)”模式的配置细节,并演示如何通过应用层代码(回调函数)实现这一功能。

 1. 需求背景

      默认情况下,PDO 可能被配置为同步(Sync)模式。但对于状态改变、报警等关键数据,我们需要它具有“实时性”,即:值变即发,无需等待 SYNC 帧。这就涉及到了 PDO 的传输类型(Transmission Type)配置。

 2. 理论基础:Transmission Type 选型

      查阅 CiA301 标准或相关资料,对象字典(OD)在 0x18**(Sub-index 02)定义的传输类型(Value)对应关系如下:

      ● 0:synchronous (acyclic) —— 同步,单次
      ● 1:synchronous (every SYNC) —— 同步,每 1 个周期触发一次
      ● 2:synchronous (every 2nd SYNC) —— 同步,每 2 个周期触发一次
      ● 240:synchronous (every 240th SYNC) —— 同步,每 240 个周期触发一次
      ● 252:RTR-only (synchronous) —— 远程帧触发,同步
      ● 253:RTR-only (event-driven) —— 远程帧触发,事件触发
      ● 254:event-driven (manufacturer-specific) —— 事件触发(用户设定)
      ● 255:event-driven (profile-specific) —— 事件触发(行业子协议设定)

      分析:根据功能需求,由于无需同步周期触发或远程帧触发,我们将研究重心放在“事件驱动(Event-driven)”模式上。基于此,首先需要了解什么是事件触发。参阅 CiA301 的文档 7.2.2.3 Triggering modes 章节所述,协议将 PDO 的传输触发分为三大类:Event- and timer-driven(事件和定时器触发)、Remotely requested(远程帧触发)、Synchronously triggered(周期触发)。

      但在参考 CiA 相关协议文档时,并未发现“PDO 映射数值变化即自动触发传输”的直接定义。换言之,仅配置 Transmission Type(传输类型)尚不足以实现该功能。若需将对象字典(OD)的变化定义为触发事件,通常属于“用户设定”范畴,需要通过应用层代码配合实现。

      深入理解 Event-driven:254 与 255 的区别
      ● 254(用户设定):触发逻辑完全由用户自行定义。传输行为仅受对象字典与应用程序控制,不受其他 CANopen 服务或报文的影响。
      ● 255(行业子协议):遵循特定行业标准(Device Profile)的设定。若相关 Profile 对 PDO 报文传输有特定约束,则需配置为 255;通用场景下,通常首选 254。

 3. 关键配置参数总结

      在确定将 Transmission Type 设置为 254 后,需同步核查 PDO 的约束参数,以确保通信的稳定性。特别是在高频触发场景下,抑制时间(Inhibit Time)的设置对于防止总线拥塞至关重要。至此,对象字典(OD)层面的关键配置参数如下:

      ● 子索引 0x02 —— 传输类型(Transmission Type):用于设定 PDO 触发类型,此处设定值为 254
      ● 子索引 0x05 —— 事件定时器(Event Timer):按照设备定时器异步触发,0 表示禁用,此处设定值为 0
      ● 子索引 0x06 —— 抑制时间(Inhibit Time):限制最小发送间隔,0 表示无限制,为了防止高频值变冲垮总线,建议设置 1ms,此处设定值为 10(对应 1ms,单位为 100µs)。

 4. 应用层代码实现

      配置完 OD 后,我们需要在代码层面实现“监控数据变化”并“请求发送”的逻辑。

      4.1 核心思路
      1. 注册一个 Object Dictionary Callback(对象字典回调函数)。
      2. 监控目标对象(例如 0x2000:01)的写入操作。
      3. 当检测到值发生变化时,调用协议栈的发送函数(如 coPdoReqNr 或类似 API)。

      4.2 代码示例(以 TPDO 1 映射值 0x2000:01 为例)

      步骤一:预设回调函数。我们在初始化阶段注册回调,监控索引 2000,子索引 01 的变化。

      步骤二:实现回调逻辑。在回调函数中,判断变化的对象,并手动触发 PDO 发送请求。

 5. 测试验证

      测试环境与应用逻辑:
      ● TPDO 1 映射对象:0x2000:01
      ● 应用逻辑:在 Demo 中设置一个 5s 定时器,每隔 5 秒让 0x2000:01 自增。

      测试结果分析:
      通过 CAN 分析仪抓包可以得到:当应用层逻辑修改 0x2000:01 的数值时,回调函数被触发,coPdoReqNr(1) 被执行。总线上即刻观测到 TPDO 1 的报文发出,且数据已更新。

 结论

      通过 Transmission Type = 254 配合 Inhibit Time 以及应用层回调机制,我们成功实现了 CANopen PDO 的事件驱动发送功能。


盟通科技有限公司     

      盟通科技专注于实时现场总线技术及工业通讯技术的研发、推广及技术支持服务,与多家行业领先的商业伙伴合作,致力于为工业自动化领域的客户提供优质服务。公司现有多款适用于工业自动化支持的软件协议栈及开发所需的正版授权软件,同时,经验丰富的技术团队也可以帮助客户设计与调试并提供必要的技术支持。