DC 同步
从站级 DC(分布式时钟)配置。所有 DC 属性和方法直接通过 slave.* 访问。
推荐使用主站级方法
大多数场景建议使用 master.ConfigureDC() 一次性配置所有 DC 从站。
从站级方法适用于需要对个别从站设置不同参数的场景。两者都默认自动计算偏移。
只读属性
| 类别 | 属性 | 类型 | 访问 | 说明 |
|---|---|---|---|---|
| DC 状态 | HasDC | bool | 只读 | ESC 硬件是否支持 DC |
HasEsiDcSync | bool | 只读 | ESI 是否声明此从站使用 DC 同步(OpMode/AssignActivate 非零) | |
DCActive | ushort | 只读 | DC 激活状态(0=禁用, 非0=已激活) | |
| DC 时间 | DCCycle0 | int | 只读 | 当前 SYNC0 周期(纳秒) |
DCCycle1 | int | 只读 | 当前 SYNC1 周期(纳秒) | |
DCShift | int | 只读 | 当前相位偏移(纳秒) | |
PropagationDelay | int | 只读 | 帧从主站到达此从站的传播延迟(纳秒) | |
| DC 拓扑 | DCNext / DCPrevious | ushort | 只读 | DC 链中下一个/上一个从站索引 |
DCParentPort | int | 只读 | DC 父端口号 | |
DCReceiveTimeA/B/C/D | int | 只读 | 各端口接收时间(纳秒) |
HasDC vs HasEsiDcSync
HasDC 仅反映 ESC 硬件 bit, 不代表应用层一定使用 DC。部分从站 ESC 报 DC capable 但 ESI 未声明 DC OpMode, 此时应跑 FreeRun / SM-Sync, 强行启用 DC 会让从站拒绝进入 OP。
启用 DC 前的稳妥写法:
if (slave.HasDC && slave.HasEsiDcSync)
{
slave.ConfigureDC(1_000_000);
}
配置方法
Slave.ConfigureDC(uint sync0CycleNs, uint sync1CycleNs = 0, int? shiftNs = null)
public void ConfigureDC(uint sync0CycleNs, uint sync1CycleNs = 0, int? shiftNs = null)
从站级重载: 一次性配置单个从站的 DC 同步, 用于需要给个别从站设不同 SYNC0 / 偏移的场景。所有参数单位:纳秒(ns)。批量配置走 master.ConfigureDC。
参数:
sync0CycleNs(uint) — SYNC0 周期(纳秒),0 表示禁用sync1CycleNs(uint) — SYNC1 增量时间(纳秒),0 表示仅 SYNC0shiftNs(int?) — 相位偏移(纳秒):null=自动计算(默认),0=不设置偏移,其他值=手动偏移
示例:
slave.ConfigureDC(1_000_000); // SYNC0 = 1ms
slave.ConfigureDC(1_000_000, shiftNs: 0); // SYNC0 = 1ms, 不设置偏移
ConfigureDC(DcSyncMode mode, uint sync0CycleNs = 0, uint sync1CycleNs = 0, int? shiftNs = null)
public void ConfigureDC(DcSyncMode mode, uint sync0CycleNs = 0, uint sync1CycleNs = 0, int? shiftNs = null)
根据同步模式配置 DC(ETG.1020)。自动配置 SM 同步类型。批量配置走 master.ConfigureDC(DcSyncMode, ...)。
参数:
mode(DcSyncMode) — DC 同步模式sync0CycleNs(uint) — SYNC0 周期(纳秒),仅 DcSynchron 模式使用sync1CycleNs(uint) — SYNC1 周期(纳秒),仅 DcSynchron 模式使用shiftNs(int?) — 相位偏移(纳秒),仅 DcSynchron 模式使用
相关结构:
public enum DcSyncMode
{
FreeRun = 0, // 自由运行 - 不使用 DC 同步
SmSynchron = 1, // SM 同步 - 使用 SM 事件触发
DcSynchron = 2 // DC 同步 - 使用 SYNC0/SYNC1 信号
}
示例:
slave.ConfigureDC(DcSyncMode.DcSynchron, 1_000_000); // DC SYNC0 = 1ms
slave.ConfigureDC(DcSyncMode.SmSynchron); // SM 同步模式
slave.ConfigureDC(DcSyncMode.FreeRun); // 自由运行
CurrentDcSyncMode
public DcSyncMode CurrentDcSyncMode { get; }
获取当前 DC 同步模式。自动检测从站的同步配置。
示例:
var mode = slave.CurrentDcSyncMode;
Console.WriteLine($"当前 DC 同步模式: {mode}");
DisableDC()
public void DisableDC()
禁用此从站的 DC 同步。
同步窗口诊断
GetSyncWindowStatus()
public SyncWindowStatus? GetSyncWindowStatus()
获取从站 DC 同步窗口的详细状态。不支持 DC 或读取失败时返回 null。
返回值:
SyncWindowStatus?— 同步窗口状态
相关结构:
public struct SyncWindowStatus
{
public int DiffNs; // 当前时间差(纳秒)
public int MaxDiffNs; // 最大时间差(纳秒)
public int MinDiffNs; // 最小时间差(纳秒)
public bool InSync; // 是否在同步窗口内
public uint OutOfSyncCount; // 超出同步窗口次数
}
便捷属性
如果只需要 InSync 或 SyncTimeDifference,可通过 slave.Diagnostics.DC 访问,详见 从站诊断。GetSyncWindowStatus() 适合需要完整统计信息的场景。
ResetSyncWindowStats()
public void ResetSyncWindowStats()
重置此从站的同步窗口统计(最大/最小时间差、超出同步次数等)。
完整示例
var slave = master.Slaves[0];
if (slave.HasDC)
{
slave.ConfigureDC(1_000_000); // SYNC0 = 1ms
Console.WriteLine($"DCActive={slave.DCActive}, DCCycle0={slave.DCCycle0}ns, DCShift={slave.DCShift}ns");
// 同步窗口详细状态
var status = slave.GetSyncWindowStatus();
if (status.HasValue)
{
Console.WriteLine($"同步差={status.Value.DiffNs}ns, 同步={status.Value.InSync}");
}
slave.DisableDC();
}