跳到主要内容

DC 同步

从站级 DC(分布式时钟)配置。DC 属性直接通过 slave.* 访问,DC 配置方法通过 DcConfig 类操作。

推荐使用主站级方法

大多数场景建议使用 master.configure_dc() 一次性配置所有 DC 从站。 从站级方法适用于需要对个别从站设置不同参数的场景。

只读属性

类别属性类型说明
DC 状态has_dcbool是否支持 DC (ESC 硬件 bit)
has_esi_dc_syncboolESI 是否声明此从站使用 DC 同步 (启用 DC 前应同时为真)
dc_activeintDC 激活状态(0=禁用, 非0=已激活)
DC 时间dc_cycle0int当前 SYNC0 周期(纳秒)
dc_cycle1int当前 SYNC1 周期(纳秒)
dc_shiftint当前相位偏移(纳秒)
propagation_delayint帧从主站到达此从站的传播延迟(纳秒)
DC 拓扑dc_next / dc_previousintDC 链中下一个/上一个从站索引
dc_parent_portintDC 父端口号
dc_receive_time_a/b/c/dint各端口接收时间(纳秒)

has_esi_dc_sync

@property
def has_esi_dc_sync(self) -> bool

ESI 文件是否声明此从站使用 DC 同步. has_dc 仅反映 ESC 硬件 bit, 不代表应用层启用 DC. 启用 DC 前应同时检查 has_dc and has_esi_dc_sync, 用于过滤 ESC 报 capable 但 ESI 未声明 DC OpMode 的从站 (如 GCAN-8200), 避免强写 DCCUC 导致从站卡死.

ESI 未加载时保守 fallback 到 has_dc.

示例:

slave = master[1]
if slave.has_dc and slave.has_esi_dc_sync:
master.configure_dc(1_000_000)
else:
print(f"从站 {slave.slave_num} 跳过 DC 配置")

配置方法

DcConfig.configure()

from ethercat import DcConfig

dc = DcConfig(dll, master_index, slave_index)
dc.configure(sync0_cycle_ns: int, sync1_cycle_ns: int = 0,
shift_ns: Optional[int] = None) -> bool

配置从站 DC 同步。所有参数单位:纳秒(ns)

参数:

  • sync0_cycle_ns (int) — SYNC0 周期(纳秒),0 表示禁用
  • sync1_cycle_ns (int) — SYNC1 增量时间(纳秒),0 表示仅 SYNC0
  • shift_ns (Optional[int]) — 相位偏移(纳秒):None=自动(0),其他值=手动偏移

返回值:

  • bool — 配置是否成功

示例:

# 通过 slave.dc_config 公共访问器获取
dc = master[1].dc_config
dc.configure(1_000_000) # SYNC0 = 1ms
dc.configure(1_000_000, 500_000) # SYNC0 = 1ms, SYNC1 = 500us

DcConfig.configure_mode()

dc.configure_mode(mode: DcSyncMode, sync0_cycle_ns: int = 0,
sync1_cycle_ns: int = 0, shift_ns: Optional[int] = None) -> bool

按同步模式配置 DC。

参数:

  • mode (DcSyncMode) — DC 同步模式
  • sync0_cycle_ns (int) — SYNC0 周期(纳秒)
  • sync1_cycle_ns (int) — SYNC1 周期(纳秒)
  • shift_ns (Optional[int]) — 相位偏移(纳秒)

相关结构 (唯一定义来源: slave/dc.py):

class DcSyncMode(IntEnum):
FreeRun = 0 # 自由运行 (不使用 DC 同步)
SmSynchron = 1 # SM 事件同步
DcSynchron = 2 # DC 同步, 仅 SYNC0 信号
DcSynchron01 = 3 # DC 同步, SYNC0 + SYNC1 信号
别名导出

ethercat.data.types 也导出 DcSyncMode (大写下划线名 FREE_RUN / SM_SYNCHRON / DC_SYNCHRON, 含义对齐), 推荐统一使用 slave.dc 来源, 避免命名风格混用。

示例:

dc.configure_mode(DcSyncMode.DcSynchron, 1_000_000)              # SYNC0 = 1ms
dc.configure_mode(DcSyncMode.DcSynchron01, 1_000_000, 500_000) # SYNC0 + SYNC1
dc.configure_mode(DcSyncMode.FreeRun) # 禁用 DC

DcConfig.disable()

dc.disable() -> bool

禁用此从站的 DC 同步。

同步窗口诊断

slave.sync_window_status

@property
def sync_window_status(self) -> Optional[dict]

获取从站 DC 同步窗口的详细状态。不支持 DC 或读取失败时返回 None

返回值:

  • Optional[dict] — 同步窗口状态字典
{
'diff_ns': int, # 当前时间差(纳秒)
'max_diff_ns': int, # 最大时间差(纳秒)
'min_diff_ns': int, # 最小时间差(纳秒)
'in_sync': bool, # 是否在同步窗口内
'out_of_sync_count': int, # 超出同步窗口次数
}
便捷属性

如果只需要 in_syncsync_time_difference,可通过 slave.diagnostics.dc 访问,详见 从站诊断

DcConfig.get_sync_window_status()

dc.get_sync_window_status() -> Optional[SyncWindowStatus]

通过 DcConfig 获取同步窗口状态,返回 SyncWindowStatus 对象。

SyncWindowStatus 唯一定义来源

SyncWindowStatus 的标准定义在 slave/slave_stats.py (dataclass), 详见 从站诊断slave/dc.py 内部存在同名类用于 DcConfig 内部回包, 字段一致, 文档统一以 slave_stats 来源为准。

slave.reset_sync_stats()

def reset_sync_stats(self) -> None

重置此从站的同步窗口统计(最大/最小时间差、超出同步次数等)。

完整示例

slave = master[1]  # 1-based 索引

if slave.has_dc:
dc = slave.dc_config # 公共访问器
dc.configure(1_000_000) # SYNC0 = 1ms

print(f"DCActive={slave.dc_active}, DCCycle0={slave.dc_cycle0}ns, DCShift={slave.dc_shift}ns")

# 同步窗口详细状态
status = slave.sync_window_status
if status is not None:
print(f"同步差={status['diff_ns']}ns, 同步={status['in_sync']}")

dc.disable()