CiA 402 — 伺服驱动器辅助
CiA 402 (IEC 61800-7-204) 是基于 CoE 的伺服驱动器设备协议。封装了驱动器状态机管理、操作模式切换和运动参数访问。
CiA 402 运行在 CoE (SDO) 之上,仅当从站支持 CoE 时可用。
通过 slave.GetCiA402() 获取 CiA402& 引用。
状态查询
StateDrive()
StateCiA402 StateDrive() const;
获取驱动器状态(解析 StatusWord)。
相关结构:
enum class StateCiA402 : uint8_t {
NotReadyToSwitchOn = 0, // 未就绪
SwitchOnDisabled = 1, // 开启已禁用
ReadyToSwitchOn = 2, // 准备就绪
SwitchedOn = 3, // 已开启
OperationEnabled = 4, // 运行使能
QuickStopActive = 5, // 快速停止中
FaultReactionActive = 6, // 故障处理中
Fault = 7 // 故障
};
Statusword
uint16_t Statusword() const;
读取状态字 (CiA 402 标准状态字, 包含状态机标志)。便捷布尔: TargetReached() / HasFault() / HasWarning() / IsRemote() / HomingAttained() / HomingError()。
示例:
auto& cia = master.GetSlave(1).GetCiA402();
printf("StatusWord: 0x%04X\n", cia.Statusword());
printf("目标到达: %s\n", cia.TargetReached() ? "是" : "否");
printf("有故障: %s\n", cia.HasFault() ? "是" : "否");
Controlword
uint16_t Controlword() const;
void Controlword(uint16_t v) const;
读取/写入 CiA 402 标准控制字。手动操作状态机时使用; 推荐使用 Enable() / QuickStop() / FaultReset() 高层包装。
使能与停止
Enable(int max_retries = 10)
bool Enable(int max_retries = 10) const;
使能驱动器: 状态机推进逻辑下沉到 native DLL (CiA402_Enable), 内部按 CiA 402-2 完成 SwitchOnDisabled → ReadyToSwitchOn → SwitchedOn → OperationEnabled 全套时序、Fault 复位、QuickStop 恢复 (含 0x605A 选项码判断), 不在 C++ 层暴露状态机 IP。
参数:
max_retries-- 最大重试次数 (默认 10)
返回值:
bool--true= 已使能到 OperationEnabled,false= 失败/超时. 详细枚举状态调用StateDrive()。
Disable()
void Disable() const;
禁用伺服 (Disable Voltage)。等同 ControlWord = 0x00, 进入 SwitchOnDisabled 状态。
DisableOperation()
void DisableOperation() const;
禁用运行 (回退到 SwitchedOn 状态), 主轴保持上电但不输出力矩。
QuickStop()
void QuickStop() const;
快速停止。
FaultReset()
void FaultReset() const;
故障复位。
示例:
auto& cia = master.GetSlave(1).GetCiA402();
// 一次性使能 (内部完成完整状态机)
if (cia.Enable()) {
printf("使能成功\n");
} else {
printf("使能失败, 当前状态: %d\n", static_cast<int>(cia.StateDrive()));
}
// 故障处理
if (cia.HasFault()) {
cia.FaultReset();
}
操作模式
OperationMode()
ModeCiA402 OperationMode() const; // 读取操作模式 (0x6061)
void OperationMode(ModeCiA402 m) const; // 设置操作模式 (0x6060)
相关结构:
enum class ModeCiA402 : int8_t {
PP = 1, // 轮廓位置模式
VL = 2, // 速度模式
PV = 3, // 轮廓速度模式
PT = 4, // 轮廓转矩模式
HM = 6, // 回零模式
IP = 7, // 插补位置模式
CSP = 8, // 周期同步位置模式
CSV = 9, // 周期同步速度模式
CST = 10, // 周期同步转矩模式
CSTCA = 11 // 周期同步转矩带换向角模式
};
IsModeSupported()
bool IsModeSupported(ModeCiA402 mode) const;
检查驱动器是否支持指定操作模式(通过 0x6502 查询)。
示例:
auto& cia = master.GetSlave(1).GetCiA402();
// 设置为 CSP 模式
cia.OperationMode(ModeCiA402::CSP);
// 验证
printf("当前模式: %d\n", static_cast<int>(cia.OperationMode()));
// 检查支持的模式
if (cia.IsModeSupported(ModeCiA402::CSP)) {
printf("支持 CSP 模式\n");
}
运动参数
位置/速度/转矩 (读取)
int32_t PositionActual() const; // 实际位置 (0x6064)
int32_t VelocityActual() const; // 实际速度 (0x606C)
int16_t TorqueActual() const; // 实际转矩 (0x6077)
目标值 (读写)
int32_t TargetPosition() const;
void TargetPosition(int32_t v) const; // 目标位置 (0x607A)
int32_t TargetVelocity() const;
void TargetVelocity(int32_t v) const; // 目标速度 (0x60FF)
int16_t TargetTorque() const;
void TargetTorque(int16_t v) const; // 目标转矩 (0x6071)
轮廓参数 (读写)
uint32_t ProfileVelocity() const;
void ProfileVelocity(uint32_t v) const; // 轮廓速度 (0x6081)
uint32_t ProfileAcceleration() const;
void ProfileAcceleration(uint32_t v) const; // 轮廓加速度 (0x6083)
uint32_t ProfileDeceleration() const;
void ProfileDeceleration(uint32_t v) const; // 轮廓减速度 (0x6084)
uint32_t QuickStopDeceleration() const;
void QuickStopDeceleration(uint32_t v) const; // 快停减速度 (0x6085)
PP 模式辅助
NewSetpoint()
void NewSetpoint(int32_t position, bool relative = false) const;
PP 模式发送新定位命令。自动设置 ControlWord Bit 4(NewSetpoint)。
ClearNewSetpoint()
void ClearNewSetpoint() const;
清除 NewSetpoint 位。
StartHoming()
void StartHoming() const;
HM 模式启动回零。
扩展轮廓参数
uint8_t Polarity() const;
void Polarity(uint8_t v) const; // 极性设置 (0x607E)
int16_t MotionProfileType() const;
void MotionProfileType(int16_t v) const; // 运动轮廓类型 (0x6086)
int32_t SoftwarePositionLimitMin() const;
void SoftwarePositionLimitMin(int32_t v) const; // 软件位置最小限制 (0x607D:01)
int32_t SoftwarePositionLimitMax() const;
void SoftwarePositionLimitMax(int32_t v) const; // 软件位置最大限制 (0x607D:02)
回零参数
int8_t HomingMethod() const;
void HomingMethod(int8_t v) const; // 回零方式 (0x6098)
int32_t HomeOffset() const;
void HomeOffset(int32_t v) const; // 原点偏移 (0x607C)
uint32_t HomingSpeedSearch() const;
void HomingSpeedSearch(uint32_t v) const; // 回零搜索速度 (0x6099:01)
uint32_t HomingSpeedZero() const;
void HomingSpeedZero(uint32_t v) const; // 回零零脉冲速度 (0x6099:02)
uint32_t HomingAcceleration() const;
void HomingAcceleration(uint32_t v) const; // 回零加速度 (0x609A)
TouchProbe
uint16_t TouchProbeStatus() const; // 状态 (0x60B9)
int32_t TouchProbePositiveEdge() const; // 正沿位置 (0x60BA)
int32_t TouchProbeNegativeEdge() const; // 负沿位置 (0x60BB)
void ConfigureTouchProbe(uint16_t function) const; // 配置 (0x60B8)
数字 IO
uint32_t DigitalInputs() const; // 数字输入 (0x60FD)
uint32_t DigitalOutputs() const; // 数字输出 (0x60FE:1)
void DigitalOutputs(uint32_t v) const; // 设置数字输出
扩展运动参数
| 方法 | 类型 | 访问 | 说明 |
|---|---|---|---|
| MaxTorque() | uint16_t | 读写 | 最大转矩 (0x6072),千分之额定转矩 |
| MotorRatedTorque() | uint32_t | 读写 | 电机额定转矩 (0x6076),单位 mNm |
| PositionOffset() | int32_t | 读写 | 位置偏移 (0x60B0),CSP 模式下叠加到目标位置 |
| VelocityOffset() | int32_t | 读写 | 速度偏移 (0x60B1),CSV 模式下叠加到目标速度 |
| TorqueOffset() | int16_t | 读写 | 转矩偏移 (0x60B2),CST 模式下叠加到目标转矩 |
| InterpolationTimePeriodValue() | uint8_t | 读写 | 插补时间周期值 (0x60C2:01) |
| InterpolationTimePeriodIndex() | int8_t | 读写 | 插补时间周期指数 (0x60C2:02),实际周期 = Value x 10^Index 秒 |
| QuickStopOptionCode() | int16_t | 读写 | 快速停止选项码 (0x605A)。0=禁用驱动, 1/2=减速停止, 5/6=减速后保持在 QuickStopActive |
示例:
auto& cia = master.GetSlave(1).GetCiA402();
// 转矩配置
cia.MaxTorque(1000); // 最大转矩 = 100% 额定
uint32_t rated = cia.MotorRatedTorque();
// CSP 模式偏移叠加
cia.PositionOffset(100); // 位置附加偏移
cia.VelocityOffset(50); // 速度附加偏移
// 插补时间周期 (1ms = 1 × 10^(-3) 秒)
cia.InterpolationTimePeriodValue(1);
cia.InterpolationTimePeriodIndex(-3);
// 快速停止选项 (5=减速后保持, 允许直接恢复)
cia.QuickStopOptionCode(5);
力矩限制
| 方法 | 类型 | 访问 | 说明 |
|---|---|---|---|
| PositiveTorqueLimit() | uint16_t | 读写 | 正方向力矩限制 (0x60E0),千分之额定转矩 |
| NegativeTorqueLimit() | uint16_t | 读写 | 负方向力矩限制 (0x60E1),千分之额定转矩 |
示例:
auto& cia = master.GetSlave(1).GetCiA402();
// 限制正负方向转矩为额定的 50%
cia.PositiveTorqueLimit(500);
cia.NegativeTorqueLimit(500);
软件位置限位
| 方法 | 类型 | 访问 | 说明 |
|---|---|---|---|
| SoftwarePositionLimitMin() | int32_t | 读写 | 软件位置限位下限 (0x607D:01) |
| SoftwarePositionLimitMax() | int32_t | 读写 | 软件位置限位上限 (0x607D:02) |
示例:
auto& cia = master.GetSlave(1).GetCiA402();
// 设置运动范围限制
cia.SoftwarePositionLimitMin(-1000000);
cia.SoftwarePositionLimitMax(1000000);
TxPDO 数据有效性
TxPdoDataInvalid()
bool TxPdoDataInvalid() const;
TxPDO 数据是否无效 (0x603E)。非零表示驱动器 TxPDO 数据不可信,例如编码器未就绪时位置值无意义。
示例:
auto& cia = master.GetSlave(1).GetCiA402();
if (!cia.TxPdoDataInvalid()) {
int32_t pos = cia.PositionActual(); // 数据有效,可安全使用
}
同步功能
| 方法 | 类型 | 访问 | 说明 |
|---|---|---|---|
| SynchronizationSettings() | uint16_t | 读写 | 同步设置 (0x60D9:01),同步使能位掩码 |
| DriveSyncStatus() | uint16_t | 只读 | 驱动同步状态 (0x60DA),指示驱动器是否已同步到主站时钟 |
示例:
auto& cia = master.GetSlave(1).GetCiA402();
// 读取驱动器同步状态
uint16_t syncStatus = cia.DriveSyncStatus();
printf("同步状态: 0x%04X\n", syncStatus);
// 配置同步设置
cia.SynchronizationSettings(0x0001);
回零方法枚举
enum class HomingMethodCiA402 : int8_t {
None = 0, // 无回零
NegativeLimitSwitch = 1, // 负限位开关
PositiveLimitSwitch = 2, // 正限位开关
PositiveHomeSwitch = 3, // 正原点开关 (正向)
PositiveHomeSwitchNeg = 4, // 正原点开关 (负向)
NegativeHomeSwitch = 5, // 负原点开关 (负向)
NegativeHomeSwitchPos = 6, // 负原点开关 (正向)
HomeSwitchPositiveIndex = 7, // 原点开关+正向索引脉冲
HomeSwitchNegativeIndex = 11, // 原点开关+负向索引脉冲
NegativeLimitIndex = 17, // 负限位+索引脉冲
PositiveLimitIndex = 18, // 正限位+索引脉冲
PositiveIndex = 33, // 正向索引脉冲
NegativeIndex = 34, // 负向索引脉冲
CurrentPosition = 35, // 当前位置为零点
TouchProbe = 37, // Touch Probe
};
快速运动控制
void MoveAbsolute(int32_t position) const; // 绝对定位运动
void MoveRelative(int32_t distance) const; // 相对定位运动
void StartMotion() const; // 启动运动 (使能)
void StopMotion() const; // 停止运动 (禁用操作)
void EmergencyStop() const; // 紧急停止 (快速停止)
bool IsMoving() const; // 是否在运动中
bool IsInPosition() const; // 是否到位
bool IsFaulted() const; // 是否有故障
uint16_t GetFaultCode() const; // 获取故障码 (0x603F)
void ClearFault() const; // 清除故障
驱动器支持查询
uint32_t SupportedDriveModes() const; // 支持的操作模式位图 (0x6502)
bool IsModeSupported(ModeCiA402 mode) const; // 检查是否支持指定模式
同步设置
uint16_t SynchronizationSettings() const;
void SynchronizationSettings(uint16_t v) const; // 同步使能位掩码 (0x60D9:01)
uint16_t DriveSyncStatus() const; // 驱动同步状态 (0x60DA, 只读)
PDO 偏移管理
用于 CSP/CSV/CST 等 PDO 模式下的零拷贝快速访问:
auto& cia = master.GetSlave(1).GetCiA402();
// 初始化 PDO 偏移缓存 (SafeOp/OP 状态下调用一次)
cia.InitializePdoOffsets();
// 检查是否已初始化
if (cia.PdoInitialized()) {
printf("PDO 偏移已初始化\n");
}
// 重置偏移缓存
cia.ResetPdoOffsets();
标准对象索引常量 (CiA402Obj)
可搭配 coe.SDORead / SDOWrite 使用:
| 常量 | 值 | 说明 |
|---|---|---|
| CONTROLWORD | 0x6040 | 控制字 |
| STATUSWORD | 0x6041 | 状态字 |
| MODES_OF_OPERATION | 0x6060 | 操作模式设置 |
| MODES_OF_OPERATION_DISPLAY | 0x6061 | 操作模式显示 |
| TARGET_POSITION | 0x607A | 目标位置 |
| POSITION_ACTUAL | 0x6064 | 实际位置 |
| TARGET_VELOCITY | 0x60FF | 目标速度 |
| VELOCITY_ACTUAL | 0x606C | 实际速度 |
| TARGET_TORQUE | 0x6071 | 目标转矩 |
| TORQUE_ACTUAL | 0x6077 | 实际转矩 |
| MAX_TORQUE | 0x6072 | 最大转矩 |
| MOTOR_RATED_TORQUE | 0x6076 | 电机额定转矩 |
| HOME_OFFSET | 0x607C | 回零偏移 |
| SOFTWARE_POSITION_LIMIT | 0x607D | 软件位置限制 |
| POLARITY | 0x607E | 极性 |
| MAX_PROFILE_VELOCITY | 0x6080 | 最大轮廓速度 |
| PROFILE_VELOCITY | 0x6081 | 轮廓速度 |
| PROFILE_ACCELERATION | 0x6083 | 轮廓加速度 |
| PROFILE_DECELERATION | 0x6084 | 轮廓减速度 |
| QUICK_STOP_DECELERATION | 0x6085 | 快速停止减速度 |
| MOTION_PROFILE_TYPE | 0x6086 | 运动轮廓类型 |
| HOMING_METHOD | 0x6098 | 回零方法 |
| HOMING_SPEEDS | 0x6099 | 回零速度 |
| HOMING_ACCELERATION | 0x609A | 回零加速度 |
| POSITION_OFFSET | 0x60B0 | 位置偏移 (CSP) |
| VELOCITY_OFFSET | 0x60B1 | 速度偏移 (CSV) |
| TORQUE_OFFSET | 0x60B2 | 转矩偏移 |
| TOUCH_PROBE_FUNCTION | 0x60B8 | Touch Probe 功能控制 |
| TOUCH_PROBE_STATUS | 0x60B9 | Touch Probe 状态 |
| TOUCH_PROBE_POS_EDGE | 0x60BA | Touch Probe 正边沿位置 |
| TOUCH_PROBE_NEG_EDGE | 0x60BB | Touch Probe 负边沿位置 |
| INTERPOLATION_TIME_PERIOD | 0x60C2 | 插补时间周期 |
| QUICK_STOP_OPTION_CODE | 0x605A | 快速停止选项码 |
| DIGITAL_INPUTS | 0x60FD | 数字输入 |
| DIGITAL_OUTPUTS | 0x60FE | 数字输出 |
| ERROR_CODE | 0x603F | 错误代码 |
| SUPPORTED_DRIVE_MODES | 0x6502 | 支持的模式位图 |
控制字命令常量
| 常量 | 值 | 说明 |
|---|---|---|
| CW_SHUTDOWN | 0x06 | 关机命令 |
| CW_SWITCH_ON | 0x07 | 开启命令 |
| CW_ENABLE_OPERATION | 0x0F | 使能运行 |
| CW_DISABLE_VOLTAGE | 0x00 | 禁用电压 |
| CW_QUICK_STOP | 0x02 | 快速停止 |
| CW_FAULT_RESET | 0x80 | 故障复位 |
| CW_HALT | 0x0100 | 暂停位 (Bit 8) |
状态字位掩码常量
| 常量 | 值 | 说明 |
|---|---|---|
| SW_READY_TO_SWITCH_ON | 0x0001 (Bit 0) | 准备就绪 |
| SW_SWITCHED_ON | 0x0002 (Bit 1) | 已开启 |
| SW_OPERATION_ENABLED | 0x0004 (Bit 2) | 运行使能 |
| SW_FAULT | 0x0008 (Bit 3) | 故障 |
| SW_VOLTAGE_ENABLED | 0x0010 (Bit 4) | 电压已使能 |
| SW_QUICK_STOP | 0x0020 (Bit 5) | 快速停止 |
| SW_SWITCH_ON_DISABLED | 0x0040 (Bit 6) | 开启已禁用 |
| SW_WARNING | 0x0080 (Bit 7) | 警告 |
| SW_REMOTE | 0x0200 (Bit 9) | 远程模式 |
| SW_TARGET_REACHED | 0x0400 (Bit 10) | 目标已到达 |
| SW_INTERNAL_LIMIT | 0x0800 (Bit 11) | 内部限位激活 |
| SW_HOMING_ATTAINED | 0x1000 (Bit 12) | 回零完成 |
| SW_HOMING_ERROR | 0x2000 (Bit 13) | 回零错误 |
驱动器信息
SupportedDriveModes()
uint32_t SupportedDriveModes() const;
支持的驱动模式位掩码 (0x6502, 只读)。Bit 0=PP, Bit 1=VL, Bit 2=PV, Bit 3=PT, Bit 5=HM, Bit 6=IP, Bit 7=CSP, Bit 8=CSV, Bit 9=CST。
GetSupportedModes()
std::vector<ModeCiA402> GetSupportedModes() const;
获取驱动器支持的全部操作模式列表。
SupportedHomingMethods()
std::vector<int8_t> SupportedHomingMethods() const;
读取驱动器支持的回零方法列表 (0x60E3)。返回所有支持的回零方法编号。
示例:
auto& cia = master.GetSlave(1).GetCiA402();
auto methods = cia.SupportedHomingMethods();
printf("支持 %d 种回零方法\n", (int)methods.size());
完整示例
CSP 模式 — 周期同步位置控制
#include "ethercat.hpp"
using namespace darra::ethercat;
int main() {
EtherCATMaster master(dll);
master.SetNetwork("\\Device\\NPF_{...}")
.SetEni("config.deni")
.Build();
auto& cia = master.GetSlave(1).GetCiA402();
// 设置操作模式 + 初始化 PDO 偏移
cia.OperationMode(ModeCiA402::CSP);
cia.InitializePdoOffsets();
master.SetState(EcState::OP);
master.Start();
// 一次性使能 (内部完成完整状态机)
if (!cia.Enable()) {
printf("使能失败, 当前状态: %d\n", static_cast<int>(cia.StateDrive()));
return -1;
}
// PDO 周期回调下发目标位置
master.Events().ProcessDataCyclicSync = [&](uint16_t /*mi*/) {
if (cia.HasFault()) {
uint16_t code = cia.GetFaultCode();
printf("驱动器故障, code=0x%04X\n", code);
cia.FaultReset();
cia.Enable();
return;
}
// 周期更新 TargetPosition (CSP 模式由 PDO 直接传递)
};
getchar();
cia.Disable();
master.Close();
return 0;
}